etcd 是 Kubernetes 的分布式键值存储,也是整个集群的”数据库”与大脑。它通过 Raft 共识保证强一致与高可用,存储着所有资源对象、配置与集群状态。本文从原理到集群部署、备份恢复与运维监控,手把手讲透生产级 etcd 实战。
一、etcd 在 Kubernetes 中的角色与一致性模型
在 K8s 架构里,只有 kube-apiserver 能直接读写 etcd,所有 Controller、Scheduler、kubelet 都通过 API Server 间接访问它。etcd 上保存了 Pod、Service、Secret、CRD 等几乎全部对象,以及集群的当前实时状态。
etcd 底层基于 Raft 共识算法:集群中只有一个 Leader 处理写请求,写操作需被多数派(quorum)确认后才提交,从而保证顺序一致性。读请求默认从 Leader 走线性一致读,因此你拿到的永远是最新已提交数据。配合 watch 机制,etcd 能在 key 变化时主动推送事件,这正是 K8s Controller 实时响应的基础。想先搞懂 K8s 整体对象模型,可回顾 K8s 入门:Pod、Deployment、Service。
正因为 etcd 是集群的唯一真相源,它的性能直接决定整个 K8s 的上限:官方强烈建议用低延迟 SSD 而不是网络盘,因为 Raft 日志的 WAL fsync 延迟会被放大成写吞吐瓶颈。同时 etcd 有 db 配额(v3.5 起默认 8 GiB 可调),超限会触发 NO SPACE 告警并拒绝写入,所以 compact/defrag 不是可选项而是运维必选项。
二、单机快速起步
2.1 二进制启动
从 GitHub Release 下载解压后,直接前台启动一个单节点 etcd:
# 下载并解压
wget https://github.com/etcd-io/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz
tar xzf etcd-v3.5.17-linux-amd64.tar.gz
cd etcd-v3.5.17-linux-amd64
# 前台启动单节点(默认监听 2379 客户端、2380 peer)
./etcd --name infra0 \
--data-dir /var/lib/etcd/infra0 \
--listen-client-urls http://127.0.0.1:2379 \
--advertise-client-urls http://127.0.0.1:2379
2.2 容器方式(包含 etcdctl)
如果只是本地验证,用官方镜像一条命令即可,避免单独安装客户端。组合编排思路与 Docker Compose 一键编排 一致:
docker run -d --name etcd -p 2379:2379 -p 2380:2380 \
quay.io/coreos/etcd:v3.5.17 \
/usr/local/bin/etcd \
--name infra0 --data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://0.0.0.0:2379
# 进入容器执行客户端命令
docker exec etcd etcdctl put hello world
验证健康状态(注意 v3 API 需显式指定 ETCDCTL_API=3):
ETCDCTL_API=3 etcdctl endpoint health
# 127.0.0.1:2379 is healthy: successfully committed proposal
三、核心操作:put / get / watch / lease
etcd 的接口极简,本质是”带版本的键值对”。下面是最常用的一组操作:
# 写入与读取
ETCDCTL_API=3 etcdctl put /app/config/timeout "30s"
ETCDCTL_API=3 etcdctl get /app/config/timeout
# 范围读取(前缀)
ETCDCTL_API=3 etcdctl get /app/config/ --prefix
# 带租约的临时 key(TTL 后自动过期,常用于选主/锁)
ETCDCTL_API=3 etcdctl lease grant 60 # 返回 lease ID,如 694d6bb6c2d3e6d8
ETCDCTL_API=3 etcdctl put /app/leader node1 --lease=694d6bb6c2d3e6d8
# 监听变化(另开终端 put 一个新值即可看到事件推送)
ETCDCTL_API=3 etcdctl watch /app/config/ --prefix
watch 是 etcd 区别于普通 KV 的关键能力——K8s 的所有控制器正是靠它实现”配置变更秒级生效”。
| 子命令 | 作用 | 典型场景 |
|---|---|---|
| put | 写入/覆盖 key | 保存配置、状态 |
| get | 读取 key(支持 –prefix/–rev) | 查询、回滚到历史版本 |
| watch | 订阅 key 变更事件 | 配置热更新、控制器同步 |
| lease | 绑定 TTL 租约 | Leader 选举、分布式锁 |
| member | 集群成员管理 | 扩容、剔除故障节点 |
四、搭建 3 节点高可用集群
生产环境必须用奇数节点(3/5/7)以保证 quorum。下面是静态初始化方式,三台机器各自指定 --initial-cluster:
# 节点 infra1(另两台把 name/ip 改掉即可)
etcd --name infra1 \
--data-dir /var/lib/etcd/infra1 \
--initial-advertise-peer-urls http://10.0.0.1:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://10.0.0.1:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster 'infra1=http://10.0.0.1:2380,infra2=http://10.0.0.2:2380,infra3=http://10.0.0.3:2380' \
--initial-cluster-state new
初始化完成后,用 member list 确认三节点已就位并选出 Leader:
ETCDCTL_API=3 etcdctl --endpoints=10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379 \
member list -w table
# 输出应显示 3 行,其中 1 个 isLeader=true
五、快照备份与灾难恢复
etcd 数据是 K8s 的”命根子”,定期快照是底线操作。v3 的快照是的一致性点-in-time 备份,可在运行时执行:
# 生成快照
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%F).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem --cert=/etc/etcd/etcd.pem --key=/etc/etcd/etcd-key.pem
# 校验快照状态
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-2026-10-09.db -w table
恢复时先把快照还原到新的 data-dir,再启动节点。注意 --initial-cluster 要与快照来源集群一致,--name 和 --data-dir 要对应:
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-2026-10-09.db \
--name infra1 --data-dir /var/lib/etcd/infra1-restored \
--initial-cluster 'infra1=http://10.0.0.1:2380,...' \
--initial-cluster-token etcd-cluster-1
# 然后用 --data-dir /var/lib/etcd/infra1-restored 重新启动 etcd
5.1 用 cron 固化自动化快照
手动快照容易遗漏,生产上应把备份固化成定时任务。下面这段每天凌晨对本地节点做一次快照,并自动清理 7 天前的旧文件:
# /etc/cron.d/etcd-backup
0 3 * * * root ETCDCTL_API=3 etcdctl snapshot save \
/backup/etcd-$(date +\%F).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem --cert=/etc/etcd/etcd.pem --key=/etc/etcd/etcd-key.pem \
&& find /backup -name 'etcd-*.db' -mtime +7 -delete
六、数据压缩与碎片整理
etcd 采用多版本并发控制(MVCC),每次写都会保留历史版本,旧版本不会自动消失,因此磁盘会持续增长。必须定期 compact(逻辑丢弃历史版本)并 defrag(物理回收空间):
# 压缩到当前版本(也可指定 --physical 一起做)
ETCDCTL_API=3 etcdctl compact $(ETCDCTL_API=3 etcdctl endpoint status --write-out=json | jq -r '.[0].Status.header.revision')
# 逐个节点离线/在线碎片整理(线上建议一台一台做,避免 quorum 丢失)
ETCDCTL_API=3 etcdctl defrag --endpoints=https://10.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem --cert=/etc/etcd/etcd.pem --key=/etc/etcd/etcd-key.pem
| 操作 | 做了什么 | 是否释放磁盘 |
|---|---|---|
| compact | 丢弃指定版本之前的历史记录 | 否(仅逻辑标记) |
| defrag | 重写 boltdb 文件,回收空闲页 | 是(物理收缩) |
七、开启 TLS 与 RBAC 鉴权
暴露 2379 的集群务必启用传输加密与身份认证。启动时挂上证书,并开启基于角色的访问控制:
# 服务端启用 mTLS
etcd --cert-file=/etc/etcd/etcd.pem --key-file=/etc/etcd/etcd-key.pem \
--client-cert-auth --trusted-ca-file=/etc/etcd/ca.pem \
--listen-client-urls=https://0.0.0.0:2379
# 开启鉴权并创建 root 角色
ETCDCTL_API=3 etcdctl user add root
ETCDCTL_API=3 etcdctl auth enable
证书与密钥的签发、轮换建议交给专业密钥管理系统托管,避免硬编码与泄露,做法可参考 Vault 实战:动态密钥与 PKI 管理。
八、生产运维要点与常见故障排查
| 症状 | 常见原因 | 排查方向 |
|---|---|---|
| Leader 频繁切换 / 无法选主 | 磁盘 IO 慢、心跳超时、节点掉线 | 看 wal_fsync_duration、网络与磁盘 |
| 磁盘写满、告警 | 未 compact/defrag,历史版本堆积 | 立即 compact + defrag |
| 读延迟高 | 大 key、未压缩、db 过大 | 拆分大 value、调 compaction 周期 |
| 升级后起不来 | 跨大版本、storage 格式不兼容 | 小版本滚动升级、先备快照 |
监控上至少盯住四个黄金指标:leader 变更次数、WAL fsync 耗时、db 总大小、提案提交延迟。把它们接到 Prometheus+Grafana 监控告警 做面板与告警,能提前发现绝大多数隐患。由于 etcd 是 GitOps 流水线的状态底座,一旦它异常,ArgoCD 的声明式发布 也会随之失稳,所以备份与监控优先级最高。
告警阈值建议:leader 变更 5 分钟内出现超过 0 次即告警;wal_fsync_duration_p99 持续 >100ms 纳入观察;db 配额使用率 >70% 主动触发压缩任务。把这些规则接进既有的监控与 CI/CD 体系,可以让 etcd 风险在影响业务前就被暴露。
九、etcd 与 Consul / Vault 的边界
三者常被一起提及,但定位不同:etcd 是 K8s 的强一致内部存储;Consul 主打多数据中心的服务发现与健康检查,KV 只是附属能力;Vault 专注密钥、证书与动态凭据。选型上:跑 K8s 就默认 etcd;要做跨集群服务治理看 Consul;要管机密就上 Vault,三者各司其职。
结语
etcd 看似只是个 KV,却是 Kubernetes 高可用的根基。抓住”Raft 强一致、watch 驱动、快照保命、compact/defrag 控盘、TLS+RBAC 守门”五条主线,你就能把生产级 etcd 运维得稳稳当当。把它和监控、密钥管理打通,集群的”大脑”才算真正可靠。




