etcd — Kubernetes 的分布式存储大脑
什么是 etcd
etcd 是一个强一致性的分布式键值存储,是 Kubernetes 集群状态的唯一真实来源(Single Source of Truth)。集群中所有对象的状态——Pod、Service、ConfigMap、Secret 等——都持久化在 etcd 中。
核心定位:etcd 是 K8s 的"数据库",API Server 是唯一与 etcd 直接通信的组件。
Raft 共识算法
etcd 使用 Raft 算法保证分布式一致性:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Leader │◄──►│Follower │◄──►│Follower │
│ (主节点) │ │ (从节点) │ │ (从节点) │
└─────────┘ └─────────┘ └─────────┘
│
│ 写入请求
▼
日志复制到多数节点 → 提交 → 应用到状态机关键特性:
- 写操作必须经过 Leader,复制到多数节点后才提交
- 读操作默认走 Leader(线性一致性读)
- 节点数建议奇数:3、5、7(容忍 1、2、3 个节点故障)
数据存储结构
K8s 对象在 etcd 中以路径形式存储:
/registry/pods/default/my-pod
/registry/deployments/default/my-deploy
/registry/services/specs/default/my-svc
/registry/configmaps/default/my-cm
/registry/secrets/default/my-secret数据以 Protobuf 格式序列化(比 JSON 更紧凑高效)。
Watch 机制
etcd 的 Watch 是 K8s 事件驱动架构的基础:
go
// API Server 监听 etcd 变化,推送给 Informer
watchChan := etcdClient.Watch(ctx, "/registry/pods/", clientv3.WithPrefix())
for resp := range watchChan {
for _, event := range resp.Events {
switch event.Type {
case mvccpb.PUT: // 创建或更新
case mvccpb.DELETE: // 删除
}
}
}MVCC(多版本并发控制):etcd 保留历史版本,支持从任意版本开始 Watch,避免事件丢失。
关键配置参数
yaml
# etcd 启动参数(生产环境关键配置)
--data-dir=/var/lib/etcd # 数据目录
--listen-peer-urls=https://0.0.0.0:2380
--listen-client-urls=https://0.0.0.0:2379
--initial-cluster-state=new # new | existing
--auto-compaction-retention=8h # 自动压缩历史版本
--quota-backend-bytes=8589934592 # 存储配额 8GB
--snapshot-count=10000 # 快照触发阈值
--heartbeat-interval=100 # 心跳间隔 ms
--election-timeout=1000 # 选举超时 ms性能调优
磁盘 I/O 优化
bash
# etcd 对磁盘延迟极敏感,建议使用 SSD
# 测试磁盘延迟
fio --rw=write --ioengine=sync --fdatasync=1 \
--directory=/var/lib/etcd --size=22m \
--bs=2300 --name=mytest
# 调整磁盘调度器
echo deadline > /sys/block/sda/queue/scheduler网络优化
bash
# etcd 节点间网络延迟应 < 10ms
# 生产环境建议专用网络备份与恢复
bash
# 备份快照
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).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=3 etcdctl snapshot status /backup/etcd-20240101.db
# 恢复快照
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-20240101.db \
--data-dir=/var/lib/etcd-restore \
--name=master-1 \
--initial-cluster=master-1=https://192.168.1.1:2380 \
--initial-advertise-peer-urls=https://192.168.1.1:2380常用运维命令
bash
# 查看集群成员
etcdctl member list -w table
# 查看集群健康状态
etcdctl endpoint health --cluster
# 查看 K8s 存储的所有 key
etcdctl get /registry --prefix --keys-only
# 查看某个 Pod 的原始数据
etcdctl get /registry/pods/default/my-pod -w json | python3 -m json.tool
# 手动压缩历史版本(释放空间)
REV=$(etcdctl endpoint status --write-out="json" | jq '.[] | .Status.header.revision')
etcdctl compact $REV
etcdctl defrag
# 监控存储使用量
etcdctl endpoint status -w table监控指标
关键 Prometheus 指标:
etcd_server_has_leader # 是否有 Leader
etcd_server_leader_changes_seen_total # Leader 切换次数
etcd_disk_wal_fsync_duration_seconds # WAL 写入延迟
etcd_disk_backend_commit_duration_seconds # 后端提交延迟
etcd_network_peer_round_trip_time_seconds # 节点间 RTT
etcd_mvcc_db_total_size_in_bytes # 数据库大小生产部署建议
| 场景 | 节点数 | 配置 |
|---|---|---|
| 开发/测试 | 1 | 2C/4G/SSD 20G |
| 小规模生产 | 3 | 4C/8G/SSD 50G |
| 大规模生产 | 5 | 8C/16G/NVMe 100G |
重要:etcd 节点应与 Control Plane 其他组件分离部署,避免资源竞争。