etcd
集群与数据模型
etcd 是使用 Raft 的一致性键值存储,常作为 Kubernetes 控制面存储。v3 API 使用扁平 key 空间,/ 只是约定的前缀;旧 v2 API 的目录与命令不能直接套用到 v3。
- 生产通常采用 3 或 5 个投票成员,3 个成员可容忍 1 个故障,5 个可容忍 2 个。
- 写入由 Leader 复制并经多数派提交;失去 quorum 后无法正常提交写入。
- 默认线性一致读需协调集群;显式选择 serializable 读可能获得旧数据。
- 每次事务提交产生 revision;Watch 可从 revision 订阅变化,但被压缩的历史不能无限重放。
- Lease 用于带 TTL 的键;分布式锁还应考虑过期持有者和外部系统的 fencing。
三节点部署参数
以 etcd 3.5/3.6 的 v3 API 为基础,实际使用受支持且经过兼容验证的补丁版本。每台机器有独立的低延迟持久磁盘,配置 TLS 证书、时间同步和受限防火墙。示例节点为 10.0.0.11、.12、.13。
第一台 /etc/etcd/etcd.yaml,其余两台修改 name 和本机地址:
name: etcd-1
data-dir: /var/lib/etcd
listen-client-urls: https://10.0.0.11:2379,https://127.0.0.1:2379
advertise-client-urls: https://10.0.0.11:2379
listen-peer-urls: https://10.0.0.11:2380
initial-advertise-peer-urls: https://10.0.0.11:2380
initial-cluster: etcd-1=https://10.0.0.11:2380,etcd-2=https://10.0.0.12:2380,etcd-3=https://10.0.0.13:2380
initial-cluster-state: new
initial-cluster-token: example-etcd-cluster
client-transport-security:
cert-file: /etc/etcd/pki/server.crt
key-file: /etc/etcd/pki/server.key
client-cert-auth: true
trusted-ca-file: /etc/etcd/pki/ca.crt
peer-transport-security:
cert-file: /etc/etcd/pki/peer.crt
key-file: /etc/etcd/pki/peer.key
client-cert-auth: true
trusted-ca-file: /etc/etcd/pki/ca.crt
证书 SAN 包含实际访问 IP/DNS,peer 证书满足双向认证用途。每台 name 唯一,三台的 initial-cluster 一致,私钥只允许运行用户读取。以专用 etcd 用户运行:
etcd --config-file=/etc/etcd/etcd.yaml
initial-cluster-state: new 仅用于初始化新集群。成员添加、重建或恢复必须走对应流程,不能保留旧 data-dir 后随意更换集群参数。Kubernetes 托管或 kubeadm 管理的 etcd 不应绕开现有生命周期工具另起实例。
客户端状态与读写
以下命令假定已取得授权客户端证书:
export ETCDCTL_API=3
export ETCDCTL_ENDPOINTS=https://10.0.0.11:2379,https://10.0.0.12:2379,https://10.0.0.13:2379
export ETCDCTL_CACERT=/etc/etcd/pki/ca.crt
export ETCDCTL_CERT=/etc/etcd/pki/client.crt
export ETCDCTL_KEY=/etc/etcd/pki/client.key
etcdctl endpoint health --cluster
etcdctl endpoint status --cluster --write-out=table
etcdctl member list --write-out=table
etcdctl alarm list
etcdctl put /demo/config value1
etcdctl get /demo/config
etcdctl get /demo/ --prefix --keys-only
etcdctl watch /demo/ --prefix
在另一个使用相同连接配置的终端执行:
etcdctl put /demo/config value2
etcdctl del /demo/config
只在专用实验前缀下操作,不要在生产 Kubernetes etcd 中直接修改 /registry/。全量遍历会增加负载,也可能泄露凭据和资源内容。
Lease 与事务
etcdctl lease grant 60
记录返回的 lease ID,替换下面的 LEASE_ID:
etcdctl put /demo/lease-key value --lease=LEASE_ID
etcdctl lease timetolive LEASE_ID --keys
etcdctl lease keep-alive LEASE_ID
etcdctl txn 可按 version、revision 或 value 比较后原子执行操作,适合 CAS。事务原子性只覆盖 etcd 内的键,不覆盖外部数据库或 HTTP 请求。
快照备份
从健康的单个 endpoint 获取 v3 快照,避免把多 endpoint 的变量直接用于只接受单端点的备份操作:
umask 077
mkdir -p /backup/etcd
etcdctl --endpoints=https://10.0.0.11:2379 snapshot save /backup/etcd/snapshot.db
etcdutl snapshot status /backup/etcd/snapshot.db --write-out=table
sha256sum /backup/etcd/snapshot.db
快照含 Kubernetes Secret 等敏感数据,应加密、异地保留并定期验证恢复。另行备份证书、配置和版本信息。etcdctl snapshot save 获取一致性快照;直接复制运行中的 data-dir 不能作为同等保证。
快照恢复
etcd 3.6 使用 etcdutl snapshot restore,旧版本命令支持情况以对应版本为准。下面是隔离灾备集群第一台的示例,不要直接覆盖正在运行的集群:
etcdutl snapshot restore /backup/etcd/snapshot.db \
--name etcd-1 \
--data-dir /var/lib/etcd-restored \
--initial-cluster 'etcd-1=https://10.0.0.11:2380,etcd-2=https://10.0.0.12:2380,etcd-3=https://10.0.0.13:2380' \
--initial-advertise-peer-urls https://10.0.0.11:2380 \
--initial-cluster-token restored-etcd-cluster
所有新成员使用同一个快照,各自设置唯一 name、peer URL 和新数据目录,再使用匹配的新配置启动。恢复会创建新逻辑集群,不是向旧集群在线合并键值。版本、文件权限、TLS、成员 ID 与数据完整性均需验收。
恢复 Kubernetes 存储时,旧 revision 可能影响 informer 缓存。按对应 etcd/Kubernetes 灾备文档考虑 --bump-revision 与 --mark-compacted,先通过 etcdutl snapshot restore --help 确认版本支持;不要只恢复快照后假定所有控制器已经重新同步。
压缩、碎片整理与成员变更
Compaction 删除旧 revision 历史;defrag 回收 backend 文件内部空闲空间,两者作用不同。先确认 Watch 客户端的重连与历史保留要求,再选择压缩 revision:
etcdctl compact REVISION
etcdctl --endpoints=https://10.0.0.12:2379 defrag
etcdctl --endpoints=https://10.0.0.13:2379 defrag
etcdctl --endpoints=https://10.0.0.11:2379 defrag
REVISION 必须替换为经评估的整数。在线 defrag 会阻塞该成员的部分读写,应在维护窗口逐个操作、尽量 Leader 最后执行,每步确认健康与 quorum,不能同时对所有成员执行。NOSPACE 告警先清理空间、压缩并整理,再确认条件满足后解除 alarm。
成员变更先 member list,一次只操作一个成员。支持 learner 的版本优先通过 learner 同步新节点,追平后再 promote;不要在已失去 quorum 时试图靠添加成员恢复。
监控与排障
Prometheus 可以通过受保护的客户端端点抓取 /metrics;也可配置独立 metrics listener,并限制其来源。若启用明文独立监听,不能认为它自动继承客户端 mTLS。
scrape_configs:
- job_name: etcd
scheme: https
tls_config:
ca_file: /etc/prometheus/pki/ca.crt
cert_file: /etc/prometheus/pki/client.crt
key_file: /etc/prometheus/pki/client.key
static_configs:
- targets: ["10.0.0.11:2379", "10.0.0.12:2379", "10.0.0.13:2379"]
重点指标包括 etcd_server_has_leader、Leader 变更、proposal 失败/积压、etcd_disk_wal_fsync_duration_seconds、backend commit 延迟、数据库总大小与使用大小、peer RTT。指标名按实际版本核对,Histogram 使用 rate 与 histogram_quantile,不要直接把累计 bucket 当作当前延迟。
| 现象 | 检查方向 |
|---|---|
| 请求超时、Leader 频繁变动 | quorum、peer 网络、磁盘 fsync、CPU/GC 和超时参数 |
| TLS 握手失败 | SAN、CA、证书用途、有效期、节点时钟和私钥权限 |
| database space exceeded | 数据库配额、历史 revision、磁盘空间、compact/defrag 和 alarm |
| required revision has been compacted | 客户端重新全量读取并从新的 revision 继续 Watch |
| 单成员损坏 | 剩余集群健康、官方成员替换流程;不要复制其他成员的数据目录直接加入 |
etcd v2 的 backup、目录操作和旧恢复流程只适用于相应旧版本,不用于新的 v3/Kubernetes 灾难恢复。
评论