Skip to content

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          # 数据库大小

生产部署建议

场景节点数配置
开发/测试12C/4G/SSD 20G
小规模生产34C/8G/SSD 50G
大规模生产58C/16G/NVMe 100G

重要:etcd 节点应与 Control Plane 其他组件分离部署,避免资源竞争。

本站内容由 褚成志 整理编写,仅供学习参考