bitnami etcd 故障成员恢复
本文介绍了在使用 bitnami/etcd 部署的集群中,如何恢复故障成员的方法。首先在处理前,往 etcd 集群中添加一些数据,以验证恢复方案不会导致集群数据丢失。然后,通过删除 etcd-1 pv 的数据目录来模拟 etcd-1 成员故障,并查看 etcd-1 pod 日志、etcd 集群成员状态以及 endpoint 健康状态来分析故障原因。接着,本文提供了一套恢复方案,包括将故障成员 etcd-1 从集群中移除、将 etcd statefulsets 缩放为 0、删除故障成员 etcd-1 绑定的 pv 的数据目录、修改 statefulsets 中 ETCD_INITIAL_CLUSTER_STATE 配置的值为 "existing"、将 etcd statefulsets 恢复为原来的副本数以及检查 etcd 集群 endpoint 健康状态等步骤。最后,验证数据是否完整。
bitnami etcd 故障成员恢复
环境准备
准备一个使用 bitnami/etcd 部署的集群。
查看 statefulsets:
1 | [root@cnode1 ~]# kubectl -n etcd get statefulsets.apps |
查看 pod:
1 | [root@cnode1 ~]# kubectl -n etcd get pod |
查看 ETCD_INITIAL_CLUSTER_STATE
配置:
1 | [root@cnode1 ~]# kubectl -n etcd get statefulsets.apps etcd -o yaml | grep ETCD_INITIAL_CLUSTER_STATE -A 1 |
查看 etcd 集群成员状态:
1 | I have no name!@etcd-0:/opt/bitnami/etcd$ bin/etcdctl member list |
该集群有 3 个成员:
- etcd-0
- etcd-1
- etcd-2
添加测试数据
在处理前,先往 etcd 集群中添加一些数据,以验证恢复方案不会导致集群数据丢失。
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |
破坏 etcd-1 成员
获取 etcd-1 的 pv:(所有 pv 均使用 local-storage)
1 | [root@cnode1 ~]# kubectl -n etcd get pvc |
获取 etcd-1 pv 所在的节点:
1 | [root@cnode1 ~]# kubectl get pv pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20 -o yaml | grep nodeAffinity -A 7 |
获取 etcd-1 pv 的数据目录:
1 | [root@cnode1 ~]# kubectl get pv pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20 -o yaml | grep hostPath -A 2 |
进入节点 cnode3 后台:
1 | ssh root@cnode3 |
删除 etcd-1 pv 的数据目录:
1 | [root@cnode3 ~]# rm -rf /data/local-path-provisioner/pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20_etcd_data-etcd-1/data/ |
删除 etcd-1 pod:
1 | [root@cnode1 ~]# kubectl -n etcd delete pod etcd-1 |
等待 etcd-1 pod 重新被拉起:
1 | [root@cnode1 ~]# kubectl -n etcd get pod |
此状态下,重启 etcd 集群也无法恢复:
1 | [root@cnode1 ~]# kubectl -n etcd rollout restart statefulset etcd |
分析 etcd-1 故障
查看 etcd-1 pod 日志:
1 | [root@cnode1 ~]# kubectl -n etcd logs -f etcd-1 |
查看 etcd 集群成员状态:(这个命令无法得知 endpoint 的健康状态)
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |
查看 etcd 集群 endpoint 健康状态:
1 | I have no name!@etcd-0:/opt/bitnami/etcd$ bin/etcdctl endpoint health --endpoints=etcd-0.etcd-headless.etcd:2380,etcd-1.etcd-headless.etcd:2380,etcd-2.etcd-headless.etcd:2380 -w table |
恢复方案
(1)将故障成员 etcd-1 从集群中移除
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |
(2)将 etcd statefulsets 缩放为 0
1 | [root@cnode1 ~]# kubectl -n etcd scale statefulset etcd --replicas=0 |
(3)删除故障成员 etcd-1 绑定的 pv 的数据目录
获取 etcd-1 的 pv
1
2
3
4
5[root@cnode1 ~]# kubectl -n etcd get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-etcd-0 Bound pvc-2a2f2a25-69b3-41ab-a21d-a5aa3d05277d 10Gi RWO local-storage 30d
data-etcd-1 Bound pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20 10Gi RWO local-storage 4h10m
data-etcd-2 Bound pvc-6da8bcd7-cd2a-43fc-9849-7e1c2870f193 10Gi RWO local-storage 30d获取 etcd-1 pv 所在的节点
1
2
3
4
5
6
7
8
9[root@cnode1 ~]# kubectl get pv pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20 -o yaml | grep nodeAffinity -A 7
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- cnode3获取 etcd-1 pv 的数据目录
1
2
3
4[root@cnode1 ~]# kubectl get pv pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20 -o yaml | grep hostPath -A 2
hostPath:
path: /data/local-path-provisioner/pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20_etcd_data-etcd-1
type: DirectoryOrCreate进入节点 cnode3 后台
1
ssh root@cnode3
清除 etcd-1 pv 的数据目录
1
2
3[root@cnode1 ~]# rm -rf /data/local-path-provisioner/pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20_etcd_data-etcd-1/data/
[root@cnode1 ~]# ls /data/local-path-provisioner/pvc-4832f8c4-0827-4992-9e39-185f9c0f8e20_etcd_data-etcd-1/
[root@cnode1 ~]#
(4)修改 statefulsets 中 ETCD_INITIAL_CLUSTER_STATE 配置的值为 "existing"
1 | [root@cnode1 ~]# kubectl -n etcd edit statefulsets.apps etcd |
修改内容如下:
1 | - name: ETCD_INITIAL_CLUSTER_STATE |
(5)将 etcd statefulsets 恢复为原来的副本数
1 | [root@cnode1 ~]# kubectl -n etcd scale statefulset etcd --replicas=3 |
(6)查看 etcd-1 的日志
1 | [root@cnode1 ~]# kubectl -n etcd logs -f etcd-1 |
(7)查看 etcd statefulsets 状态
1 | [root@cnode1 ~]# kubectl -n etcd get statefulsets.apps etcd |
(8)检查 etcd 集群 endpoint 健康状态
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |
(9)查看 etcd 集群成员状态
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |
(10)修改 statefulsets 中 ETCD_INITIAL_CLUSTER_STATE 配置的值恢复为 "new"(可选)
1 | [root@cnode1 ~]# kubectl -n etcd edit statefulsets.apps etcd |
修改内容如下:
1 | - name: ETCD_INITIAL_CLUSTER_STATE |
等待 statefulsets 重启完成:
1 | [root@cnode1 ~]# kubectl -n etcd get statefulsets.apps etcd |
(11)验证数据是否完整
1 | [root@cnode1 ~]# kubectl -n etcd exec -it etcd-0 -- bash |