8.1 K8s 生产运维:etcd 备份与恢复

预计阅读时间:17 分钟

📖 目录

etcd 是 Kubernetes 控制面的数据存储,保存了集群的全部状态——Pod、Service、ConfigMap、Secret 等。etcd 数据丢失意味着整个集群的配置丢失。生产环境必须做好 etcd 备份策略。

学习目标

  • 理解 etcd 在 Kubernetes 架构中的角色及其数据模型
  • 掌握手动与自动化两种 etcd 快照备份方式
  • 能够在灾难场景下安全地恢复 etcd 数据并验证集群状态
  • 建立生产级别的备份策略与监控告警体系

前置知识

  • 熟悉 Kubernetes 控制面组件(kube-apiserver、etcd、controller-manager、scheduler)的基本职责
  • 了解 TLS 证书体系——etcd 通信依赖 mTLS 认证
  • 具备 Linux 系统管理基础:systemctl、文件权限、证书路径
  • 了解 kubeadm 部署方式下静态 Pod 的管理机制(manifest 目录)

etcd 架构回顾

  • etcd 是分布式的键值存储,基于 Raft 共识算法
  • K8s 控制面组件(kube-apiserver)是唯一直接读写 etcd 的组件
  • 集群推荐 3 或 5 节点奇数部署(容忍 (n-1)/2 节点故障)
  • 数据存储路径:/var/lib/etcd/
  • etcd 默认存储配额为 2GB,超过后集群进入只读模式
  • Raft 日志会无限增长,需要配置自动压缩(auto-compaction)

etcd 与 K8s 的交互流程

所有 K8s 资源的增删改查都经过 kube-apiserver 转译为 etcd 的 key-value 操作。资源以 /registry/<resource-type>/<namespace>/<name> 的路径存储。例如一个名为 my-pod 的 Pod 存储在 /registry/pods/default/my-pod。理解这一路径结构有助于在极端情况下手动排查 etcd 数据。

Raft 共识与 Leader 选举

  • etcd 集群通过 Raft 协议保证数据一致性
  • 写操作必须经过 Leader 节点复制到多数节点后才返回成功
  • 3 节点容忍 1 台故障,5 节点容忍 2 台故障
  • Leader 选举超时默认为 1000ms,心跳间隔为 100ms

前提条件

# 确认 etcdctl 已安装
etcdctl version

# K8s 1.29+ 中 etcd 快照需要设置环境变量
export ETCDCTL_API=3
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/server.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key

# kubeadm 部署的集群,etcd 运行在 Pod 中
# 通过 kubectl 进入 etcd pod 操作更方便

证书文件说明

证书用途默认路径
ca.crtetcd CA 根证书,验证服务端身份/etc/kubernetes/pki/etcd/ca.crt
server.crtetcd 服务端证书,客户端验证服务端/etc/kubernetes/pki/etcd/server.crt
server.keyetcd 服务端私钥/etc/kubernetes/pki/etcd/server.key
peer.crtetcd 节点间通信证书(集群内部)/etc/kubernetes/pki/etcd/peer.crt
healthcheck-client.crt健康检查客户端证书/etc/kubernetes/pki/etcd/healthcheck-client.crt

1. 手动创建快照

方式一:通过 etcdctl(控制面节点上执行)

sudo etcdctl snapshot save /backup/etcd-snapshot-$(date +%F).db

# 验证快照
sudo etcdctl snapshot status /backup/etcd-snapshot-2026-07-30.db -w table

# 输出示例:
# +----------+----------+------------+------------+
# |   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
# +----------+----------+------------+------------+
# | xxxx     |  123456  |     5678   |    120 MB  |
# +----------+----------+------------+------------+

# 以 JSON 格式输出(适合脚本解析)
sudo etcdctl snapshot status /backup/etcd-snapshot-2026-07-30.db -w json

方式二:etcd Pod 内执行(kubeadm 集群)

# 进入 etcd pod
kubectl -n kube-system exec -it etcd-master -- sh

# 在 pod 内执行快照
ETCDCTL_API=3 etcdctl --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 \
  snapshot save /var/lib/etcd/snapshot.db

# 从 pod 复制到宿主机
kubectl -n kube-system cp etcd-master:/var/lib/etcd/snapshot.db /backup/

# 一行命令完成(不进入 Pod)
kubectl -n kube-system exec etcd-master -- \
  ETCDCTL_API=3 etcdctl snapshot save /tmp/snapshot.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

方式三:通过 kube-apiserver 的 /healthz 间接验证

# 确认 etcd 健康(apiserver 能连接到 etcd)
kubectl get --raw /healthz/etcd
# 输出 "ok" 表示正常

# 查看 etcd 的 leader 状态
kubectl -n kube-system exec etcd-master -- \
  etcdctl endpoint status --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 -w table

2. 自动化备份(推荐方式)

使用 etcd-backup CronJob 或 Velero:

# etcd-backup CronJob YAML
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup
  namespace: kube-system
spec:
  schedule: "0 */6 * * *"  # 每 6 小时
  jobTemplate:
    spec:
      template:
        spec:
          nodeName: master-node  # 在控制面节点运行
          hostNetwork: true
          containers:
          - name: etcdctl
            image: bitnami/etcd:3.5
            env:
            - name: ETCDCTL_API
              value: "3"
            - name: ETCDCTL_ENDPOINTS
              value: https://127.0.0.1:2379
            - name: ETCDCTL_CACERT
              value: /certs/ca.crt
            - name: ETCDCTL_CERT
              value: /certs/server.crt
            - name: ETCDCTL_KEY
              value: /certs/server.key
            command:
            - /bin/sh
            - -c
            - etcdctl snapshot save /backup/snapshot-$(date +%Y%m%d-%H%M).db
              # 保留最近 30 个快照,删除旧的
              ls -t /backup/etcd-*.db | tail -n +31 | xargs -r rm
              # 验证快照完整性
              etcdctl snapshot status /backup/etcd-$(date +%Y%m%d-%H%M).db -w json
            volumeMounts:
            - name: etcd-certs
              mountPath: /certs
              readOnly: true
            - name: backup
              mountPath: /backup
          volumes:
          - name: etcd-certs
            hostPath:
              path: /etc/kubernetes/pki/etcd
              type: Directory
          - name: backup
            hostPath:
              path: /backup/etcd
              type: DirectoryOrCreate
          restartPolicy: OnFailure

备份到对象存储(S3/OSS)

本地备份不够安全,推荐将快照同步到云对象存储:

# 在 CronJob 中增加上传步骤
- /bin/sh
- -c
- |
  BACKUP_FILE="/backup/etcd-$(date +%Y%m%d-%H%M).db"
  etcdctl snapshot save "$BACKUP_FILE"
  etcdctl snapshot status "$BACKUP_FILE" -w json
  
  # 上传到 S3
  aws s3 cp "$BACKUP_FILE" s3://my-etcd-backups/$(date +%Y/%m/%d)/ \
    --sse AES256
  
  # 清理本地 30 天前的备份
  find /backup -name "etcd-*.db" -mtime +30 -delete
  
  # 清理 S3 上 90 天前的备份
  aws s3 ls s3://my-etcd-backups/ | while read -r line; do
    dir_date=$(echo "$line" | awk '{print $2}' | tr -d '/')
    if [[ $(date -d "$dir_date" +%s) -lt $(date -d "90 days ago" +%s) ]]; then
      aws s3 rm "s3://my-etcd-backups/$dir_date/" --recursive
    fi
  done

3. 快照恢复

恢复操作是高风险操作,需要严格按顺序执行。恢复前确认已获得最新的快照文件。

恢复前检查

# 确认快照文件可用
etcdctl snapshot status /backup/etcd-latest.db -w table

# 记录当前集群状态(如果 apiserver 仍可用)
kubectl get nodes -o wide
kubectl get pods -A -o wide > /tmp/pre-restore-state.txt

# 确认 etcd 数据目录大小
du -sh /var/lib/etcd/

执行恢复

# 1. 停止 kube-apiserver(先停 apiserver,再停 etcd)
sudo systemctl stop kube-apiserver
# 或移动静态 Pod manifest
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/

# 2. 停止 etcd
sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/
# 等待 etcd pod 终止
kubectl -n kube-system wait --for=delete pod/etcd-master --timeout=60s

# 3. 备份当前数据目录(保险起见)
sudo cp -r /var/lib/etcd /var/lib/etcd.bak

# 4. 恢复快照到新数据目录
sudo ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-latest.db \
  --data-dir=/var/lib/etcd-restore \
  --initial-cluster=master=https://127.0.0.1:2380 \
  --initial-advertise-peer-urls=https://127.0.0.1:2380 \
  --name=master

# 5. 替换数据目录
sudo mv /var/lib/etcd /var/lib/etcd.old
sudo mv /var/lib/etcd-restore /var/lib/etcd

# 6. 恢复 etcd manifest
sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/
# 等待 etcd 启动
kubectl -n kube-system wait --for=condition=ready pod/etcd-master --timeout=120s

# 7. 恢复 kube-apiserver
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

# 8. 验证集群状态
kubectl get nodes
kubectl get pods -A

多节点 etcd 集群恢复

对于 3 节点或 5 节点的高可用 etcd 集群,恢复流程略有不同:

# 在所有 etcd 节点上执行恢复(使用同一个快照)
# 每个节点的 --name 和 --initial-cluster 参数不同

# 节点 1
sudo ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-latest.db \
  --data-dir=/var/lib/etcd-restore \
  --name=etcd-0 \
  --initial-cluster=etcd-0=https://10.0.0.1:2380,etcd-1=https://10.0.0.2:2380,etcd-2=https://10.0.0.3:2380 \
  --initial-advertise-peer-urls=https://10.0.0.1:2380

# 节点 2
sudo ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-latest.db \
  --data-dir=/var/lib/etcd-restore \
  --name=etcd-1 \
  --initial-cluster=etcd-0=https://10.0.0.1:2380,etcd-1=https://10.0.0.2:2380,etcd-2=https://10.0.0.3:2380 \
  --initial-advertise-peer-urls=https://10.0.0.2:2380

# 节点 3
sudo ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-latest.db \
  --data-dir=/var/lib/etcd-restore \
  --name=etcd-2 \
  --initial-cluster=etcd-0=https://10.0.0.1:2380,etcd-1=https://10.0.0.2:2380,etcd-2=https://10.0.0.3:2380 \
  --initial-advertise-peer-urls=https://10.0.0.3:2380

4. 备份策略建议

环境备份频率保留策略存储位置
生产每 6 小时本地 30 天 + 云 90 天本地 + 云对象存储
预发每天7 天本地
开发不强制按需本地

5. 快照、压缩与存储配额

快照与 Raft 日志的关系

etcd 的数据由两部分组成:当前状态(内存中的 B+ 树键值)和 Raft 日志(全部写操作的历史)。每次写操作先追加到 Raft 日志,提交后才应用到内存状态机。快照(snapshot)是某个 revision 时刻完整状态的一次持久化拷贝——有了快照之后,之前的 Raft 日志就可以安全丢弃。

数据组成部分存放位置作用
WAL(Write-Ahead Log)/var/lib/etcd/member/wal/记录每次写入,崩溃后重放恢复,防止丢数据
snap(快照文件)/var/lib/etcd/member/snap/定期保存的状态副本,加速重启恢复
db(后端数据库)/var/lib/etcd/member/dbboltDB 持久化的键值数据(db 是文件不是目录),即快照本体

理解这一点是备份策略的前提:etcdctl snapshot save 保存的是 boltDB 数据库文件的在线拷贝,它天然是一致的(内部有事务保证),不需要像 MySQL 那样先锁表再备份。

自动压缩(auto-compaction)

如果不做压缩,Raft 历史会无限增长,最终耗尽存储并触发告警。etcd 3.5 起推荐使用 --auto-compaction-retention 按小时或按 revision 数压缩:

# 方式一:按时间保留(推荐,单位可以是 h/m/s)
--auto-compaction-retention=8h   # 保留最近 8 小时的历史版本

# 方式二:按 revision 数量保留
--auto-compaction-retention=100000  # 保留最近 10 万个 revision

# 查看当前压缩状态(Compaction 相关字段)
ETCDCTL_API=3 etcdctl endpoint status --write-out=table

# 手动触发压缩(应急场景)
ETCDCTL_API=3 etcdctl compact 123456
注意 自动压缩只清理"历史版本",不会缩小 db 文件体积——db 文件的物理回收必须依赖碎片整理(defrag)。K8s 场景下 1.29+ 版本默认每 5 分钟自动 defrag 一次,无需人工干预。

存储配额与只读保护

# 默认配额 2GB,超过后写入被拒(集群进入只读)
--quota-backend-bytes=8589934592   # 调大到 8GB(生产常见配置)

# 观察当前 db 大小
du -sh /var/lib/etcd/member/db/
ETCDCTL_API=3 etcdctl endpoint status -w table | grep DB_SIZE

# 配额已满时的应急处理
# 1. 确认不是异常增长(检查是否有循环写操作)
# 2. 压缩 + defrag 回收空间
ETCDCTL_API=3 etcdctl compact --physical $(etcdctl endpoint status -w json | jq -r '.[0].Status.header.revision')
ETCDCTL_API=3 etcdctl defrag
# 3. 若仍无法回收,需在维护窗口重启 etcd 节点

碎片整理的最佳时机

  • defrag 是阻塞操作,会暂时停止节点服务,必须在低峰期执行
  • 多节点集群逐个节点执行,一次只整理一台,避免同时阻塞
  • defrag 前确认该节点不是当前 Leader,或接受短暂写入延迟
  • 整理后立即做一次快照备份——defrag 可能改变 db 文件结构

6. etcd 监控与告警

备份体系的价值建立在"知道什么时候该恢复"之上。etcd 自身的 Prometheus 指标(监听 :2381 指标端口)是判断集群健康的第一手数据:

指标名含义告警阈值
etcd_server_has_leader节点是否能看到 Leader(0/1)0 持续 30s(选主失败)
etcd_server_leader_changes_seen_totalLeader 切换次数5 分钟内增长(频繁选主)
etcd_server_is_leader当前节点是否为 Leader多节点同时为 1(脑裂征兆)
etcd_server_slow_apply_totalapply 耗时超过阈值的次数持续增长(磁盘慢)
etcd_mvcc_db_total_size_in_bytesdb 文件实际大小超过配额 80%
etcd_network_client_grpc_received_bytes_total客户端流量异常突增(扫描或写入风暴)
# Prometheus 告警规则示例(etcd-alerting.yml)
groups:
- name: etcd.rules
  rules:
  - alert: EtcdNoLeader
    expr: etcd_server_has_leader == 0
    for: 30s
    labels:
      severity: critical
    annotations:
      summary: "etcd 集群失去 Leader 超过 30 秒"
  - alert: EtcdLeaderChanges
    expr: increase(etcd_server_leader_changes_seen_total[5m]) > 3
    labels:
      severity: warning
    annotations:
      summary: "etcd 集群 5 分钟内发生多次 Leader 切换"
  - alert: EtcdDbQuotaHigh
    expr: etcd_mvcc_db_total_size_in_bytes / 8589934592 > 0.8
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "etcd 数据库使用量超过配额 80%,即将进入只读模式"
  - alert: EtcdSnapshotFailure
    expr: etcd_server_snapshot_failures_total > 0
    labels:
      severity: critical
    annotations:
      summary: "etcd 快照创建失败,备份链路可能中断"
联动备份监控 仅监控 etcd 本身还不够——备份产物同样要监控:在备份 CronJob 中加入 snapshot status 验证并上报成功/失败指标(如写入文件时间戳),再配合 alertmanager 检查"备份文件超过 8 小时未更新"即可形成完整闭环。

7. 恢复演练全流程

"能恢复的备份才有价值"不是口号——多数团队第一次真正执行恢复都是在故障现场,结果发现快照损坏、证书不匹配、参数记错。恢复演练就是把这些错误提前暴露在可控环境里。

演练设计要点

  • 频率:生产集群每季度至少一次;每次 etcd 或 K8s 大版本升级后追加一次
  • 环境:演练必须使用独立的测试集群,禁止在生产环境"假恢复"
  • 随机性:从备份池随机选取一个快照(而不是每次都拿最新一份),验证历史快照也可用
  • 完整闭环:演练结束要产出报告(RTO 实测值、问题清单、改进项),并纳入下季度计划

演练步骤模板

# 演练场景:单节点集群 etcd 数据目录彻底损坏
# 阶段一:故障注入
sudo systemctl stop kubelet
sudo rm -rf /var/lib/etcd

# 阶段二:恢复(计时开始,作为 RTO 基准)
sudo ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-latest.db \
  --data-dir=/var/lib/etcd-restore \
  --initial-cluster=master=https://127.0.0.1:2380 \
  --initial-advertise-peer-urls=https://127.0.0.1:2380 \
  --name=master
sudo mv /var/lib/etcd-restore /var/lib/etcd
sudo systemctl start kubelet

# 阶段三:验证(计时结束)
kubectl get nodes
kubectl get pods -A
# 抽查关键业务:选 3 个 Namespace,核对资源数量与恢复前记录一致
kubectl get deploy,svc,cm,secret -n production | wc -l
# 检查 etcd 健康
kubectl -n kube-system exec etcd-master -- etcdctl endpoint health

演练验收标准

指标目标值说明
RTO(恢复时间目标)单节点 ≤ 15 分钟;HA 集群 ≤ 30 分钟从故障注入到业务可用
RPO(数据丢失容忍)等于备份周期(如 6 小时)恢复后 revision 落后不超过一个备份周期
数据完整性抽查资源 100% 一致对比恢复前后资源清单
演练报告24 小时内产出含问题清单与改进项

8. 灾备场景与多区域容灾

典型故障场景与应对

场景恢复方式停机影响
单台 etcd 节点宕机(HA 集群)无需恢复,其余节点自动补位,替换故障节点无感知
etcd 数据目录损坏(单节点)从快照恢复(本文第 3 节)RTO 内可恢复
误删除 Namespace/资源(人祸)从快照恢复,接受部分数据回退需评估其他组件一致性
磁盘损坏导致数据全丢新盘 + 快照恢复取决于备份介质可用性
整个可用区故障依赖跨区域备份 + 异地重建数小时级别

多区域容灾方案

单区域灾难(机房断电、云可用区故障)会同时摧毁集群和本地备份,因此生产环境必须满足 3-2-1 原则:3 份副本(1 份集群内 + 2 份独立介质)、2 种存储类型(本地磁盘 + 对象存储)、1 份异地存放(跨区域桶)。

# 跨区域备份的最小实现:本地 CronJob 快照 + 对象存储同步
# 方案 A:AWS S3 跨区域复制(CRR)——主桶开启 CRR 到灾备区域
aws s3api put-bucket-replication --bucket my-etcd-backups \
  --replication-configuration file://crr-config.json

# 方案 B:双写两个区域(备份脚本内两次上传)
aws s3 cp "$BACKUP_FILE" s3://my-etcd-backups/           # 主区域
aws s3 cp "$BACKUP_FILE" s3://dr-etcd-backups/            # 灾备区域桶

# 定期验证异地副本(恢复演练时指定从灾备桶拉取)
aws s3 ls s3://dr-etcd-backups/ | sort -r | head -5
aws s3 cp s3://dr-etcd-backups/$(ls -t | head -1) /backup/dr-test.db
ETCDCTL_API=3 etcdctl snapshot status /backup/dr-test.db -w table
备份快照 + K8s 资源清单双保险 etcd 快照能恢复一切,但用 kubectl get all -A -o yaml 定期导出资源清单(存入 Git),可以在不重启集群的情况下快速核对恢复结果,两者互为印证。

9. 备份产物管理与审计

备份体系运行一段时间后,最常见的失控点是"备份文件散落各处、无人核查"。用清单化管理把备份变成可审计的资产:

管理项建议做法验证方式
命名规范etcd-<集群名>-<日期>-<revision>.dbls 即可追溯来源与新旧
完整性校验每个快照同步生成 SHA256 校验文件sha256sum -c 每日比对
异地留存快照 + 校验文件一起上传对象存储定期从存储下载校验一次
保留期限本地 30 天、云端 90 天(与 RPO 匹配)过期自动清理任务存在且运行
访问权限备份文件含集群全部密钥(Secret),必须加密对象存储服务端加密(SSE)
# 备份审计脚本片段:检查"最新快照是否够新"
#!/bin/bash
# 目标:最新快照不超过 8 小时,否则告警
LATEST=$(ls -t /backup/etcd-*.db | head -1)
AGE_MIN=$(( $(date +%s) - $(stat -c %Y "$LATEST") ))
if [ "$AGE_MIN" -gt 480 ]; then
  echo "ALERT: 最新 etcd 快照已 $AGE_MIN 分钟未更新"
  exit 1
fi
# 校验最近 3 份快照的完整性
for f in $(ls -t /backup/etcd-*.db | head -3); do
  ETCDCTL_API=3 etcdctl snapshot status "$f" -w table || echo "ALERT: 快照损坏 $f"
done
季度审计动作 每季度抽 1 份 30 天前的快照做完整恢复演练,验证"长期保留的备份同样可恢复"——很多团队只测最新快照,等真要用旧快照时才发现已损坏或格式不兼容。

常见错误

问题原因解决方案
etcdctl snapshot save 超时etcd 负载过高或网络延迟降低快照频率,检查 etcd check perf 输出,确认磁盘 IO 正常
恢复后 apiserver 无法启动快照版本与当前 etcd 版本不匹配确认 etcd 二进制版本兼容,使用 etcd --version 检查
恢复后集群数据比预期旧恢复的是旧快照而非最新恢复前务必用 snapshot status 检查 REVISION 字段,选择最大 revision 的快照
多节点恢复后集群无法选主--initial-cluster 参数配置错误确保每个节点的 --name--initial-cluster 中的名称严格一致
etcd 数据目录权限问题sudo 恢复后目录属主变为 root执行 chown -R etcd:etcd /var/lib/etcd 修正权限

最佳实践

  • 定期做恢复演练——不能恢复的备份毫无价值
  • 快照文件加密后上传到异地对象存储(S3/OSS)
  • 监控 etcd 数据库大小(默认 2GB quota,超过后集群只读)
  • etcd 慢查询监控:etcdctl check perf
  • 限制 etcd 历史版本保留数:--auto-compaction-retention=8(保留 8 小时历史)
  • 为备份文件添加 SHA256 校验:sha256sum /backup/etcd-snapshot.db > /backup/etcd-snapshot.db.sha256
  • 在 CronJob 中增加快照完整性验证步骤,确保备份文件可用
  • 使用 etcd-defrag 工具定期整理碎片空间,但需在低峰期执行

练习题

  1. 手动备份与验证:在你的测试集群上执行一次手动 etcd 快照,使用 -w json 输出格式获取详细信息,并将 REVISION、TOTAL KEYS、TOTAL SIZE 记录到日志文件中。
  2. 自动化备份 CronJob:编写一个完整的 CronJob YAML,实现每 4 小时自动备份一次 etcd,保留最近 15 个快照,备份完成后自动验证快照完整性,并将结果通过 kubectl create configmap 记录到集群中。
  3. 恢复演练:在测试集群上模拟 etcd 数据丢失场景——先备份,然后手动删除一个 Namespace,再通过恢复快照找回该 Namespace。记录完整的恢复步骤和耗时。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 etcd 的 Raft 一致性协议和数据备份原理尝试向他人讲解
命令操作能不查文档完成 etcd 快照备份、恢复和状态检查在终端实际执行
原理掌握能说出 etcd 数据恢复的完整流程和注意事项画出流程图
故障排查能独立排查 etcd 集群选举失败或数据损坏的问题模拟故障并修复
最佳实践能说明为什么需要定期进行 etcd 恢复演练对比不同方案

本章总结

备份本身没有价值,能恢复的备份才有价值——因此必须定期做恢复演练,并遵循 3-2-1 原则:3 份副本、2 种存储介质、1 份异地存放。生产环境用 CronJob 自动化快照并加入完整性校验(snapshot status/MD5),同时监控 etcd 数据库大小(2GB 配额)与慢查询,防止集群在配额耗尽后进入只读模式。

延伸阅读

  • 6.15:HA 集群 Linux 高可用集群——etcd Raft 选举与备份恢复
  • 5.2:Docker 生产实践 Docker 生产实践——生产级部署策略
  • etcd 官方文档:https://etcd.io/docs/v3.5/op-guide/maintenance/
  • Kubernetes 官方文档:https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
↑ 回到顶部