上一篇【第60篇】API Server深度解析——K8s的“总控制器“是怎么把请求玩弄于股掌的
下一篇【第62篇】Controller Manager——K8s的"自动驾驶仪"
摘要
如果说API Server是K8s的前台,那etcd就是公司的档案室+保险柜——而且是所有数据的唯一真源。
你在K8s里创建的一切——每一个Pod、Service、ConfigMap、Secret、PV,甚至每个节点的状态——最终都序列化进etcd。如果etcd的数据没了,你的集群就失忆了:API Server还在,但它啥都不记得了,等于一个全新的空集群。
正因为etcd这么重要,它用了Raft共识算法来保证:数据不丢(持久化)、数据一致(所有节点看到相同内容)、高可用(挂几个节点还能工作)。这篇文章讲清etcd的地位、Raft怎么干活、它的KV结构,以及最实用的——怎么备份和恢复。
一、etcd在K8s里的地位
1.1 唯一真源
【etcd = K8s 的唯一持久化存储】 所有资源的最终归宿: Pod ─┐ Service ─┤ ConfigMap ─┼──► 序列化(JSON) ──► etcd Secret ─┤ (key-value) Node状态 ─┘ ... API Server: • 读: 从etcd取 • 写: 写进etcd • 缓存: 内存watch cache(加速读,但不是真源) ⚠️ 记忆口诀: "etcd没了 = 集群失忆" API Server可以重启,etcd的数据不能丢!要点:K8s里没有任何其他组件持久化状态。kubelet本地的Pod状态、调度器的缓存,都是易失的。只有etcd是"铁打的存储"。这也是为什么生产集群etcd必须跑在专用、高速SSD、低延迟的机器上,且至少要3副本(5副本更佳)。
1.2 部署拓扑
【etcd 集群拓扑(奇数节点)】 为什么奇数?Raft选主要"多数派"(quorum) 3节点: 允许挂1个 (1/3) 5节点: 允许挂2个 (2/5) 4节点: 允许挂1个 (和3节点一样能力,但多花一台) → 所以不用偶数 ┌────────┐ ┌────────┐ ┌────────┐ │ etcd-0 │◄─►│ etcd-1 │◄─►│ etcd-2 │ ← 两两互联,Raft复制 └────────┘ └────────┘ └────────┘ ▲ ▲ ▲ └────────────┼────────────┘ ▼ API Server (连所有etcd节点)二、Raft共识算法
2.1 选主与日志复制
【Raft 三个核心角色】 Leader (领导者): 唯一处理写请求,把日志复制给Follower Follower (跟随者): 被动接收日志,参与投票 Candidate (候选者): 选主时的临时状态 ┌─────────────────────────────────────────────┐ │ 写流程(客户端→Leader): │ │ 1. 客户端发写请求给Leader │ │ 2. Leader追加到自己的日志(Entry) │ │ 3. Leader复制日志给所有Follower │ │ 4. 多数派(quorum)确认收到 → Leader提交 │ │ 5. 通知Follower也提交 │ │ 6. 返回客户端"成功" │ │ │ │ 关键: 只有"多数派"确认了才叫提交 │ │ → 保证即使少数节点挂了,数据也不丢 │ └─────────────────────────────────────────────┘2.2 为什么Raft强一致
| 场景 | 行为 |
|---|---|
| Leader挂了 | 剩余Follower选新Leader(任期term+1),继续服务 |
| 网络分区 | 少数派分区无法选主/写(防止脑裂) |
| 日志落后 | 新Leader强制Follower追平自己的日志 |
| 读请求 | 默认从Leader读(保证强一致),或只读模式(可能稍旧) |
要点:Raft的精髓是"多数派存活就能工作"。3节点允许挂1个、5节点允许挂2个。但它要求节点间网络延迟低——如果etcd节点跨地域部署、延迟高,Raft的提交会卡顿,整个K8s变慢。所以etcd节点一定要放同一个机房、同高速网络。
三、etcd的数据结构
3.1 一切皆在 /registry 下
【etcd 的 Key 结构】 /registry/ ├── pods/ │ ├── default/nginx-abc123 → Pod的JSON │ └── kube-system/etcd-0 ├── services/ │ ├── spec/default/my-svc │ └── endpoints/default/my-svc ├── configmaps/default/my-config ├── secrets/default/my-secret ├── deployments/apps/default/my-deploy └── ... → 你可以在etcd里直接看到所有资源(这就是为什么etcd要加密!)# 直接看etcd里的key (用etcdctl)ETCDCTL_API=3etcdctl\--endpoints=https://127.0.0.1:2379\--cacert=/etc/kubernetes/pki/etcd/ca.crt\--cert=/etc/kubernetes/pki/etcd/server.crt\--key=/etc/kubernetes/pki/etcd/server.key\get /registry/pods/default/nginx-abc123 --print-value-only# 输出: {"kind":"Pod","apiVersion":"v1",...} ← 序列化的Pod四、性能调优
4.1 两个关键参数
【etcd 性能的两个命门】 1. 磁盘IO (最重要!) etcd对磁盘延迟极其敏感 → 必须用 SSD/NVMe,绝不用HDD → 延迟 > 10ms 集群就开始抽风 2. 数据库大小 (配额) 默认配额 2GB,超了etcd就拒绝写入! → 大集群要调大: --quota-backend-bytes=8589934592 (8GB) 3. 历史压缩 (compaction) etcd保留所有历史版本(为了watch) → 历史太多=数据库膨胀 → 要定期压缩: etcdctl compact <revision> → 配合 defrag 真正回收空间# 看etcd性能关键指标ETCDCTL_API=3etcdctl endpoint status --write-out=table# | ENDPOINT | ID | VERSION | DB SIZE | ... |# DB SIZE 持续增长 → 该压缩了# 压缩+碎片整理ETCDCTL_API=3etcdctl compact$(ETCDCTL_API=3etcdctl endpoint status-wjson|...)ETCDCTL_API=3etcdctl defrag五、备份与恢复——保命技能
5.1 快照备份
这是运维K8s最关键的命令,没有之一:
# 创建快照(在线,不影响运行)ETCDCTL_API=3etcdctl snapshot save /backup/etcd-$(date+%F).db\--endpoints=https://127.0.0.1:2379\--cacert=/etc/kubernetes/pki/etcd/ca.crt\--cert=/etc/kubernetes/pki/etcd/server.crt\--key=/etc/kubernetes/pki/etcd/server.key# 验证快照完整性ETCDCTL_API=3etcdctl snapshot status /backup/etcd-2026-07-28.db-wtable# 显示: 数据库大小、revision、总key数、是否被截断5.2 从快照恢复
# 恢复流程(灾难恢复):# 1. 停掉所有 API Server (kubectl不可用时用systemctl)# 2. 用快照恢复etcd数据ETCDCTL_API=3etcdctl snapshot restore /backup/etcd-2026-07-28.db\--data-dir=/var/lib/etcd-restore\--name=etcd-0\--initial-cluster=etcd-0=https://127.0.0.1:2380\--initial-cluster-token=etcd-cluster\--initial-advertise-peer-urls=https://127.0.0.1:2380# 3. 把恢复的数据目录替换原目录# 4. 重启etcd和API Server# 5. 集群"复活",所有资源回到快照时刻的状态要点:etcd快照是K8s的"后悔药"。生产环境务必定期自动备份(CronJob或Velero,见第082篇),并且定期演练恢复——很多人备份了但从没试过恢复,真出事时发现备份是坏的。记住:不演练的备份等于没备份。
本篇小结
etcd是K8s唯一的持久化真源,所有资源最终都序列化进它。它用Raft保证强一致和高可用——3节点可挂1个、5节点可挂2个,但要求低延迟网络(同机房、SSD)。数据按/registry/<资源类型>/<ns>/<名>组织,所以etcd必须加密。
性能命门是磁盘IO和数据库大小(记得调大配额+定期compact/defrag)。最关键的运维技能是etcdctl snapshot save/restore——定期备份、定期演练恢复,这是集群失忆后的唯一救命稻草。下篇讲Controller Manager——K8s的"自动驾驶仪"。
上一篇【第60篇】API Server深度解析——K8s的“总控制器“是怎么把请求玩弄于股掌的
下一篇【第62篇】Controller Manager——K8s的"自动驾驶仪"