# 实验准备(制造测试数据)

在备份前,先在集群中创建一点数据,用于后续验证恢复效果:

kubectl create namespace etcd-test
kubectl run test-pod --image=nginx -n etcd-test

# 阶段一:执行快照备份 (Backup)

1. 确认参数并执行备份 备份必须携带三个证书,并且务必加上 ETCDCTL_API=3 环境变量。考场上快照的目标路径会由题目指定(例如 /opt/etcd-backup.db)。

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 /opt/etcd-backup.db

2. 验证快照(考场好习惯) 确认文件无损且正确生成:

ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/etcd-backup.db

(此时可以执行 kubectl delete namespace etcd-test 删掉刚才的数据,模拟灾难发生。)


# 阶段二:执行快照恢复 (Restore)

1. 收集集群启动参数 为了防止恢复后 ETCD 报错 Member mismatch,必须先从原配置中查出集群参数:

cat /etc/kubernetes/manifests/etcd.yaml  grep "initial-cluster" -A 2 -B 2

2. 确保目标目录绝对干净(防存在报错) 恢复的目标目录(如 /var/lib/etcd-restore绝对不能提前存在。:

sudo rm -rf /var/lib/etcd-restore

3. 执行完全体恢复命令 结合第 1 步查到的参数,将快照数据解压到全新的目录中:

sudo ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
  --name=master \
  --data-dir=/var/lib/etcd-restore \
  --initial-cluster=master=https://192.168.44.121:2380 \
  --initial-cluster-token=etcd-cluster-1 \
  --initial-advertise-peer-urls=https://192.168.44.121:2380

(看到 added member... 即代表数据落盘成功。)


# 阶段三:修改静态 Pod 配置并生效

1. 修改 ETCD 配置文件(最易错点) 打开静态 Pod 的 YAML 文件:

sudo vi /etc/kubernetes/manifests/etcd.yaml
  • 绝对不要碰 volumeMounts 里的 mountPath(那是容器内的路径,必须保持 /var/lib/etcd)。
  • 直接跳到文件最底部的 volumes: 块。
  • 只修改 hostPath(这是物理机上的真实路径),将其指向你刚才恢复的新目录:
  volumes:
  - hostPath:
      path: /var/lib/etcd-restore   # <--- 修改这里!
      type: DirectoryOrCreate
    name: etcd-data

2. 保存退出,等待重连 保存退出(:wq)后,kubelet 会自动发现配置变化并重启 ETCD。 如果想加速这个过程,可以使用“移出-移入”神技:

sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/ && sleep 10 && sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/

3. 最终验证 等待约 30-60 秒,API Server 重新上线后,查询你的测试数据:

kubectl get pods -n etcd-test

# 清理

1、清理 kubernetes 测试资源

kubectl delete namespace etcd-test

2、还原 ETCD 配置文件(最关键!)

为了下次做实验时不产生混乱,我们需要把 ETCD 的数据目录重新指回默认的 /var/lib/etcd

打开 ETCD 的静态 Pod 配置文件:

sudo vi /etc/kubernetes/manifests/etcd.yaml

翻到文件最底部的 volumes: 区域,把刚才修改的 hostPath.path 改回原样:

  volumes:
  - hostPath:
      path: /etc/kubernetes/pki/etcd
      type: DirectoryOrCreate
    name: etcd-certs
  - hostPath:
      path: /var/lib/etcd          # <--- 把带有 -restore 的后缀删掉,恢复成默认路径
      type: DirectoryOrCreate
    name: etcd-data

保存并退出 (:wq)。

3、强制重启 ETCD 并等待 API Server 恢复

老规矩,用移出移入大法让 Kubelet 立刻加载默认路径的原始数据:

sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/ && sleep 10 && sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/

等待大约 30 秒到 1 分钟,直到你能正常执行 kubectl get nodes 且不报错为止。这说明 API Server 已经重新连上了原始的 ETCD 数据库。

3、清理物理机上的残留文件和目录

现在原有的 ETCD 已经正常接管了,我们可以放心地把刚才实验产生的文件全部删掉:

## 删除备份的快照文件
sudo rm -f /opt/etcd-backup.db

## 删除我们练习恢复时创建的那个目录
sudo rm -rf /var/lib/etcd-restore