3.3. 恢复到一个以前的集群状态
为了将集群还原到以前的状态,您必须已通过创建快照备份了 etcd 数据 。您将需要使用此快照来还原集群状态。
3.3.1. 恢复到一个以前的集群状态
您可以使用已保存的 etcd 备份恢复到先前的集群状态。您可以使用 etcd 备份来恢复单个 master 主机。然后,etcd cluster Operator 会处理剩余的 master 主机的扩展。
恢复集群时,必须使用同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.4.2 集群必须使用从 4.4.2 中获得的 etcd 备份。
先决条件
-
使用具有
cluster-admin
角色的用户访问集群。 - 具有对 master 主机的 SSH 访问权限。
-
包含从同一备份中获取的 etcd 快照和静态 pod 资源的备份目录。该目录中的文件名必须采用以下格式:
snapshot_<datetimestamp>.db 和
。static_
kuberesources_<datetimestamp>.tar.gz
流程
- 选择一个要用作恢复主机的 master 主机。这是您要在其中运行恢复操作的主机。
建立到每个 master 节点(包括恢复主机)的 SSH 连接。
一旦恢复过程开始,Kubernetes API 服务器将无法访问,因此您无法访问 master 节点。因此,建议在一个单独的终端中建立到每个 master 主机的 SSH 连接。
重要如果没有完成这个步骤,将无法访问 master 主机来完成恢复过程,您将无法从这个状态恢复集群。
将 etcd 备份目录复制复制到恢复 master 主机上。
此流程假设您将
backup
目录(其中包含 etcd 快照和静态 pod 资源)复制到恢复 master 主机的/home/core/
目录中。在所有其他 master 节点上停止静态 pod。
注意不需要手动停止恢复主机上的 pod。恢复脚本将停止恢复主机上的 pod。
- 访问不是恢复主机的一个 master 主机。
将现有 etcd pod 文件从 Kubelet 清单目录中移出:
[core@ip-10-0-154-194 ~]$ sudo mv /etc/kubernetes/manifests/etcd-pod.yaml /tmp
验证 etcd pod 是否已停止。
[core@ip-10-0-154-194 ~]$ sudo crictl ps | grep etcd | grep -v operator
命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。
将现有 Kubernetes API 服务器 pod 文件移出 kubelet 清单目录中:
[core@ip-10-0-154-194 ~]$ sudo mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
验证 Kubernetes API 服务器 pod 是否已停止。
[core@ip-10-0-154-194 ~]$ sudo crictl ps | grep kube-apiserver | grep -v operator
命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。
将 etcd 数据目录移到不同的位置:
[core@ip-10-0-154-194 ~]$ sudo mv /var/lib/etcd/ /tmp
- 在其他不是恢复主机的 master 主机上重复这个步骤。
- 访问恢复 master 主机。
如果启用了集群范围的代理,请确定已导出了
NO_PROXY
、HTTP_PROXY
和HTTPS_PROXY
环境变量。提示您可以通过查看
oc get proxy cluster -o yaml
的输出来检查代理是否已启用。如果httpProxy
、httpsProxy
和noProxy
字段设置了值,则会启用代理。在恢复 master 主机上运行恢复脚本,提供到 etcd 备份目录的路径:
[core@ip-10-0-143-125 ~]$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/backup ...stopping kube-scheduler-pod.yaml ...stopping kube-controller-manager-pod.yaml ...stopping etcd-pod.yaml ...stopping kube-apiserver-pod.yaml Waiting for container etcd to stop .complete Waiting for container etcdctl to stop .............................complete Waiting for container etcd-metrics to stop complete Waiting for container kube-controller-manager to stop complete Waiting for container kube-apiserver to stop ..........................................................................................complete Waiting for container kube-scheduler to stop complete Moving etcd data-dir /var/lib/etcd/member to /var/lib/etcd-backup starting restore-etcd static pod starting kube-apiserver-pod.yaml static-pod-resources/kube-apiserver-pod-7/kube-apiserver-pod.yaml starting kube-controller-manager-pod.yaml static-pod-resources/kube-controller-manager-pod-7/kube-controller-manager-pod.yaml starting kube-scheduler-pod.yaml static-pod-resources/kube-scheduler-pod-8/kube-scheduler-pod.yaml
在所有 master 主机上重启 kubelet 服务。
在恢复主机中运行以下命令:
[core@ip-10-0-143-125 ~]$ sudo systemctl restart kubelet.service
- 在所有其他 master 主机上重复此步骤。
确认单个成员 control plane 已被成功启动。
从恢复主机上,验证 etcd 容器是否正在运行。
[core@ip-10-0-143-125 ~]$ sudo crictl ps | grep etcd | grep -v operator 3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
从恢复主机上,验证 etcd pod 是否正在运行。
[core@ip-10-0-143-125 ~]$ oc get pods -n openshift-etcd | grep etcd NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
注意如果您试图在运行这个命令前运行
oc login
并接收以下错误,请等待一些时间以便身份验证控制器启动并再次尝试。Unable to connect to the server: EOF
如果状态是
Pending
,或者输出中列出了多个正在运行的 etcd pod,请等待几分钟,然后再次检查。
强制 etcd 重新部署。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 1
- 1
forceRedeploymentReason
值必须是唯一的,这就是为什么附加时间戳的原因。
当 etcd cluster Operator 执行重新部署时,现有节点开始使用与初始 bootstrap 扩展类似的新 pod。
验证所有节点是否已更新至最新的修订版本。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
查看 etcd 的
NodeInstallerProgressing
状态条件,以验证所有节点是否处于最新的修订。在更新成功后,输出会显示AllNodesAtLatestRevision
:AllNodesAtLatestRevision 3 nodes are at revision 3
如果输出显示
2 个节点处于修订版本 3,1 个节点处于修订版本 4
,这意味着更新仍在进行中。等待几分钟后重试。在重新部署 etcd 后,为 control plane 强制进行新的 rollout。由于 kubelet 使用内部负载平衡器连接到 API 服务器,因此 Kubernetes API 将在其他节点上重新安装自己。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令。更新
kubeapiserver
:$ oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
验证所有节点是否已更新至最新的修订版本。
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
查看
NodeInstallerProgressing
状态条件,以验证所有节点是否处于最新版本。在更新成功后,输出会显示AllNodesAtLatestRevision
:AllNodesAtLatestRevision 3 nodes are at revision 3
更新
kubecontrollermanager
:$ oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
验证所有节点是否已更新至最新的修订版本。
$ oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
查看
NodeInstallerProgressing
状态条件,以验证所有节点是否处于最新版本。在更新成功后,输出会显示AllNodesAtLatestRevision
:AllNodesAtLatestRevision 3 nodes are at revision 3
更新
kubescheduler
:$ oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
验证所有节点是否已更新至最新的修订版本。
$ oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
查看
NodeInstallerProgressing
状态条件,以验证所有节点是否处于最新版本。在更新成功后,输出会显示AllNodesAtLatestRevision
:AllNodesAtLatestRevision 3 nodes are at revision 3
验证所有 master 主机已启动并加入集群。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd | grep etcd etcd-ip-10-0-143-125.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-154-194.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-173-171.ec2.internal 2/2 Running 0 9h
请注意,在完成这个过程后,可能需要几分钟才能恢复所有服务。例如,在重启 OAuth 服务器 pod 前,使用 oc login
进行身份验证可能无法立即正常工作。