本文档介绍了如何为使用 Google Distributed Cloud for VMware(纯软件)创建的管理员集群备份和恢复 etcd 存储区。此文档还提供了一个脚本,您可以使用该脚本自动备份集群的 etcd 存储区。您还可以使用 gkectl
命令行工具备份和恢复管理员集群。
您可以创建备份文件,以便从可能会破坏集群的 etcd 数据的意外灾难中恢复数据。请将备份文件存储在集群外部且不依赖于集群操作的位置。
限制
本文档中介绍的备份和恢复过程存在以下限制:
此过程不会备份应用特定的数据。
此过程不会备份 PersistentVolume。
创建备份后安排的工作负载不会随该备份一起恢复。
升级失败后,您无法恢复集群。
此过程不适用于恢复已删除的集群。
如需详细了解限制,请参阅基础设施不兼容性。
备份管理员集群
管理员集群备份包含以下内容:
- 管理员集群的 etcd 快照。
- 管理员控制层面的 Secret,这是向管理员集群和用户集群进行身份验证所必需的。
在创建管理员集群备份前,请完成以下步骤:
找到管理员集群的外部 IP 地址(用于通过 SSH 连接到管理员集群控制平面):
kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get nodes -n kube-system -o wide | grep master
其中,[ADMIN_CLUSTER_KUBECONFIG] 是管理员集群的 kubeconfig 文件。
从管理员集群的私钥创建一个名为
vsphere_tmp
的 SSH 密钥。您可以从管理员集群 Secret 中找到私钥:
kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get secrets sshkeys -n kube-system -o yaml
在命令输出中,您可以在
vsphere_tmp
字段中找到私钥。将私钥复制到
vsphere_tmp
:echo "[PRIVATE_KEY]" | base64 -d > vsphere_tmp; chmod 600 vsphere_tmp
检查您是否可以使用此私钥通过 shell 进入管理员控制平面:
ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
退出该容器:
exit
备份管理员集群的 etcd 存储区
要备份管理员集群的 etcd 存储区,请执行以下操作:
获取 etcd pod 的名称:
kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get pods \ -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}'
通过 shell 进入 pod 的 kube-etcd 容器:
kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] exec -it \ -n kube-system [ADMIN_ETCD_POD] -- bin/sh
其中,[ADMIN_ETCD_POD] 是 etcd pod 的名称。
在 Shell 中,使用
etcdctl
在本地目录中创建一个名为snapshot.db
的备份:ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \ --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/snapshot.db
退出该容器:
exit
使用
kubectl cp
从 kube-etcd 容器中复制备份:kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] cp \ kube-system/[ADMIN_ETCD_POD]:tmp/snapshot.db [RELATIVE_DIRECTORY]
其中,[RELATIVE_DIRECTORY] 是存储备份的路径。
备份管理员集群的 Secret
要备份管理员控制层面的 Secret,请执行以下操作:
使用 SSH 连接到管理员控制平面节点:
ssh -i vsphere_tmp ubuntu@EXTERNAL_IP
将
EXTERNAL_IP
替换为您之前记下的管理员控制层面的外部 IP 地址。创建本地备份目录是可选步骤,但我们强烈建议您执行。
您需要更改备份 Secret 的权限,以将其复制到节点之外。
mkdir backup
在本地将 Secret 复制到本地备份目录:
sudo cp -r /etc/kubernetes/pki/* backup/
更改备份 Secret 的权限:
sudo chmod -R a+rX backup/
退出管理员控制平面节点:
exit
运行
scp
从管理员控制平面节点复制备份文件夹:sudo scp -r -i vsphere_tmp ubuntu@EXTERNAL_IP:backup/ RELATIVE_DIRECTORY
将
RELATIVE_DIRECTORY
替换为您要用于存储备份的路径。
恢复管理员集群
以下过程会重新创建备份管理员集群以及创建 etcd 快照时其管理的所有用户控制层面。
运行
scp
以将snapshot.db
复制到管理员控制平面:sudo scp -i vsphere_tmp snapshot.db ubuntu@[EXTERNAL_IP]:
其中,[EXTERNAL_IP] 是您之前收集的管理员控制层面的外部 IP 地址。
通过 shell 进入管理员控制平面:
sudo ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
将
snapshot.db/
复制到/mnt
:sudo cp snapshot.db /mnt/
设置临时目录,例如
backup
:mkdir backup
退出管理员控制平面:
exit
将证书复制到
backup/
:sudo scp -r -i vsphere_tmp [BACKUP_CERT_FILE] ubuntu@[EXTERNAL_IP]:backup/
通过 shell 进入管理员控制平面节点:
ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
其中,[EXTERNAL_IP] 是您之前收集的管理员控制层面的外部 IP 地址。
停止
kube-etcd
和kube-apiserver
。sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/etcd.yaml
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/kube-apiserver.yaml
将备份 Secret 复制到
/etc/kubernetes/pki/
:sudo cp -r backup/* /etc/kubernetes/pki/
使用 Docker 运行
etcdctl restore
:sudo docker run --rm \ -v '/mnt:/backup' \ -v '/var/lib/etcd:/var/lib/etcd' --env ETCDCTL_API=3 'gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION' /bin/sh -c "etcdctl snapshot restore '/backup/snapshot.db'; rm -r /var/lib/etcd/*; mv /default.etcd/member/ /var/lib/etcd/"
重启
kube-etcd
和kube-apiserver
。sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml
验证
kube-etcd
和kube-apiserver
已启动。sudo crictl ps -a
将
/etc/kubernetes/admin.conf
复制到.kube
文件夹,以便从管理员工作站访问:mkdir -p [HOME]/.kube
sudo cp -i /etc/kubernetes/admin.conf [HOME]/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
退出管理员控制平面:
exit
从管理员节点复制新生成的 kubeconfig 文件:
sudo scp -i vsphere_tmp ubuntu@[EXTERNAL_IP]:[HOME]/.kube/config kubeconfig
sudo chown $(id -u):$(id -g) kubeconfig
其中:
- [EXTERNAL_IP] 是管理员控制层面的外部 IP 地址。
- [HOME] 是管理员节点上的主目录。
现在,您可以使用这一新的 kubeconfig 文件访问恢复的集群。
排查管理员集群恢复问题
如果您在恢复管理员集群时遇到问题,则必须与 Google 支持团队联系以解决管理员集群相关问题。
在此期间,您可以查看以下各项以进一步进行问题排查。
找到 etcd 容器 ID
sudo crictl ps -a | grep [ADMIN_ETCD_POD]
其中,[ADMIN_ETCD_POD] 是 etcd pod 的名称。
检查来自 etc 容器的日志
sudo crictl logs [ETCD_CONTAINER_ID]
其中,[ETCD_CONTAINER_ID] 是 etcd 容器的 ID。
查找如下权限遭拒的日志消息
etcdserver: create snapshot directory error:mkdir /var/lib/etcd/member/snap: permission denied
如果找到权限遭拒的消息,请更新 /opt/data/var/lib/etcd/ 的所有权
sudo chown -R 2001:2001 /opt/data/var/lib/etcd/
验证
kube-etcd
和kube-apiserver
已启动。sudo crictl ps
自动备份集群
您可以使用此处提供的示例脚本自动备份集群。请注意,以下脚本不受支持,仅供参考,您应在此基础上编写更好、更可靠且更完善的脚本。在运行脚本之前,请在脚本开头填写五个变量的值:
- 将
BACKUP_DIR
设置为您要存储管理员集群和用户集群备份的路径。此路径不应存在。 - 将
ADMIN_CLUSTER_KUBECONFIG
设置为管理员集群的 kubeconfig 文件的路径。 - 将
USER_CLUSTER_NAMESPACE
设置为您的用户集群的名称。用户集群的名称是管理员集群中的命名空间。 - 将
EXTERNAL_IP
设置为您为管理员控制平面服务预留的 VIP。 - 将
SSH_PRIVATE_KEY
设置为 SSH 密钥的路径。 - 如果您使用的是专用网络,请将
JUMP_IP
设置为该网络的跳转服务器的 IP 地址。
#!/usr/bin/env bash
# Automates manual steps for taking backups of user and admin clusters.
# Fill in the variables below before running the script.
BACKUP_DIR="" # path to store user and admin cluster backups
ADMIN_CLUSTER_KUBECONFIG="" # path to admin cluster kubeconfig
USER_CLUSTER_NAMESPACE="" # user cluster namespace
EXTERNAL_IP="" # admin control plane node external ip - follow steps in documentation
SSH_PRIVATE_KEY="" # path to vsphere_tmp ssh private key - follow steps in documentation
JUMP_IP="" # network jump server IP - leave empty string if not using private network.
mkdir -p $BACKUP_DIR
mkdir $BACKUP_DIR/pki
# USER CLUSTER BACKUP
# Snapshot user cluster etcd
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n ${USER_CLUSTER_NAMESPACE} kube-etcd-0 -c kube-etcd -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcdCA.crt --cert=/etcd.local.config/certificates/etcd.crt --key=/etcd.local.config/certificates/etcd.key snapshot save /tmp/${USER_CLUSTER_NAMESPACE}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp ${USER_CLUSTER_NAMESPACE}/kube-etcd-0:tmp/${USER_CLUSTER_NAMESPACE}_snapshot.db $BACKUP_DIR/user-cluster_${USER_CLUSTER_NAMESPACE}_snapshot.db
# ADMIN CLUSTER BACKUP
# Set up ssh options
SSH_OPTS=(-oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY})
if [ "${JUMP_IP}" != "" ]; then
SSH_OPTS+=(-oProxyCommand="ssh -oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY} -W %h:%p ubuntu@${JUMP_IP}")
fi
# Copy admin certs
ssh "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP} 'sudo chmod -R a+rX /etc/kubernetes/pki/*'
scp -r "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP}:/etc/kubernetes/pki/* ${BACKUP_DIR}/pki/
# Snapshot admin cluster etcd
admin_etcd=$(kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}')
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n kube-system ${admin_etcd} -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/admin_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:tmp/admin_snapshot.db $BACKUP_DIR/admin-cluster_snapshot.db
后续步骤
- 备份和恢复用户集群
- 了解如何诊断集群问题
- 了解 augur,这是一个用于从 etcd 备份中恢复单个对象的开源工具。