6.3. 灾难恢复
6.3.1. 关于灾难恢复 复制链接链接已复制到粘贴板!
灾难恢复文档为管理员提供了如何从 OpenShift Container Platform 集群可能出现的几个灾难情形中恢复的信息。作为管理员,您可能需要遵循以下一个或多个步骤将集群恢复为工作状态。
灾难恢复要求您至少有一个健康的 control plane 主机。
- 仲裁恢复
在已丢失了大多数 control plane 主机并导致 etcd quorum 丢失,且集群离线的情况下,可以使用这个解决方案。这个解决方案不需要 etcd 备份。
注意如果大多数 control plane 节点仍可用,且有 etcd 仲裁,则替换单个不健康的 etcd 成员。
- 恢复到一个以前的集群状态
如果您希望将集群恢复到一个以前的状态时(例如,管理员错误地删除了一些关键信息),则可以使用这个解决方案。如果您执行了 etcd 备份,您可以将集群恢复到以前的状态。
如果适用,可能还需要从过期的 control plane 证书中恢复。
警告在一个正在运行的集群中恢复到以前的集群状态是破坏性的,而不稳定的操作。这仅应作为最后的手段使用。
在执行恢复前,请参阅关于恢复集群状态以了解有关对集群的影响的更多信息。
- 从 control plane 证书已过期的情况下恢复
- 如果 control plane 证书已经过期,则可以使用这个解决方案。例如:在第一次证书轮转前(在安装后 24 小时内)关闭了集群,您的证书将不会被轮转,且会过期。可以按照以下步骤从已过期的 control plane 证书中恢复。
6.3.1.1. 测试恢复过程 复制链接链接已复制到粘贴板!
测试恢复过程非常重要,以确保您的自动化和工作负载安全处理新的集群状态。由于 etcd 仲裁的复杂性,以及 etcd Operator 会尝试自动修复,通常很难正确地使您的集群进入一个可以恢复的状态。
您必须有到集群的 SSH 访问权限。如果无法进行 SSH 访问,您的集群可能完全丢失。
先决条件
- 有到 control plane 主机的 SSH 访问权限。
-
已安装 OpenShift CLI(
oc
)。
流程
使用 SSH 连接到每个非恢复节点,并运行以下命令来禁用 etcd 和
kubelet
服务:运行以下命令来禁用 etcd:
sudo /usr/local/bin/disable-etcd.sh
$ sudo /usr/local/bin/disable-etcd.sh
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 运行以下命令来删除 etcd 的变量数据:
sudo rm -rf /var/lib/etcd
$ sudo rm -rf /var/lib/etcd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 运行以下命令来禁用
kubelet
服务:sudo systemctl disable kubelet.service
$ sudo systemctl disable kubelet.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
- 退出每个 SSH 会话。
运行以下命令,以确保您的非恢复节点处于
NOT READY
状态:oc get nodes
$ oc get nodes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 按照"恢复到以前的集群状态"中的步骤来恢复集群。
恢复集群和 API 响应后,使用 SSH 连接到每个非恢复节点并启用
kubelet
服务:sudo systemctl enable kubelet.service
$ sudo systemctl enable kubelet.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 退出每个 SSH 会话。
运行以下命令,观察您的节点返回
READY
状态:oc get nodes
$ oc get nodes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 运行以下命令验证 etcd 是否可用:
oc get pods -n openshift-etcd
$ oc get pods -n openshift-etcd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
6.3.2. 仲裁恢复 复制链接链接已复制到粘贴板!
您可以使用 quorum-restore.sh
脚本来恢复因为仲裁丢失而离线的集群中的 etcd 仲裁。当 quorum 丢失时,OpenShift Container Platform API 将变为只读。恢复仲裁后,OpenShift Container Platform API 会返回读/写模式。
6.3.2.1. 为高可用性集群恢复 etcd 仲裁 复制链接链接已复制到粘贴板!
您可以使用 quorum-restore.sh
脚本来恢复因为仲裁丢失而离线的集群中的 etcd 仲裁。当 quorum 丢失时,OpenShift Container Platform API 将变为只读。恢复仲裁后,OpenShift Container Platform API 会返回读/写模式。
quorum-restore.sh
脚本会立即根据其本地数据目录返回一个新的单成员 etcd 集群,并通过停止之前的集群标识符将所有其他成员标记为无效。无需预先备份就可以从 control plane 中恢复。
对于高可用性(HA)集群,一个三节点集群需要在两个主机上关闭 etcd,以避免集群分割。在四节点和五个节点 HA 集群中,您必须关闭三个主机。仲裁只需要具有多数节点的情况。三节点 HA 集群中,仲裁最少需要两个节点。在四节点和五个节点 HA 集群中,仲裁需要的最小节点数为三。如果您从恢复主机上的备份启动新集群,其他 etcd 成员可能仍然可以组成仲裁并继续服务。
如果运行恢复的主机没有复制其中的所有数据,您可能会遇到数据丢失的情况。
仲裁恢复不应用于减少恢复过程外的节点数量。减少节点数会导致出现不受支持的集群配置。
先决条件
- 有到用来恢复仲裁的节点的 SSH 访问权限。
流程
选择一个要用作恢复主机的 control plane 主机。您可以在此主机上运行恢复操作。
运行以下命令列出正在运行的 etcd pod:
oc get pods -n openshift-etcd -l app=etcd --field-selector="status.phase==Running"
$ oc get pods -n openshift-etcd -l app=etcd --field-selector="status.phase==Running"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 选择 pod 并运行以下命令来获取其 IP 地址:
oc exec -n openshift-etcd <etcd-pod> -c etcdctl -- etcdctl endpoint status -w table
$ oc exec -n openshift-etcd <etcd-pod> -c etcdctl -- etcdctl endpoint status -w table
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 记录在不是 learner,且具有最高 Raft 索引的成员的 IP 地址。
运行以下命令并记录与所选 etcd 成员的 IP 地址对应的节点名称:
oc get nodes -o jsonpath='{range .items[*]}[{.metadata.name},{.status.addresses[?(@.type=="InternalIP")].address}]{end}'
$ oc get nodes -o jsonpath='{range .items[*]}[{.metadata.name},{.status.addresses[?(@.type=="InternalIP")].address}]{end}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
使用 SSH 连接到所选恢复节点,并运行以下命令来恢复 etcd 仲裁:
sudo -E /usr/local/bin/quorum-restore.sh
$ sudo -E /usr/local/bin/quorum-restore.sh
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 几分钟后,关闭的节点会自动与运行恢复脚本的节点同步。任何剩余的在线节点都会自动重新加入由
quorum-restore.sh
脚本创建的新 etcd 集群。这个过程需要几分钟时间。- 退出 SSH 会话。
如果有任何节点离线,则返回三节点配置。对离线的每个节点重复此步骤,以删除并重新创建它们。重新创建机器后,会强制一个新修订版本,etcd 会自动扩展。
如果使用用户置备的裸机安装,您可以使用最初创建它时使用的相同方法重新创建 control plane 机器。如需更多信息,请参阅"在裸机上安装用户置备的集群"。
警告不要为恢复主机删除并重新创建机器。
如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行:
警告不要为恢复主机删除并重新创建机器。
对于安装程序置备的基础架构上的裸机安装,不会重新创建 control plane 机器。如需更多信息,请参阅"替换裸机控制平面节点"。
为其中一个离线节点获取机器。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:oc get machines -n openshift-machine-api -o wide
$ oc get machines -n openshift-machine-api -o wide
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 这是离线节点的 control plane 机器
ip-10-0-131-183.ec2.internal
。
运行以下命令来删除离线节点的机器:
oc delete machine -n openshift-machine-api clustername-8qw5l-master-0
$ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 为离线节点指定 control plane 机器的名称。
删除离线节点的机器后会自动置备新机器。
运行以下命令验证新机器是否已创建:
oc get machines -n openshift-machine-api -o wide
$ oc get machines -n openshift-machine-api -o wide
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 新机器
clustername-8qw5l-master-3
会被创建,并在阶段从Provisioning
变为Running
后就绪。
创建新机器可能需要几分钟时间。当机器或节点返回健康状态时,etcd 集群 Operator 将自动同步。
- 对离线的每个节点重复这些步骤。
运行以下命令等待 control plane 恢复:
oc adm wait-for-stable-cluster
$ oc adm wait-for-stable-cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意control plane 最多可能需要 15 分钟才能恢复。
故障排除
如果推出 etcd 静态 pod 的过程没有进展,您可以通过运行以下命令来强制从 etcd 集群 Operator 重新部署:
oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
6.3.3. 恢复到一个以前的集群状态 复制链接链接已复制到粘贴板!
要将集群恢复到以前的状态,您必须已通过创建快照来备份 etcd
数据。您将需要使用此快照来还原集群状态。如需更多信息,请参阅"恢复 etcd 数据"。
6.3.3.1. 关于恢复到以前的集群状态 复制链接链接已复制到粘贴板!
要将集群恢复到以前的状态,您必须已通过创建快照来备份 etcd
数据。您将需要使用此快照来还原集群状态。如需更多信息,请参阅"恢复 etcd 数据"。
您可以使用 etcd 备份将集群恢复到以前的状态。在以下情况中可以使用这个方法进行恢复:
- 集群丢失了大多数 control plane 主机(仲裁丢失)。
- 管理员删除了一些关键内容,必须恢复才能恢复集群。
在一个正在运行的集群中恢复到以前的集群状态是破坏性的,而不稳定的操作。这仅应作为最后的手段使用。
如果您可以使用 Kubernetes API 服务器检索数据,则代表 etcd 可用,且您不应该使用 etcd 备份来恢复。
恢复 etcd 实际相当于把集群返回到以前的一个状态,所有客户端都会遇到一个有冲突的、并行历史记录。这会影响 kubelet、Kubernetes 控制器管理器、持久性卷控制器和 OpenShift Container Platform Operator 等监视组件的行为,包括网络操作器。
当 etcd 中的内容与磁盘上的实际内容不匹配时,可能会导致 Operator churn,从而导致 Kubernetes API 服务器、Kubernetes 控制器管理器、Kubernetes 调度程序和 etcd 的 Operator 在磁盘上的文件与 etcd 中的内容冲突时卡住。这可能需要手动操作来解决问题。
在极端情况下,集群可能会丢失持久性卷跟踪,删除已不存在的关键工作负载,重新镜像机器,以及重写带有过期证书的 CA 捆绑包。
6.3.3.2. 将单一节点恢复到以前的集群状态 复制链接链接已复制到粘贴板!
您可以使用已保存的 etcd 备份,将单一节点恢复到以前的集群状态。
恢复集群时,必须使用同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.19.2 集群必须使用从 4.19.2 中获得的 etcd 备份。
先决条件
-
通过一个基于证书的
kubeconfig
使用具有cluster-admin
角色的用户访问集群,如安装期间的情况。 - 有到 control plane 主机的 SSH 访问权限。
-
包含从同一备份中获取的 etcd 快照和静态 pod 资源的备份目录。该目录中的文件名必须采用以下格式:
snapshot_<datetimestamp>.db
和static_kuberesources_<datetimestamp>.tar.gz
。
流程
运行以下命令,使用 SSH 连接到单一节点,并将 etcd 备份复制到
/home/core
目录中:cp <etcd_backup_directory> /home/core
$ cp <etcd_backup_directory> /home/core
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在单一节点中运行以下命令从以前的备份中恢复集群:
sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd_backup_directory>
$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd_backup_directory>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 退出 SSH 会话。
运行以下命令监控 control plane 的恢复进度:
oc adm wait-for-stable-cluster
$ oc adm wait-for-stable-cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意control plane 最多可能需要 15 分钟才能恢复。
6.3.3.3. 为多个节点恢复到一个以前的集群状态 复制链接链接已复制到粘贴板!
您可以使用保存的 etcd 备份来恢复以前的集群状态,或恢复丢失了大多数 control plane 主机的集群。
对于高可用性(HA)集群,一个三节点集群需要在两个主机上关闭 etcd,以避免集群分割。在四节点和五个节点 HA 集群中,您必须关闭三个主机。仲裁只需要具有多数节点的情况。三节点 HA 集群中,仲裁最少需要两个节点。在四节点和五个节点 HA 集群中,仲裁需要的最小节点数为三。如果您从恢复主机上的备份启动新集群,其他 etcd 成员可能仍然可以组成仲裁并继续服务。
如果您的集群使用 control plane 机器集,请参阅 "Troubleshooting control plane 机器集"。对于单一节点上的 OpenShift Container Platform,请参阅"为单一节点提供以前的集群状态"。
恢复集群时,必须使用同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.19.2 集群必须使用从 4.19.2 中获得的 etcd 备份。
先决条件
-
通过一个基于证书的
kubeconfig
使用具有cluster-admin
角色的用户访问集群,如安装期间的情况。 - 用作恢复主机的健康 control plane 主机。
- 有到 control plane 主机的 SSH 访问权限。
-
包含从同一备份中获取的 etcd 快照和静态
pod
资源的备份目录。该目录中的文件名必须采用以下格式:snapshot_<datetimestamp>.db
和static_kuberesources_<datetimestamp>.tar.gz
。
对于非恢复 control plane 节点,不需要建立 SSH 连接或停止静态 pod。您可以逐个删除并重新创建其他非恢复 control plane 机器。
流程
- 选择一个要用作恢复主机的 control plane 主机。这是在其中运行恢复操作的主机。
建立到每个 control plane 节点(包括恢复主机)的 SSH 连接。
恢复过程启动后,
kube-apiserver
将无法访问,因此您无法访问 control plane 节点。因此,建议在一个单独的终端中建立到每个control plane 主机的 SSH 连接。重要如果没有完成这个步骤,将无法访问 control plane 主机来完成恢复过程,您将无法从这个状态恢复集群。
使用 SSH 连接到每个 control plane 节点,并运行以下命令来禁用 etcd:
sudo -E /usr/local/bin/disable-etcd.sh
$ sudo -E /usr/local/bin/disable-etcd.sh
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将 etcd 备份目录复制复制到恢复 control plane 主机上。
此流程假设您将
backup
目录(其中包含 etcd 快照和静态 pod 资源)复制到恢复 control plane 主机的/home/core/
目录中。运行以下命令,使用 SSH 连接到恢复主机并从以前的备份中恢复集群:
sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd-backup-directory>
$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd-backup-directory>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 退出 SSH 会话。
API 响应后,通过运行nning 来关闭 etcd Operator 仲裁保护:
oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 运行以下命令监控 control plane 的恢复进度:
oc adm wait-for-stable-cluster
$ oc adm wait-for-stable-cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意control plane 最多可能需要 15 分钟才能恢复。
恢复后,运行以下命令来启用仲裁保护:
oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
故障排除
如果推出 etcd 静态 pod 的过程没有进展,您可以通过运行以下命令来强制从 cluster-etcd-operator
重新部署:
oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
6.3.3.4. 从 etcd 备份手动恢复集群 复制链接链接已复制到粘贴板!
恢复过程在 "Restoring to a previous cluster state" 部分中介绍:
-
需要 2 个 control plane 节点的完整重新创建,这可能是使用 UPI 安装方法安装的集群的一个复杂步骤,因为 UPI 安装不会为 control plane 节点创建任何
Machine
或ControlPlaneMachineset
。 - 使用脚本 /usr/local/bin/cluster-restore.sh,它会启动新的单成员 etcd 集群,然后将其扩展到三个成员。
相反,这个过程:
- 不需要重新创建任何 control plane 节点。
- 直接启动一个三成员 etcd 集群。
如果集群使用 MachineSet
用于 control plane,建议使用 "Restoring to a previous cluster state" 用于简化 etcd 恢复的步骤。
恢复集群时,必须使用同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.7.2 集群必须使用从 4.7.2 开始的 etcd 备份。
先决条件
-
使用具有
cluster-admin
角色的用户访问集群,例如kubeadmin
用户。 -
通过 SSH 访问所有 control plane 主机,允许主机用户成为
root
用户;例如,默认的core
主机用户。 -
包含之前 etcd 快照和来自同一备份的静态 pod 资源的备份目录。该目录中的文件名必须采用以下格式:
snapshot_<datetimestamp>.db
和static_kuberesources_<datetimestamp>.tar.gz
。
流程
使用 SSH 连接到每个 control plane 节点。
恢复过程启动后,Kubernetes API 服务器将无法访问,因此您无法访问 control plane 节点。因此,建议针对每个 control plane 主机都使用一个单独的终端来进行 SSH 连接。
重要如果没有完成这个步骤,将无法访问 control plane 主机来完成恢复过程,您将无法从这个状态恢复集群。
将 etcd 备份目录复制到每个 control plane 主机上。
此流程假设您将
backup
目录(其中包含 etcd 快照和静态 pod 资源)复制到每个 control plane 主机的/home/core/assets
目录中。如果尚未存在,您可能需要创建此assets
文件夹。停止所有 control plane 节点上的静态 pod;一次只针对一个主机进行。
将现有 Kubernetes API Server 静态 pod 清单从 kubelet 清单目录中移出。
mkdir -p /root/manifests-backup mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /root/manifests-backup/
$ mkdir -p /root/manifests-backup $ mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /root/manifests-backup/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令验证 Kubernetes API 服务器容器是否已停止:
crictl ps | grep kube-apiserver | grep -E -v "operator|guard"
$ crictl ps | grep kube-apiserver | grep -E -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。
如果 Kubernetes API 服务器容器仍在运行,使用以下命令手动终止它们:
crictl stop <container_id>
$ crictl stop <container_id>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对
kube-controller-manager-pod.yaml
、kube-scheduler-pod.yaml
最后为etcd-pod.yaml
重复相同的步骤,。使用以下命令停止
kube-controller-manager
pod:mv /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /root/manifests-backup/
$ mv /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /root/manifests-backup/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令检查容器是否已停止:
crictl ps | grep kube-controller-manager | grep -E -v "operator|guard"
$ crictl ps | grep kube-controller-manager | grep -E -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令停止
kube-scheduler
pod:mv /etc/kubernetes/manifests/kube-scheduler-pod.yaml /root/manifests-backup/
$ mv /etc/kubernetes/manifests/kube-scheduler-pod.yaml /root/manifests-backup/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令检查容器是否已停止:
crictl ps | grep kube-scheduler | grep -E -v "operator|guard"
$ crictl ps | grep kube-scheduler | grep -E -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令停止
etcd
pod:mv /etc/kubernetes/manifests/etcd-pod.yaml /root/manifests-backup/
$ mv /etc/kubernetes/manifests/etcd-pod.yaml /root/manifests-backup/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令检查容器是否已停止:
crictl ps | grep etcd | grep -E -v "operator|guard"
$ crictl ps | grep etcd | grep -E -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
在每个 control plane 主机上,保存当前的
etcd
数据(将它移到backup
目录中):mkdir /home/core/assets/old-member-data mv /var/lib/etcd/member /home/core/assets/old-member-data
$ mkdir /home/core/assets/old-member-data $ mv /var/lib/etcd/member /home/core/assets/old-member-data
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 当
etcd
备份恢复无法正常工作,且etcd
集群必须恢复到当前状态,则这些数据将很有用。为每个 control plane 主机找到正确的 etcd 参数。
<ETCD_NAME>
的值对每个 control plane 主机都是唯一的,它等于特定 control plane 主机上的清单/etc/kubernetes/static-pod-resources/etcd-certs/configmaps/restore-etcd-pod/pod.yaml
文件中的ETCD_NAME
变量的值。它可以通过以下命令找到:RESTORE_ETCD_POD_YAML="/etc/kubernetes/static-pod-resources/etcd-certs/configmaps/restore-etcd-pod/pod.yaml" cat $RESTORE_ETCD_POD_YAML | \ grep -A 1 $(cat $RESTORE_ETCD_POD_YAML | grep 'export ETCD_NAME' | grep -Eo 'NODE_.+_ETCD_NAME') | \ grep -Po '(?<=value: ").+(?=")'
RESTORE_ETCD_POD_YAML="/etc/kubernetes/static-pod-resources/etcd-certs/configmaps/restore-etcd-pod/pod.yaml" cat $RESTORE_ETCD_POD_YAML | \ grep -A 1 $(cat $RESTORE_ETCD_POD_YAML | grep 'export ETCD_NAME' | grep -Eo 'NODE_.+_ETCD_NAME') | \ grep -Po '(?<=value: ").+(?=")'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <UUID>
的值可使用以下命令在 control plane 主机中生成:uuidgen
$ uuidgen
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意<UUID>
的值必须只生成一次。在一个 control plane 主机上生成UUID
后,请不要在其他主机上再次生成它。相同的UUID
会在后续步骤中的所有 control plane 主机上使用。ETCD_NODE_PEER_URL
的值应设置为类似以下示例:https://<IP_CURRENT_HOST>:2380
https://<IP_CURRENT_HOST>:2380
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 正确的 IP 可以从特定 control plane 主机的
<ETCD_NAME>
中找到,使用以下命令:echo <ETCD_NAME> | \ sed -E 's/[.-]/_/g' | \ xargs -I {} grep {} /etc/kubernetes/static-pod-resources/etcd-certs/configmaps/etcd-scripts/etcd.env | \ grep "IP" | grep -Po '(?<=").+(?=")'
$ echo <ETCD_NAME> | \ sed -E 's/[.-]/_/g' | \ xargs -I {} grep {} /etc/kubernetes/static-pod-resources/etcd-certs/configmaps/etcd-scripts/etcd.env | \ grep "IP" | grep -Po '(?<=").+(?=")'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow <ETCD_INITIAL_CLUSTER>
的值应设置为如下所示,其中<ETCD_NAME_n>
是每个 control plane 主机的<ETCD_NAME>
。注意使用的端口必须是 2380,而不是 2379。端口 2379 用于 etcd 数据库管理,并直接在容器中的 etcd start 命令中配置。
输出示例
<ETCD_NAME_0>=<ETCD_NODE_PEER_URL_0>,<ETCD_NAME_1>=<ETCD_NODE_PEER_URL_1>,<ETCD_NAME_2>=<ETCD_NODE_PEER_URL_2>
<ETCD_NAME_0>=<ETCD_NODE_PEER_URL_0>,<ETCD_NAME_1>=<ETCD_NODE_PEER_URL_1>,<ETCD_NAME_2>=<ETCD_NODE_PEER_URL_2>
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 指定每个 control plane 主机中的
ETCD_NODE_PEER_URL
值。
<ETCD_INITIAL_CLUSTER>
值在所有 control plane 主机上都是相同的。在后续步骤中,每个 control plane 主机都需要使用相同的值。
从备份中重新生成 etcd 数据库。
此类操作必须在每个 control plane 主机上执行。
使用以下命令将
etcd
备份复制到/var/lib/etcd
目录中:cp /home/core/assets/backup/<snapshot_yyyy-mm-dd_hhmmss>.db /var/lib/etcd
$ cp /home/core/assets/backup/<snapshot_yyyy-mm-dd_hhmmss>.db /var/lib/etcd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在继续操作前,识别正确的
etcdctl
镜像。使用以下命令从 pod 清单的备份中检索镜像:jq -r '.spec.containers[]|select(.name=="etcdctl")|.image' /root/manifests-backup/etcd-pod.yaml
$ jq -r '.spec.containers[]|select(.name=="etcdctl")|.image' /root/manifests-backup/etcd-pod.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow podman run --rm -it --entrypoint="/bin/bash" -v /var/lib/etcd:/var/lib/etcd:z <image-hash>
$ podman run --rm -it --entrypoint="/bin/bash" -v /var/lib/etcd:/var/lib/etcd:z <image-hash>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 检查
etcdctl
工具的版本是创建备份的etcd
服务器的版本:etcdctl version
$ etcdctl version
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 运行以下命令重新生成
etcd
数据库,为当前主机使用正确的值:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意在重新生成
etcd
数据库时,引号是必需的。
记录下在
added member
日志中的值,例如:输出示例
2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "56cd73b614699e7", "added-peer-peer-urls": ["https://10.0.91.5:2380"], "added-peer-is-learner": false} 2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "1f63d01b31bb9a9e", "added-peer-peer-urls": ["https://10.0.90.221:2380"], "added-peer-is-learner": false} 2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "fdc2725b3b70127c", "added-peer-peer-urls": ["https://10.0.94.214:2380"], "added-peer-is-learner": false}
2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "56cd73b614699e7", "added-peer-peer-urls": ["https://10.0.91.5:2380"], "added-peer-is-learner": false} 2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "1f63d01b31bb9a9e", "added-peer-peer-urls": ["https://10.0.90.221:2380"], "added-peer-is-learner": false} 2022-06-28T19:52:43Z info membership/cluster.go:421 added member {"cluster-id": "c5996b7c11c30d6b", "local-member-id": "0", "added-peer-id": "fdc2725b3b70127c", "added-peer-peer-urls": ["https://10.0.94.214:2380"], "added-peer-is-learner": false}
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 退出容器。
-
在其他 control plane 主机上重复这些步骤,检查
added member
日志中的值对于所有 control plane 主机都是一样的。
将重新生成的
etcd
数据库移到默认位置。此类操作必须在每个 control plane 主机上执行。
将重新生成的数据库(上一个
etcdctl snapshot restore
命令创建的member
文件夹)移到默认的 etcd 位置/var/lib/etcd
:mv /var/lib/etcd/restore-<UUID>/member /var/lib/etcd
$ mv /var/lib/etcd/restore-<UUID>/member /var/lib/etcd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在
/var/lib/etcd
目录中恢复/var/lib/etcd/member
文件夹的 SELinux 上下文:restorecon -vR /var/lib/etcd/
$ restorecon -vR /var/lib/etcd/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 删除剩下的文件和目录:
rm -rf /var/lib/etcd/restore-<UUID>
$ rm -rf /var/lib/etcd/restore-<UUID>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow rm /var/lib/etcd/<snapshot_yyyy-mm-dd_hhmmss>.db
$ rm /var/lib/etcd/<snapshot_yyyy-mm-dd_hhmmss>.db
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要完成后,
/var/lib/etcd
目录只能包含文件夹member
。- 在其他 control plane 主机上重复这些步骤。
重启 etcd 集群。
- 必须在所有 control plane 主机上执行以下步骤,但一次只针对一个主机执行。
将
etcd
静态 pod 清单移回到 kubelet 清单目录,以便 kubelet 启动相关的容器:mv /tmp/etcd-pod.yaml /etc/kubernetes/manifests
$ mv /tmp/etcd-pod.yaml /etc/kubernetes/manifests
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 验证所有
etcd
容器是否已启动:crictl ps | grep etcd | grep -v operator
$ crictl ps | grep etcd | grep -v operator
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
38c814767ad983 f79db5a8799fd2c08960ad9ee22f784b9fbe23babe008e8a3bf68323f004c840 28 seconds ago Running etcd-health-monitor 2 fe4b9c3d6483c e1646b15207c6 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcd-metrics 0 fe4b9c3d6483c 08ba29b1f58a7 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcd 0 fe4b9c3d6483c 2ddc9eda16f53 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcdctl
38c814767ad983 f79db5a8799fd2c08960ad9ee22f784b9fbe23babe008e8a3bf68323f004c840 28 seconds ago Running etcd-health-monitor 2 fe4b9c3d6483c e1646b15207c6 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcd-metrics 0 fe4b9c3d6483c 08ba29b1f58a7 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcd 0 fe4b9c3d6483c 2ddc9eda16f53 9d28c15860870e85c91d0e36b45f7a6edd3da757b113ec4abb4507df88b17f06 About a minute ago Running etcdctl
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果这个命令的输出为空,请等待几分钟,然后再次检查。
检查
etcd
集群的状态。在任何 control plane 主机上,使用以下命令检查
etcd
集群的状态:crictl exec -it $(crictl ps | grep etcdctl | awk '{print $1}') etcdctl endpoint status -w table
$ crictl exec -it $(crictl ps | grep etcdctl | awk '{print $1}') etcdctl endpoint status -w table
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
重启其他静态 pod。
必须在所有 control plane 主机上执行以下步骤,但一次只针对一个主机执行。
将 Kubernetes API Server 静态 pod 清单重新移到 kubelet 清单目录中,以便 kubelet 使用命令启动相关的容器:
mv /root/manifests-backup/kube-apiserver-pod.yaml /etc/kubernetes/manifests
$ mv /root/manifests-backup/kube-apiserver-pod.yaml /etc/kubernetes/manifests
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 验证所有 Kubernetes API 服务器容器是否已启动:
crictl ps | grep kube-apiserver | grep -v operator
$ crictl ps | grep kube-apiserver | grep -v operator
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意如果以下命令的输出为空,请等待几分钟,然后再次检查。
对
kube-controller-manager-pod.yaml
和kube-scheduler-pod.yaml
文件重复相同的步骤。使用以下命令重启所有节点中的 kubelet:
systemctl restart kubelet
$ systemctl restart kubelet
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令启动剩余的 control plane pod:
mv /root/manifests-backup/kube-* /etc/kubernetes/manifests/
$ mv /root/manifests-backup/kube-* /etc/kubernetes/manifests/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 检查
kube-apiserver
、kube-scheduler
和kube-controller-manager
pod 是否已正确启动:crictl ps | grep -E 'kube-(apiserver|scheduler|controller-manager)' | grep -v -E 'operator|guard'
$ crictl ps | grep -E 'kube-(apiserver|scheduler|controller-manager)' | grep -v -E 'operator|guard'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下命令擦除 OVN 数据库:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
6.3.3.6. 恢复持久性存储状态的问题和解决方法 复制链接链接已复制到粘贴板!
如果您的 OpenShift Container Platform 集群使用任何形式的持久性存储,集群的状态通常存储在 etcd 外部。它可能是在 pod 中运行的 Elasticsearch 集群,或者在 StatefulSet
对象中运行的数据库。从 etcd 备份中恢复时,还会恢复 OpenShift Container Platform 中工作负载的状态。但是,如果 etcd 快照是旧的,其状态可能无效或过期。
持久性卷(PV)的内容绝不会属于 etcd 快照的一部分。从 etcd 快照恢复 OpenShift Container Platform 集群时,非关键工作负载可能会访问关键数据,反之亦然。
以下是生成过时状态的一些示例情况:
- MySQL 数据库在由 PV 对象支持的 pod 中运行。从 etcd 快照恢复 OpenShift Container Platform 不会使卷恢复到存储供应商上,且不会生成正在运行的 MySQL pod,尽管 pod 会重复尝试启动。您必须通过在存储供应商中恢复卷,然后编辑 PV 以指向新卷来手动恢复这个 pod。
- Pod P1 使用卷 A,它附加到节点 X。如果另一个 pod 在节点 Y 上使用相同的卷,则执行 etcd 恢复时,pod P1 可能无法正确启动,因为卷仍然被附加到节点 Y。OpenShift Container Platform 并不知道附加,且不会自动分离它。发生这种情况时,卷必须从节点 Y 手动分离,以便卷可以在节点 X 上附加,然后 pod P1 才可以启动。
- 在执行 etcd 快照后,云供应商或存储供应商凭证会被更新。这会导致任何依赖于这些凭证的 CSI 驱动程序或 Operator 无法正常工作。您可能需要手动更新这些驱动程序或 Operator 所需的凭证。
在生成 etcd 快照后,会从 OpenShift Container Platform 节点中删除或重命名设备。Local Storage Operator 会为从
/dev/disk/by-id
或/dev
目录中管理的每个 PV 创建符号链接。这种情况可能会导致本地 PV 引用不再存在的设备。要解决这个问题,管理员必须:
- 手动删除带有无效设备的 PV。
- 从对应节点中删除符号链接。
-
删除
LocalVolume
或LocalVolumeSet
对象(请参阅 StorageConfiguring persistent storage Persistent storage Persistent storage Deleting the Local Storage Operator Resources)。
6.3.4. 从 control plane 证书已过期的情况下恢复 复制链接链接已复制到粘贴板!
6.3.4.1. 从 control plane 证书已过期的情况下恢复 复制链接链接已复制到粘贴板!
集群可以从过期的 control plane 证书中自动恢复。
但是,您需要手动批准待处理的 node-bootstrapper
证书签名请求(CSR)来恢复 kubelet 证书。对于用户置备的安装,您可能需要批准待处理的 kubelet 服务 CSR。
使用以下步骤批准待处理的 CSR:
流程
获取当前 CSR 列表:
oc get csr
$ oc get csr
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 输出示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 查看一个 CSR 的详细信息以验证其是否有效:
oc describe csr <csr_name>
$ oc describe csr <csr_name>
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
<csr_name>
是当前 CSR 列表中 CSR 的名称。
批准每个有效的
node-bootstrapper
CSR:oc adm certificate approve <csr_name>
$ oc adm certificate approve <csr_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对于用户置备的安装,请批准每个有效的 kubelet 服务 CSR:
oc adm certificate approve <csr_name>
$ oc adm certificate approve <csr_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow