使用etcd快照恢复集群数据
备份etcd及相关证书
1 | #!/bin/bash |
恢复
注意:恢复的顺序是 global 集群 、 业务集群。如果只有业务集群升级失败,不支持只回滚业务集群,必须都要回滚,因为 global 集群上,存有业务集群的 hr 资源。
获取 etcd 地址,并停掉所有(业务集群和 global 集群) master 节点上的 kubelet 服务。
执行命令的环境: 业务集群和 global 集群的所有 master 节点上
执行的命令:
1
2
3
4
5
6
7ETCD_SERVER=($(kubectl get pod -n kube-system $(kubectl get pod -n kube-system | \
grep etcd | awk 'NR==1 {print $1}') -o yaml | \
awk '/--initial-cluster=/{print}' | \
sed -e 's/,/ /g' -e's/^.*cluster=//' | \
sed -e 's#[0-9\.]*=https://##g' -e 's/:2380//g'))
systemctl stop kubelet
删掉 kube-apiserver 容器,目的是恢复过程和恢复之后,global 不要通过调用 kubeapi 写数据到业务集群的 etcd 内。
执行命令的环境: 要恢复 Kubernetes 集群的所有 master 节点上
执行的命令:
docker rm -f $(docker ps -a | awk '/_kube-api/{print $NF}')
命令的结果: 所有 kube-api 的容器都被删除。
判断 etcdctl 命令是否存在第一台 master 节点上,一般执行
backup_recovery.sh
这个备份 etcd 的脚本,会自动将 etcdctl 拷贝到/usr/bin/etcdctl
,如果不存在,需要自行手动拷贝出来。执行命令的环境: 要恢复 Kubernetes 集群的第一台 master 节点上
执行的命令:
whereis etcdctl
命令的结果: 应该打印处 etcdctl 的路径,如果没有就表明是错的。
通过备份的快照恢复 etcd。
执行命令的环境: 要恢复 Kubernetes 集群的第一台 master 节点上
执行的命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16mkdir /tmp/dd
ETCD_SERVER=($(kubectl get pod -n kube-system $(kubectl get pod -n kube-system | grep etcd | awk 'NR==1 {print $1}') -o yaml | awk '/--initial-cluster=/{print}' | sed -e 's/,/ /g' -e's/^.*cluster=//' | sed -e 's#[0-9\.]*=https://##g' -e 's/:2380//g')) ## 这个地址在回滚的第一步已经获取了,执行回滚之前,echo 这个变量检查地址是否获取成功
snapshot_db=<备份时,导出的 etcd 快照文件名,必须是绝对路径>
for i in ${ETCD_SERVER[@]}
do
export ETCDCTL_API=3
etcdctl snapshot restore ${snapshot_db} \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--data-dir=/tmp/dd/etcd \
--name ${i} \
--initial-cluster ${ETCD_SERVER[0]}=https://${ETCD_SERVER[0]}:2380,${ETCD_SERVER[1]}=https://${ETCD_SERVER[1]}:2380,${ETCD_SERVER[2]}=https://${ETCD_SERVER[2]}:2380 \
--initial-advertise-peer-urls https://$i:2380 && \
mv /tmp/dd/etcd etcd_$i
done命令的结果: 会生成
etcd_<ip 地址>
这样的三个目录,将这三个目录拷贝到对应ip的服务器的/root
内。
删掉 etcd 容器。
执行命令的环境: 要恢复 Kubernetes 集群的所有 master 节点上
执行的命令:
docker rm -f $(docker ps -a | awk '/_etcd/{print $NF}')
命令的结果: 所有 etcd 的容器都被删除。
迁移恢复的数据。
执行命令的环境: 要恢复 Kubernetes 集群的所有 master 节点上
执行的命令:
1
2
3docker ps -a | awk '/_etcd/{print $NF}' ##确保没有 etcd 容器
mv /var/lib/etcd/member /cpaas/backup
mv /root/var/lib/etcd/member /var/lib/etcd命令的结果: 会把 etcd 的数据挪到备份目录下,然后将上一步生成的目录拷贝到
/var/lib/etcd
里。
启动 etcd 和 kube-api。
执行命令的环境: 要恢复 Kubernetes 集群的所有 master 节点上
执行的命令:
systemctl start kubelet
命令的结果: kubelet 服务启动后,会自动创建 etcd 的 pod,这个时候执行
docker ps -a | grep -E 'etcd|kube-api'
会找到 etcd 和 kube-api 容器。
问题解决
- 回滚之后,如果出现在kubelet和页面查看所有资源都存在,但是在业务节点没有资源的情况,重启k8s 集群内所有节点的 kubelet 和 docker 服务,也可采用重启集群内所有服务器的方式来解决