5.3.2.2. 恢复到一个以前的集群状态
您可以使用已保存的 etcd 备份来恢复以前的集群状态,或者恢复丢失了大多数 control plane 主机(也称为 master 主机)的集群。
恢复集群时,必须使用同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.6.2 集群必须使用从 4.6.2 进行的 etcd 备份。
先决条件
-
使用具有
cluster-admin
角色的用户访问集群。 - 用作恢复主机的健康 control plane 主机。
- SSH 对 control plane 主机的访问。
-
包含从同一备份中获取的 etcd 快照和静态 pod 资源的备份目录。该目录中的文件名必须采用以下格式:
snapshot_<datetimestamp>.db 和
。static_
kuberesources_<datetimestamp>.tar.gz
对于非恢复 control plane 节点,不需要建立 SSH 连接或停止静态 pod。您可以逐个删除并重新创建其他非恢复 control plane 机器。
步骤
- 选择一个要用作恢复主机的 control plane 主机。这是您要在其中运行恢复操作的主机。
建立到每个 control plane 节点(包括恢复主机)的 SSH 连接。
恢复过程启动后,Kubernetes API 服务器将无法访问,因此您无法访问 control plane 节点。因此,建议在一个单独的终端中建立到每个control plane 主机的 SSH 连接。
重要如果没有完成这个步骤,将无法访问 control plane 主机来完成恢复过程,您将无法从这个状态恢复集群。
将 etcd 备份目录复制复制到恢复 control plane 主机上。
此流程假设您将
backup
目录(其中包含 etcd 快照和静态 pod 资源)复制到恢复 control plane 主机的/home/core/
目录中。在任何其他 control plane 节点上停止静态 pod。
注意不需要手动停止恢复主机上的 pod。恢复脚本将停止恢复主机上的 pod。
- 访问不是恢复主机的 control plane 主机。
将现有 etcd pod 文件从 Kubelet 清单目录中移出:
$ sudo mv /etc/kubernetes/manifests/etcd-pod.yaml /tmp
验证 etcd pod 是否已停止。
$ sudo crictl ps | grep etcd | grep -v operator
命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。
将现有 Kubernetes API 服务器 pod 文件移出 kubelet 清单目录中:
$ sudo mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
验证 Kubernetes API 服务器 pod 是否已停止。
$ sudo crictl ps | grep kube-apiserver | grep -v operator
命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。
将 etcd 数据目录移到不同的位置:
$ sudo mv /var/lib/etcd/ /tmp
- 在其他不是恢复主机的 control plane 主机上重复此步骤。
- 访问恢复 control plane 主机。
如果启用了集群范围的代理,请确定已导出了
NO_PROXY
、HTTP_PROXY
和HTTPS_PROXY
环境变量。提示您可以通过查看
oc get proxy cluster -o yaml
的输出来检查代理是否已启用。如果httpProxy
、httpsProxy
和noProxy
字段设置了值,则会启用代理。在恢复 control plane 主机上运行恢复脚本,提供到 etcd 备份目录的路径:
$ 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
注意如果在最后的 etcd 备份后更新节点,恢复过程可能会导致节点进入
NotReady
状态。检查节点以确保它们处于
Ready
状态。运行以下命令:
$ oc get nodes -w
输出示例
NAME STATUS ROLES AGE VERSION host-172-25-75-28 Ready master 3d20h v1.23.3+e419edf host-172-25-75-38 Ready infra,worker 3d20h v1.23.3+e419edf host-172-25-75-40 Ready master 3d20h v1.23.3+e419edf host-172-25-75-65 Ready master 3d20h v1.23.3+e419edf host-172-25-75-74 Ready infra,worker 3d20h v1.23.3+e419edf host-172-25-75-79 Ready worker 3d20h v1.23.3+e419edf host-172-25-75-86 Ready worker 3d20h v1.23.3+e419edf host-172-25-75-98 Ready infra,worker 3d20h v1.23.3+e419edf
所有节点都可能需要过几分钟时间才能报告其状态。
如果有任何节点处于
NotReady
状态,请登录节点,并从每个节点上的/var/lib/kubelet/pki
目录中删除所有 PEM 文件。您可以 SSH 到节点,或使用 web 控制台中的终端窗口。$ ssh -i <ssh-key-path> core@<master-hostname>
pki
目录示例sh-4.4# pwd /var/lib/kubelet/pki sh-4.4# ls kubelet-client-2022-04-28-11-24-09.pem kubelet-server-2022-04-28-11-24-15.pem kubelet-client-current.pem kubelet-server-current.pem
在所有 control plane 主机上重启 kubelet 服务。
在恢复主机中运行以下命令:
$ sudo systemctl restart kubelet.service
- 在所有其他 control plane 主机上重复此步骤。
批准待处理的 CSR:
获取当前 CSR 列表。
$ oc get csr
输出示例
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-2s94x 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 1 csr-4bd6t 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending 2 csr-4hl85 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 3 csr-zhhhp 3m8s kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending 4 ...
查看一个 CSR 的详细信息以验证其是否有效:
$ oc describe csr <csr_name> 1
- 1
<csr_name>
是当前 CSR 列表中 CSR 的名称。
批准每个有效的
node-bootstrapper
CSR:$ oc adm certificate approve <csr_name>
对于用户置备的安装,请批准每个有效的 kubelet 服务 CSR:
$ oc adm certificate approve <csr_name>
确认单个成员 control plane 已被成功启动。
从恢复主机上,验证 etcd 容器是否正在运行。
$ sudo crictl ps | grep etcd | grep -v operator
输出示例
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
从恢复主机上,验证 etcd pod 是否正在运行。
$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | grep etcd
注意如果您试图在运行这个命令前运行
oc login
并接收以下错误,请等待一些时间以便身份验证控制器启动并再次尝试。Unable to connect to the server: EOF
输出示例
NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
如果状态是
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 7 1
- 1
- 在本例中,最新的修订版本号是
7
。
如果输出包含多个修订号,如
2 个节点为修订版本 6;1 个节点为修订版本 7
,这意味着更新仍在进行中。等待几分钟后重试。在重新部署 etcd 后,为 control plane 强制进行新的 rollout。由于 kubelet 使用内部负载平衡器连接到 API 服务器,因此 Kubernetes API 将在其他节点上重新安装自己。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令。为 Kubernetes API 服务器强制进行新的推出部署:
$ 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 7 1
- 1
- 在本例中,最新的修订版本号是
7
。
如果输出包含多个修订号,如
2 个节点为修订版本 6;1 个节点为修订版本 7
,这意味着更新仍在进行中。等待几分钟后重试。为 Kubernetes 控制器管理器强制进行新的推出部署:
$ 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 7 1
- 1
- 在本例中,最新的修订版本号是
7
。
如果输出包含多个修订号,如
2 个节点为修订版本 6;1 个节点为修订版本 7
,这意味着更新仍在进行中。等待几分钟后重试。为 Kubernetes 调度程序强制进行新的推出部署:
$ 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 7 1
- 1
- 在本例中,最新的修订版本号是
7
。
如果输出包含多个修订号,如
2 个节点为修订版本 6;1 个节点为修订版本 7
,这意味着更新仍在进行中。等待几分钟后重试。
验证所有 control plane 主机是否已启动并加入集群。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | 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
为确保所有工作负载在恢复过程后返回到正常操作,请重启存储 Kubernetes API 信息的每个 pod。这包括 OpenShift Container Platform 组件,如路由器、Operator 和第三方组件。
请注意,在完成这个过程后,可能需要几分钟才能恢复所有服务。例如,在重启 OAuth 服务器 pod 前,使用 oc login
进行身份验证可能无法立即正常工作。