Kubernetes etcd 运维与灾备

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
API Application Programming Interface 应用程序编程接口
CA Certificate Authority 证书颁发机构
CPU Central Processing Unit 中央处理器
CRD Custom Resource Definition Kubernetes 自定义资源定义
DNS Domain Name System 域名系统
EKS Elastic Kubernetes Service AWS 托管 Kubernetes 服务
GitOps GitOps 以 Git 保存期望状态、由自动化持续协调实际状态的运维方式
I/O Input/Output 输入/输出
IOPS Input/Output Operations Per Second 每秒输入输出操作数
IP Internet Protocol 网际协议;IP 地址是网络寻址标识
KMS Key Management Service 密钥管理服务
PKI Public Key Infrastructure 公钥基础设施
PV Persistent Volume 持久卷
RBAC Role-Based Access Control 基于角色的访问控制
RPO Recovery Point Objective 恢复点目标,可接受的数据丢失时间范围
RTO Recovery Time Objective 恢复时间目标,可接受的恢复耗时
SAN Subject Alternative Name 证书主题备用名称,用于声明域名或 IP
SLO Service Level Objective 服务等级目标
TLS Transport Layer Security 传输层安全协议

适用于有控制面主机权限的自建 Kubernetes。以下以 kubeadm 静态 Pod、三成员 etcd 为例,地址和路径需按实际清单调整;托管 EKS/GKE 控制面不执行这些命令。

1. 确认连接与健康状态#

在控制面主机的 Bash 中执行。先检查 /etc/kubernetes/manifests/etcd.yaml 的镜像版本、--data-dir、挂载目录及 TLS 参数,再准备匹配版本的 etcdctl 和 etcdutl。

export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/healthcheck-client.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/healthcheck-client.key

etcdctl member list --write-out=table
etcdctl endpoint status --cluster --write-out=table
etcdctl endpoint health --cluster
etcdctl alarm list

--cluster 使用成员公布的客户端地址,当前主机必须能访问且证书 SAN 匹配。验收:3 个成员健康、恰好一个 Leader、无告警,Raft applied index 在持续写入时可短暂不同,但不应长期落后。

不批量导出键值来“巡检”,其中可能包含 Secret。检查 Kubernetes 对象使用 kubectl。

2. 在线快照与备份策略#

快照从一个健康 endpoint 获取;etcdctl 保存,etcdutl 检查和恢复。不要用复制运行中数据目录代替一致性快照。

set -euo pipefail
umask 077
BACKUP_DIR=/var/backups/etcd
install -d -m 0700 "$BACKUP_DIR"
SNAPSHOT="$BACKUP_DIR/etcd-$(date -u +%Y%m%dT%H%M%SZ).db"

etcdctl --endpoints=https://127.0.0.1:2379 snapshot save "$SNAPSHOT"
etcdutl snapshot status "$SNAPSHOT" --write-out=table
(cd "$BACKUP_DIR" && sha256sum "$(basename "$SNAPSHOT")" > "$(basename "$SNAPSHOT").sha256")

自动化任务需显式设置上述 TLS 环境变量,避免重叠执行,失败立即告警。上传到加密、受限访问的异机存储后校验对象完整性;不要将唯一副本留在控制面磁盘。

项目 实施要求
周期 按 RPO 设置,例如每 15 分钟;备份失败或传输延迟会扩大实际 RPO
保留 示例:最近 48 小时保留全部快照,日备份保留 30 天;按容量与合规调整
配套资产 Kubernetes/etcd 版本、成员名/IP、静态 Pod 清单、PKI、加密配置及 KMS 恢复权限
演练 在隔离环境恢复并验证对象可读;记录恢复耗时作为 RTO 依据
业务数据 PV、数据库、对象存储单独备份,协调应用一致性

快照可能包含敏感数据,应限制读取权限。KMS 不可用或旧密钥已销毁时,只有快照也可能无法解密 Kubernetes 资源。

3. 先选择正确的故障处理#

故障 操作
3 个成员中 1 个不可用,另外 2 个健康 修复或替换该成员,保持现有集群数据
多数成员暂时不可达 优先恢复网络、磁盘、证书或进程,不立即回滚数据
多数成员永久丢失 隔离旧集群,从已验证快照重建全部成员
单个 Kubernetes 对象误删 优先通过 GitOps 或对象级备份恢复,避免全局回滚
大范围逻辑破坏 选择故障前快照,评估丢失写入及外部系统一致性后整体恢复

4. 三节点灾备恢复流程#

本例在原三台主机恢复;成员名为 cp1/cp2/cp3,peer 地址为 10.0.1.10/10.0.2.10/10.0.3.10:2380。变更 IP 时,先更新证书 SAN、防火墙和 API Server 的 etcd endpoint。

4.1 冻结与隔离#

  1. 暂停发布、GitOps 自动同步和入口变更,记录故障时间、快照时间及预期丢失窗口。
  2. 在所有控制面节点将 kube-apiserver.yaml 移出静态 Pod 目录,确认 API Server 容器已停止;同时暂停 controller-manager、scheduler,防止恢复过程中自动协调。
  3. 在所有 etcd 节点将 etcd.yaml 移出该目录,确认 etcd 容器和监听端口已停止。使用 crictl ps 检查,不能只依赖已不可用的 API。
  4. 隔离任何可能重新上线的旧成员;保留原数据目录和清单,禁止新旧集群并行接受请求。

清单备份必须放在 /etc/kubernetes/manifests/ 之外,仅改成 .bak 仍可能被 kubelet 读取。外部 etcd 则停止对应 systemd 服务。参考 Kubernetes 恢复说明。

4.2 在每个成员离线恢复#

将同一个快照与校验文件安全复制到三台主机。保留原文件名;校验文件记录相对文件名,可跨主机验证。校验和应来自受限备份记录,不能与损坏文件一起重新生成。以下命令在每台主机执行一次,分别修改 MEMBER_NAME 和 PEER_IP;目标目录必须不存在。

set -euo pipefail
MEMBER_NAME=cp1
PEER_IP=10.0.1.10
INITIAL_CLUSTER='cp1=https://10.0.1.10:2380,cp2=https://10.0.2.10:2380,cp3=https://10.0.3.10:2380'
RESTORE_TOKEN=etcd-dr-20260922
SNAPSHOT=/var/backups/etcd/REPLACE_ORIGINAL_SNAPSHOT_FILENAME.db
(cd "$(dirname "$SNAPSHOT")" && sha256sum -c "$(basename "$SNAPSHOT").sha256")
etcdutl snapshot status "$SNAPSHOT" --write-out=table

etcdutl snapshot restore "$SNAPSHOT" --name "$MEMBER_NAME" --data-dir /var/lib/etcd-restored --initial-cluster "$INITIAL_CLUSTER" --initial-advertise-peer-urls "https://$PEER_IP:2380" --initial-cluster-token "$RESTORE_TOKEN" --bump-revision 1000000000 --mark-compacted

三节点使用相同 cluster 列表、token 和 Revision bump,成员名及 peer 地址各不相同。1000000000 是示例增量,应大于“快照年龄 × 峰值 Revision 增长率”并留余量。--mark-compacted 迫使 Watch 客户端重新同步。不要使用 --skip-hash-check 绕过损坏快照。参数依据 etcd 恢复文档。

4.3 启动 etcd,再启动控制面#

  1. 检查恢复目录属主、权限和 SELinux 上下文与原目录要求一致。
  2. 修改移出的 etcd 清单:将数据卷 hostPath.path 改为 /var/lib/etcd-restored;容器内 mountPath 与 --data-dir 保持一致。例如二者仍为 /var/lib/etcd,只是宿主机路径改变。核对成员名、peer 地址、cluster 列表和 token,与恢复命令一致。
  3. 在三台主机放回 etcd 清单,等待形成 quorum。执行第一节的健康检查,确认全部成员正常后才继续。
  4. 放回各节点 API Server 清单,确认原 PKI、加密配置和 KMS 可用;随后恢复 controller-manager、scheduler,重启其他使用 Watch 缓存的控制器,使其重新同步。
  5. 完成下面的验收,再恢复 GitOps、发布和业务流量。若失败,保持冻结并排障;不要让旧数据目录与恢复集群混用。

4.4 验收与业务对账#

kubectl get --raw='/readyz?verbose'
kubectl get nodes
kubectl get pods -A
kubectl get pvc -A
kubectl get events -A --sort-by=.metadata.creationTimestamp

kubectl create namespace etcd-dr-check
kubectl -n etcd-dr-check create configmap write-check --from-literal=status=ok
kubectl -n etcd-dr-check get configmap write-check -o jsonpath='{.data.status}'
kubectl delete namespace etcd-dr-check

确认关键 CRD、RBAC 和受加密资源可由授权工作负载正常读取,不将 Secret 值打印到日志。执行业务读写、DNS、Ingress、存储挂载及控制器收敛检查。快照之后的资源变更会丢失,但云负载均衡器、PV 和外部数据库不会随之回滚,需对账孤立资源、重复任务及订单状态。最后生成新快照并记录实际 RPO/RTO。

5. 日常维护与成员替换#

历史压缩与碎片整理#

先核对 API Server 的 --etcd-compaction-interval 与现有自动压缩策略,避免重复配置。只有确定保留窗口后才手工执行:

# 用经评估的历史 Revision 替换占位值,不要盲目压缩到最新版本。
COMPACT_REV='<保留窗口之前的 Revision>'
etcdctl compact "$COMPACT_REV"

# 一次只处理一个成员:先 follower,确认恢复健康后再处理下一个。
etcdctl --endpoints=https://10.0.2.10:2379 --command-timeout=60s defrag
etcdctl endpoint health --cluster

在线 Defrag 会阻塞该成员读写,安排低峰期,Leader 最后处理。NOSPACE 时先控制增长来源,经 Kubernetes API 清理不需要的资源,再压缩与逐成员 Defrag;确认低于配额后执行 etcdctl alarm disarm,最后通过 Kubernetes API 验证写入。不要直接删除 /registry/ 数据。见 etcd 维护文档。

替换永久故障成员#

前提:其余投票成员仍构成 quorum,并已完成快照。每次只替换一个成员;kubeadm 管理的控制面优先遵循其节点移除/加入流程,避免与手工成员变更重复。

# 先核对 member list;这些 ID 是十六进制占位值。
FAILED_MEMBER_ID='<故障成员 ID>'
etcdctl member remove "$FAILED_MEMBER_ID"
etcdctl member add cp4 --peer-urls=https://10.0.4.10:2380 --learner

在新节点配置有效的 peer/client TLS、空数据目录,按 member add 输出设置成员列表并使用 initial-cluster-state=existing 启动。等待日志追平后执行:

NEW_MEMBER_ID='<新 learner 的 ID>'
etcdctl member promote "$NEW_MEMBER_ID"
etcdctl member list --write-out=table
etcdctl endpoint health --cluster

Learner 不参与投票;未追平时 Promote 会被拒绝,等待排障后重试,不关闭严格检查。禁止让已移除成员携带旧数据目录重新加入。见成员变更说明。

升级时先验证 Kubernetes 兼容范围并备份,按对应 etcd 版本升级指南逐成员滚动升级,每步检查健康;不要同时重启多数成员或直接跳过 minor 版本。

6. 监控与排障#

通过受限网络采集 /metrics,不要公开暴露。指标见官方监控文档,阈值应结合磁盘、网络基线和控制面 SLO 制定。

信号或现象 优先检查
etcd_server_has_leader = 0 quorum、2380 连通性、成员进程及证书
etcd_server_leader_changes_seen_total 短期频繁增长 磁盘 fsync、网络抖动、CPU 饥饿
etcd_disk_wal_fsync_duration_seconds、etcd_disk_backend_commit_duration_seconds 延迟升高 磁盘 IOPS/延迟、容量、同机 I/O 竞争
etcd_mvcc_db_total_size_in_bytes 接近 etcd_server_quota_backend_bytes 与 etcd_mvcc_db_total_size_in_use_in_bytes 对比,区分有效数据增长与碎片
etcd_server_proposals_pending 持续升高 写入压力、Leader、网络与磁盘瓶颈
x509 错误 证书有效期、CA、SAN、主机时间;kubeadm 可用 kubeadm certs check-expiration
request timed out / context deadline exceeded 先确认健康、quorum 与延迟,不先增大超时掩盖故障
required revision has been compacted Watch 重新 List 后重建;长期循环检查客户端重试逻辑
快照失败或备份年龄超限 磁盘空间、TLS、定时任务环境、上传状态与告警链路

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭