5.2. 替换不健康的 etcd 成员
本文档描述了替换一个不健康 etcd 成员的过程。
此过程取决于 etcd 成员不健康的原因,如机器没有运行,或节点未就绪,或 etcd pod 处于 crashlooping 状态。
如果您丢失了大多数 control plane 主机(也被称为 master 主机),并导致 etcd 仲裁丢失,那么您必须遵循灾难恢复流程恢复到集群原来的状态 ,而不是这个过程。
如果 control plane 证书在被替换的成员中无效,则必须遵循从已过期 control plane 证书中恢复的步骤,而不是此过程。
如果 control plane 节点丢失并且创建了一个新节点,etcd 集群 Operator 将处理生成新 TLS 证书并将节点添加为 etcd 成员。
5.2.1. 先决条件
- 在替换不健康的 etcd 成员,需要进行 etcd 备份。
5.2.2. 找出一个不健康的 etcd 成员
您可以识别集群是否有不健康的 etcd 成员。
先决条件
-
使用具有
cluster-admin
角色的用户访问集群。
流程
使用以下命令检查
EtcdMembersAvailable
状态条件的状态:$ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="EtcdMembersAvailable")]}{.message}{"\n"}'
查看输出:
2 of 3 members are available, ip-10-0-131-183.ec2.internal is unhealthy
这个示例输出显示
ip-10-0-131-183.ec2.internal
etcd 成员不健康。
5.2.3. 确定不健康的 etcd 成员的状态
替换不健康 etcd 成员的步骤取决于 etcd 的以下状态:
- 机器没有运行或者该节点未就绪
- etcd pod 处于 crashlooping 状态
此流程决定了 etcd 成员处于哪个状态。这可让您了解替换不健康的 etcd 成员要遵循的步骤。
如果您知道机器没有运行或节点未就绪,但它们应该很快返回健康状态,那么您就不需要执行替换 etcd 成员的流程。当机器或节点返回一个健康状态时,etcd cluster Operator 将自动同步。
先决条件
-
您可以使用具有
cluster-admin
角色的用户访问集群。 - 您已找到不健康的 etcd 成员。
流程
检查 机器是否没有运行:
$ oc get machines -A -ojsonpath='{range .items[*]}{@.status.nodeRef.name}{"\t"}{@.status.providerStatus.instanceState}{"\n"}' | grep -v running
输出示例
ip-10-0-131-183.ec2.internal stopped 1
- 1
- 此输出列出了节点以及节点机器的状态。如果状态不是
running
,则代表机器没有运行。
如果机器没有运行,按照替换机器没有运行或节点没有就绪的非健康 etcd 成员过程进行操作。
确定 节点是否未就绪。
如果以下任何一种情况是正确的,则代表节点没有就绪。
如果机器正在运行,检查节点是否不可访问:
$ oc get nodes -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{"\t"}{range .spec.taints[*]}{.key}{" "}' | grep unreachable
输出示例
ip-10-0-131-183.ec2.internal node-role.kubernetes.io/master node.kubernetes.io/unreachable node.kubernetes.io/unreachable 1
- 1
- 如果节点带有
unreachable
污点,则节点没有就绪。
如果该节点仍然可访问,则检查该节点是否列为
NotReady
:$ oc get nodes -l node-role.kubernetes.io/master | grep "NotReady"
输出示例
ip-10-0-131-183.ec2.internal NotReady master 122m v1.21.0 1
- 1
- 如果节点列表为
NotReady
,则 该节点没有就绪。
如果节点没有就绪,按照替换机器没有运行或节点没有就绪的 etcd 成员的步骤进行操作。
确定 etcd Pod 是否处于 crashlooping 状态。
如果机器正在运行并且节点已就绪,请检查 etcd pod 是否处于 crashlooping 状态。
验证所有 control plane 节点(也称为 master 节点)是否都列为
Ready
:$ oc get nodes -l node-role.kubernetes.io/master
输出示例
NAME STATUS ROLES AGE VERSION ip-10-0-131-183.ec2.internal Ready master 6h13m v1.21.0 ip-10-0-164-97.ec2.internal Ready master 6h13m v1.21.0 ip-10-0-154-204.ec2.internal Ready master 6h13m v1.21.0
检查 etcd pod 的状态是否为
Error
或CrashLoopBackOff
:$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | grep etcd
输出示例
etcd-ip-10-0-131-183.ec2.internal 2/3 Error 7 6h9m 1 etcd-ip-10-0-164-97.ec2.internal 3/3 Running 0 6h6m etcd-ip-10-0-154-204.ec2.internal 3/3 Running 0 6h6m
- 1
- 由于此 pod 的状态是
Error
,因此 etcd pod 为 crashlooping 状态。
如果 etcd pod 为 crashlooping 状态,请按照替换 etcd pod 处于 crashlooping 状态的不健康的 etcd 成员的步骤进行操作。
5.2.4. 替换不健康的 etcd 成员
根据不健康的 etcd 成员的状态,使用以下一个流程:
5.2.4.1. 替换机器没有运行或节点未就绪的不健康 etcd 成员
此流程详细介绍了替换因机器没有运行或节点未就绪造成不健康的 etcd 成员的步骤。
先决条件
- 您已找出不健康的 etcd 成员。
- 您已确认机器没有运行,或者该节点未就绪。
-
您可以使用具有
cluster-admin
角色的用户访问集群。 已进行 etcd 备份。
重要执行此流程前务必要进行 etcd 备份,以便在遇到任何问题时可以恢复集群。
流程
删除不健康的成员。
选择一个不在受影响节点上的 pod:
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | grep etcd
输出示例
etcd-ip-10-0-131-183.ec2.internal 3/3 Running 0 123m etcd-ip-10-0-164-97.ec2.internal 3/3 Running 0 123m etcd-ip-10-0-154-204.ec2.internal 3/3 Running 0 124m
连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
查看成员列表:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+------------------------------+---------------------------+---------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | +------------------+---------+------------------------------+---------------------------+---------------------------+ | 6fc1e7c9db35841d | started | ip-10-0-131-183.ec2.internal | https://10.0.131.183:2380 | https://10.0.131.183:2379 | | 757b6793e2408b6c | started | ip-10-0-164-97.ec2.internal | https://10.0.164.97:2380 | https://10.0.164.97:2379 | | ca8c2990a0aa29d1 | started | ip-10-0-154-204.ec2.internal | https://10.0.154.204:2380 | https://10.0.154.204:2379 | +------------------+---------+------------------------------+---------------------------+---------------------------+
记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。
$ etcdctl endpoint health
命令将列出已删除的成员,直到完成替换过程并添加了新成员。通过向
etcdctl member remove
命令提供 ID 来删除不健康的 etcd 成员 :sh-4.2# etcdctl member remove 6fc1e7c9db35841d
输出示例
Member 6fc1e7c9db35841d removed from cluster ead669ce1fbfb346
再次查看成员列表,并确认成员已被删除:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+------------------------------+---------------------------+---------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | +------------------+---------+------------------------------+---------------------------+---------------------------+ | 757b6793e2408b6c | started | ip-10-0-164-97.ec2.internal | https://10.0.164.97:2380 | https://10.0.164.97:2379 | | ca8c2990a0aa29d1 | started | ip-10-0-154-204.ec2.internal | https://10.0.154.204:2380 | https://10.0.154.204:2379 | +------------------+---------+------------------------------+---------------------------+---------------------------+
现在您可以退出节点 shell。
重要删除成员后,在剩余的 etcd 实例重启时,集群可能无法访问。
输入以下命令关闭仲裁保护:
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
此命令可确保您可以成功重新创建机密并推出静态 pod。
删除已删除的不健康 etcd 成员的旧 secret。
列出已删除的不健康 etcd 成员的 secret。
$ oc get secrets -n openshift-etcd | grep ip-10-0-131-183.ec2.internal 1
- 1
- 传递您之前在这个过程中记录的不健康 etcd 成员的名称。
有一个对等的、服务和指标的 secret,如以下输出所示:
输出示例
etcd-peer-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m etcd-serving-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m etcd-serving-metrics-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m
删除已删除的不健康 etcd 成员的 secret。
删除 peer(对等)secret:
$ oc delete secret -n openshift-etcd etcd-peer-ip-10-0-131-183.ec2.internal
删除 serving secret:
$ oc delete secret -n openshift-etcd etcd-serving-ip-10-0-131-183.ec2.internal
删除 metrics secret:
$ oc delete secret -n openshift-etcd etcd-serving-metrics-ip-10-0-131-183.ec2.internal
删除并重新创建 control plane 机器(也称为 master 机器)。重新创建此机器后,会强制一个新修订版本并自动扩展 etcd。
如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建 master 时使用的相同方法创建新的 master。
获取不健康成员的机器。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-0 Running m4.xlarge us-east-1 us-east-1a 3h37m ip-10-0-131-183.ec2.internal aws:///us-east-1a/i-0ec2782f8287dfb7e stopped 1 clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-154-204.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-164-97.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
- 1
- 这是不健康节点的 control plane 机器
ip-10-0-131-183.ec2.internal
。
将机器配置保存到文件系统中的一个文件中:
$ oc get machine clustername-8qw5l-master-0 \ 1 -n openshift-machine-api \ -o yaml \ > new-master-machine.yaml
- 1
- 为不健康的节点指定 control plane 机器的名称。
编辑上一步中创建的
new-master-machine.yaml
文件,以分配新名称并删除不必要的字段。删除整个
status
部分:status: addresses: - address: 10.0.131.183 type: InternalIP - address: ip-10-0-131-183.ec2.internal type: InternalDNS - address: ip-10-0-131-183.ec2.internal type: Hostname lastUpdated: "2020-04-20T17:44:29Z" nodeRef: kind: Node name: ip-10-0-131-183.ec2.internal uid: acca4411-af0d-4387-b73e-52b2484295ad phase: Running providerStatus: apiVersion: awsproviderconfig.openshift.io/v1beta1 conditions: - lastProbeTime: "2020-04-20T16:53:50Z" lastTransitionTime: "2020-04-20T16:53:50Z" message: machine successfully created reason: MachineCreationSucceeded status: "True" type: MachineCreation instanceId: i-0fdb85790d76d0c3f instanceState: stopped kind: AWSMachineProviderStatus
将
metadata.name
字段更改为新名称。建议您保留与旧机器相同的基础名称,并将结束号码改为下一个可用数字。在本例中,
clustername-8qw5l-master-0
改为clustername-8qw5l-master-3
。例如:
apiVersion: machine.openshift.io/v1beta1 kind: Machine metadata: ... name: clustername-8qw5l-master-3 ...
删除
spec.providerID
字段:providerID: aws:///us-east-1a/i-0fdb85790d76d0c3f
删除不健康成员的机器:
$ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 1
- 1
- 为不健康的节点指定 control plane 机器的名称。
验证机器是否已删除:
$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-154-204.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-164-97.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
使用
new-master-machine.yaml
文件创建新机器:$ oc apply -f new-master-machine.yaml
验证新机器是否已创建:
$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-154-204.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-164-97.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-master-3 Provisioning m4.xlarge us-east-1 us-east-1a 85s ip-10-0-133-53.ec2.internal aws:///us-east-1a/i-015b0888fe17bc2c8 running 1 clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running
- 1
- 新机器
clustername-8qw5l-master-3
将被创建,并当阶段从Provisioning
变为Running
后就可以使用。
创建新机器可能需要几分钟时间。当机器或节点返回一个健康状态时,etcd cluster Operator 将自动同步。
输入以下命令重新打开仲裁保护:
$ oc patch etcd/cluster --type=merge -p '\{"spec": {"unsupportedConfigOverrides": null}}
您可以输入以下命令验证
unsupportedConfigOverrides
部分是否已从对象中删除:$ oc get etcd/cluster -oyaml
验证
验证所有 etcd pod 是否都正常运行。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | grep etcd
输出示例
etcd-ip-10-0-133-53.ec2.internal 3/3 Running 0 7m49s etcd-ip-10-0-164-97.ec2.internal 3/3 Running 0 123m etcd-ip-10-0-154-204.ec2.internal 3/3 Running 0 124m
如果上一命令的输出只列出两个 pod,您可以手动强制重新部署 etcd。在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 1
- 1
forceRedeploymentReason
值必须是唯一的,这就是为什么附加时间戳的原因。
验证只有三个 etcd 成员。
连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
查看成员列表:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+------------------------------+---------------------------+---------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | +------------------+---------+------------------------------+---------------------------+---------------------------+ | 5eb0d6b8ca24730c | started | ip-10-0-133-53.ec2.internal | https://10.0.133.53:2380 | https://10.0.133.53:2379 | | 757b6793e2408b6c | started | ip-10-0-164-97.ec2.internal | https://10.0.164.97:2380 | https://10.0.164.97:2379 | | ca8c2990a0aa29d1 | started | ip-10-0-154-204.ec2.internal | https://10.0.154.204:2380 | https://10.0.154.204:2379 | +------------------+---------+------------------------------+---------------------------+---------------------------+
如果上一命令的输出列出了超过三个 etcd 成员,您必须删除不需要的成员。
警告确保删除正确的 etcd 成员;如果删除了正常的 etcd 成员则有可能会导致仲裁丢失。
5.2.4.2. 替换其 etcd Pod 处于 crashlooping 状态的不健康 etcd 成员
此流程详细介绍了替换因 etcd pod 处于 crashlooping 状态造成不健康的 etcd 成员的步骤。
先决条件
- 您已找出不健康的 etcd 成员。
- 已确认 etcd pod 处于 crashlooping 状态。
-
您可以使用具有
cluster-admin
角色的用户访问集群。 已进行 etcd 备份。
重要执行此流程前务必要进行 etcd 备份,以便在遇到任何问题时可以恢复集群。
流程
停止处于 crashlooping 状态的 etcd pod。
对处于 crashlooping 状态的节点进行调试。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc debug node/ip-10-0-131-183.ec2.internal 1
- 1
- 使用不健康节点的名称来替换它。
将您的根目录改为
/host
:sh-4.2# chroot /host
将现有 etcd pod 文件从 Kubelet 清单目录中移出:
sh-4.2# mkdir /var/lib/etcd-backup
sh-4.2# mv /etc/kubernetes/manifests/etcd-pod.yaml /var/lib/etcd-backup/
将 etcd 数据目录移到不同的位置:
sh-4.2# mv /var/lib/etcd/ /tmp
现在您可以退出节点 shell。
删除不健康的成员。
选择一个不在受影响节点上的 pod。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | grep etcd
输出示例
etcd-ip-10-0-131-183.ec2.internal 2/3 Error 7 6h9m etcd-ip-10-0-164-97.ec2.internal 3/3 Running 0 6h6m etcd-ip-10-0-154-204.ec2.internal 3/3 Running 0 6h6m
连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
查看成员列表:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+------------------------------+---------------------------+---------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | +------------------+---------+------------------------------+---------------------------+---------------------------+ | 62bcf33650a7170a | started | ip-10-0-131-183.ec2.internal | https://10.0.131.183:2380 | https://10.0.131.183:2379 | | b78e2856655bc2eb | started | ip-10-0-164-97.ec2.internal | https://10.0.164.97:2380 | https://10.0.164.97:2379 | | d022e10b498760d5 | started | ip-10-0-154-204.ec2.internal | https://10.0.154.204:2380 | https://10.0.154.204:2379 | +------------------+---------+------------------------------+---------------------------+---------------------------+
记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。
通过向
etcdctl member remove
命令提供 ID 来删除不健康的 etcd 成员 :sh-4.2# etcdctl member remove 62bcf33650a7170a
输出示例
Member 62bcf33650a7170a removed from cluster ead669ce1fbfb346
再次查看成员列表,并确认成员已被删除:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+------------------------------+---------------------------+---------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | +------------------+---------+------------------------------+---------------------------+---------------------------+ | b78e2856655bc2eb | started | ip-10-0-164-97.ec2.internal | https://10.0.164.97:2380 | https://10.0.164.97:2379 | | d022e10b498760d5 | started | ip-10-0-154-204.ec2.internal | https://10.0.154.204:2380 | https://10.0.154.204:2379 | +------------------+---------+------------------------------+---------------------------+---------------------------+
现在您可以退出节点 shell。
输入以下命令关闭仲裁保护:
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
此命令可确保您可以成功重新创建机密并推出静态 pod。
删除已删除的不健康 etcd 成员的旧 secret。
列出已删除的不健康 etcd 成员的 secret。
$ oc get secrets -n openshift-etcd | grep ip-10-0-131-183.ec2.internal 1
- 1
- 传递您之前在这个过程中记录的不健康 etcd 成员的名称。
有一个对等的、服务和指标的 secret,如以下输出所示:
输出示例
etcd-peer-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m etcd-serving-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m etcd-serving-metrics-ip-10-0-131-183.ec2.internal kubernetes.io/tls 2 47m
删除已删除的不健康 etcd 成员的 secret。
删除 peer(对等)secret:
$ oc delete secret -n openshift-etcd etcd-peer-ip-10-0-131-183.ec2.internal
删除 serving secret:
$ oc delete secret -n openshift-etcd etcd-serving-ip-10-0-131-183.ec2.internal
删除 metrics secret:
$ oc delete secret -n openshift-etcd etcd-serving-metrics-ip-10-0-131-183.ec2.internal
强制 etcd 重新部署。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "single-master-recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 1
- 1
forceRedeploymentReason
值必须是唯一的,这就是为什么附加时间戳的原因。
当 etcd 集群 Operator 执行重新部署时,它会确保所有 control plane 节点(也称为 master 节点)都有一个可正常工作的 etcd pod。
输入以下命令重新打开仲裁保护:
$ oc patch etcd/cluster --type=merge -p '\{"spec": {"unsupportedConfigOverrides": null}}
您可以输入以下命令验证
unsupportedConfigOverrides
部分是否已从对象中删除:$ oc get etcd/cluster -oyaml
验证
确认新成员可用且健康。
连接到正在运行的 etcd 容器。
在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:
$ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
验证所有成员是否健康:
sh-4.2# etcdctl endpoint health
输出示例
https://10.0.131.183:2379 is healthy: successfully committed proposal: took = 16.671434ms https://10.0.154.204:2379 is healthy: successfully committed proposal: took = 16.698331ms https://10.0.164.97:2379 is healthy: successfully committed proposal: took = 16.621645ms
5.2.4.3. 替换机器没有运行或节点未就绪的不健康裸机 etcd 成员
此流程详细介绍了替换因机器没有运行或节点未就绪造成不健康的裸机 etcd 成员的步骤。
如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建控制平面节点时使用的相同方法创建新的控制平面。
先决条件
- 您已找出不健康的裸机 etcd 成员。
- 您已确认机器没有运行,或者该节点未就绪。
-
您可以使用具有
cluster-admin
角色的用户访问集群。 已进行 etcd 备份。
重要执行此流程前务必要进行 etcd 备份,以便在遇到任何问题时可以恢复集群。
流程
验证并删除不健康的成员。
选择一个不在受影响节点上的 pod:
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd -o wide | grep etcd | grep -v guard
输出示例
etcd-openshift-control-plane-0 5/5 Running 11 3h56m 192.168.10.9 openshift-control-plane-0 <none> <none> etcd-openshift-control-plane-1 5/5 Running 0 3h54m 192.168.10.10 openshift-control-plane-1 <none> <none> etcd-openshift-control-plane-2 5/5 Running 0 3h58m 192.168.10.11 openshift-control-plane-2 <none> <none>
连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc rsh -n openshift-etcd etcd-openshift-control-plane-0
查看成员列表:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+--------------------+---------------------------+---------------------------+---------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | +------------------+---------+--------------------+---------------------------+---------------------------+---------------------+ | 7a8197040a5126c8 | started | openshift-control-plane-2 | https://192.168.10.11:2380/ | https://192.168.10.11:2379/ | false | | 8d5abe9669a39192 | started | openshift-control-plane-1 | https://192.168.10.10:2380/ | https://192.168.10.10:2379/ | false | | cc3830a72fc357f9 | started | openshift-control-plane-0 | https://192.168.10.9:2380/ | https://192.168.10.9:2379/ | false | +------------------+---------+--------------------+---------------------------+---------------------------+---------------------+
记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。
etcdctl endpoint health
命令将列出已删除的成员,直到完成替换过程并添加了新成员。通过向
etcdctl member remove
命令提供 ID 来删除不健康的 etcd 成员 :警告确保删除正确的 etcd 成员;如果删除了正常的 etcd 成员则有可能会导致仲裁丢失。
sh-4.2# etcdctl member remove 7a8197040a5126c8
输出示例
Member 7a8197040a5126c8 removed from cluster b23536c33f2cdd1b
再次查看成员列表,并确认成员已被删除:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | +------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+ | 7a8197040a5126c8 | started | openshift-control-plane-2 | https://192.168.10.11:2380/ | https://192.168.10.11:2379/ | false | | 8d5abe9669a39192 | started | openshift-control-plane-1 | https://192.168.10.10:2380/ | https://192.168.10.10:2379/ | false | +------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+
现在您可以退出节点 shell。
重要删除成员后,在剩余的 etcd 实例重启时,集群可能无法访问。
输入以下命令关闭仲裁保护:
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
此命令可确保您可以成功重新创建机密并推出静态 pod。
运行以下命令,删除已删除的不健康 etcd 成员的旧 secret。
列出已删除的不健康 etcd 成员的 secret。
$ oc get secrets -n openshift-etcd | grep openshift-control-plane-2
传递您之前在这个过程中记录的不健康 etcd 成员的名称。
有一个对等的、服务和指标的 secret,如以下输出所示:
etcd-peer-openshift-control-plane-2 kubernetes.io/tls 2 134m etcd-serving-metrics-openshift-control-plane-2 kubernetes.io/tls 2 134m etcd-serving-openshift-control-plane-2 kubernetes.io/tls 2 134m
删除已删除的不健康 etcd 成员的 secret。
删除 peer(对等)secret:
$ oc delete secret etcd-peer-openshift-control-plane-2 -n openshift-etcd secret "etcd-peer-openshift-control-plane-2" deleted
删除 serving secret:
$ oc delete secret etcd-serving-metrics-openshift-control-plane-2 -n openshift-etcd secret "etcd-serving-metrics-openshift-control-plane-2" deleted
删除 metrics secret:
$ oc delete secret etcd-serving-openshift-control-plane-2 -n openshift-etcd secret "etcd-serving-openshift-control-plane-2" deleted
删除 control plane 机器。
如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建控制平面节点时使用的相同方法创建新的控制平面。
获取不健康成员的机器。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE examplecluster-control-plane-0 Running 3h11m openshift-control-plane-0 baremetalhost:///openshift-machine-api/openshift-control-plane-0/da1ebe11-3ff2-41c5-b099-0aa41222964e externally provisioned 1 examplecluster-control-plane-1 Running 3h11m openshift-control-plane-1 baremetalhost:///openshift-machine-api/openshift-control-plane-1/d9f9acbc-329c-475e-8d81-03b20280a3e1 externally provisioned examplecluster-control-plane-2 Running 3h11m openshift-control-plane-2 baremetalhost:///openshift-machine-api/openshift-control-plane-2/3354bdac-61d8-410f-be5b-6a395b056135 externally provisioned examplecluster-compute-0 Running 165m openshift-compute-0 baremetalhost:///openshift-machine-api/openshift-compute-0/3d685b81-7410-4bb3-80ec-13a31858241f provisioned examplecluster-compute-1 Running 165m openshift-compute-1 baremetalhost:///openshift-machine-api/openshift-compute-1/0fdae6eb-2066-4241-91dc-e7ea72ab13b9 provisioned
- 1
- 这是不健康节点的 control plane 机器,
examplecluster-control-plane-2
。
将机器配置保存到文件系统中的一个文件中:
$ oc get machine examplecluster-control-plane-2 \ 1 -n openshift-machine-api \ -o yaml \ > new-master-machine.yaml
- 1
- 为不健康的节点指定 control plane 机器的名称。
编辑上一步中创建的
new-master-machine.yaml
文件,以分配新名称并删除不必要的字段。删除整个
status
部分:status: addresses: - address: "" type: InternalIP - address: fe80::4adf:37ff:feb0:8aa1%ens1f1.373 type: InternalDNS - address: fe80::4adf:37ff:feb0:8aa1%ens1f1.371 type: Hostname lastUpdated: "2020-04-20T17:44:29Z" nodeRef: kind: Machine name: fe80::4adf:37ff:feb0:8aa1%ens1f1.372 uid: acca4411-af0d-4387-b73e-52b2484295ad phase: Running providerStatus: apiVersion: machine.openshift.io/v1beta1 conditions: - lastProbeTime: "2020-04-20T16:53:50Z" lastTransitionTime: "2020-04-20T16:53:50Z" message: machine successfully created reason: MachineCreationSucceeded status: "True" type: MachineCreation instanceId: i-0fdb85790d76d0c3f instanceState: stopped kind: Machine
将
metadata.name
字段更改为新名称。建议您保留与旧机器相同的基础名称,并将结束号码改为下一个可用数字。在本例中,
examplecluster-control-plane-2
改为examplecluster-control-plane-3
。例如:
apiVersion: machine.openshift.io/v1beta1 kind: Machine metadata: ... name: examplecluster-control-plane-3 ...
删除
spec.providerID
字段:providerID: baremetalhost:///openshift-machine-api/openshift-control-plane-2/3354bdac-61d8-410f-be5b-6a395b056135
删除
metadata.annotations
和metadata.generation
字段:annotations: machine.openshift.io/instance-state: externally provisioned ... generation: 2
删除
spec.conditions
、spec.lastUpdated
、spec.nodeRef
和spec.phase
字段:lastTransitionTime: "2022-08-03T08:40:36Z" message: 'Drain operation currently blocked by: [{Name:EtcdQuorumOperator Owner:clusteroperator/etcd}]' reason: HookPresent severity: Warning status: "False" type: Drainable lastTransitionTime: "2022-08-03T08:39:55Z" status: "True" type: InstanceExists lastTransitionTime: "2022-08-03T08:36:37Z" status: "True" type: Terminable lastUpdated: "2022-08-03T08:40:36Z" nodeRef: kind: Node name: openshift-control-plane-2 uid: 788df282-6507-4ea2-9a43-24f237ccbc3c phase: Running
运行以下命令,确保 Bare Metal Operator 可用:
$ oc get clusteroperator baremetal
输出示例
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE baremetal 4.11.3 True False False 3d15h
使用以下命令删除不健康成员的机器:
$ oc delete machine -n openshift-machine-api examplecluster-control-plane-2
如果删除机器因任何原因或者命令被移动而延迟而延迟而延迟,您可以通过删除机器对象终结器字段来强制删除。
重要不要通过按
Ctrl+c
中断机器删除。您必须允许命令继续完成。打开一个新的终端窗口来编辑并删除 finalizer 字段。$ oc edit machine -n openshift-machine-api examplecluster-control-plane-2
查找并删除字段:
finalizers: - machine.machine.openshift.io
保存您的更改:
machine.machine.openshift.io/examplecluster-control-plane-2 edited
运行以下命令验证机器是否已删除:
$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE examplecluster-control-plane-0 Running 3h11m openshift-control-plane-0 baremetalhost:///openshift-machine-api/openshift-control-plane-0/da1ebe11-3ff2-41c5-b099-0aa41222964e externally provisioned examplecluster-control-plane-1 Running 3h11m openshift-control-plane-1 baremetalhost:///openshift-machine-api/openshift-control-plane-1/d9f9acbc-329c-475e-8d81-03b20280a3e1 externally provisioned examplecluster-compute-0 Running 165m openshift-compute-0 baremetalhost:///openshift-machine-api/openshift-compute-0/3d685b81-7410-4bb3-80ec-13a31858241f provisioned examplecluster-compute-1 Running 165m openshift-compute-1 baremetalhost:///openshift-machine-api/openshift-compute-1/0fdae6eb-2066-4241-91dc-e7ea72ab13b9 provisioned
使用以下命令删除旧
BareMetalHost
对象:$ oc delete bmh openshift-control-plane-2 -n openshift-machine-api
输出示例
baremetalhost.metal3.io "openshift-control-plane-2" deleted
删除
BareMetalHost
和Machine
对象后,Machine
Controller 会自动删除Node
对象。如果删除
BareMetalHost
对象后,机器节点需要过量删除时间,可以使用以下方法删除机器节点:$ oc delete node openshift-control-plane-2 node "openshift-control-plane-2" deleted
验证节点已被删除:
$ oc get nodes NAME STATUS ROLES AGE VERSION openshift-control-plane-0 Ready master 3h24m v1.24.0+9546431 openshift-control-plane-1 Ready master 3h24m v1.24.0+9546431 openshift-compute-0 Ready worker 176m v1.24.0+9546431 openshift-compute-1 Ready worker 176m v1.24.0+9546431
创建新的
BareMetalHost
对象和 secret,以存储 BMC 凭证:$ cat <<EOF | oc apply -f - apiVersion: v1 kind: Secret metadata: name: openshift-control-plane-2-bmc-secret namespace: openshift-machine-api data: password: <password> username: <username> type: Opaque --- apiVersion: metal3.io/v1alpha1 kind: BareMetalHost metadata: name: openshift-control-plane-2 namespace: openshift-machine-api spec: automatedCleaningMode: disabled bmc: address: redfish://10.46.61.18:443/redfish/v1/Systems/1 credentialsName: openshift-control-plane-2-bmc-secret disableCertificateVerification: true bootMACAddress: 48:df:37:b0:8a:a0 bootMode: UEFI externallyProvisioned: false online: true rootDeviceHints: deviceName: /dev/sda userData: name: master-user-data-managed namespace: openshift-machine-api EOF
注意用户名和密码可从其他裸机主机的 secret 中找到。
bmc:address
中使用的协议可以从其他 bmh 对象获取。重要如果您从现有 control plane 主机重复使用
BareMetalHost
对象定义,请不要将 externalProvisioned
字段保留为true
。如果 OpenShift Container Platform 安装程序置备,现有 control plane
BareMetalHost
对象可能会将externallyProvisioned
标记设为true
。检查完成后,
BareMetalHost
对象会被创建并可用置备。使用可用的
BareMetalHost
对象验证创建过程:$ oc get bmh -n openshift-machine-api NAME STATE CONSUMER ONLINE ERROR AGE openshift-control-plane-0 externally provisioned examplecluster-control-plane-0 true 4h48m openshift-control-plane-1 externally provisioned examplecluster-control-plane-1 true 4h48m openshift-control-plane-2 available examplecluster-control-plane-3 true 47m openshift-compute-0 provisioned examplecluster-compute-0 true 4h48m openshift-compute-1 provisioned examplecluster-compute-1 true 4h48m
使用
new-master-machine.yaml
文件创建新 control plane 机器:$ oc apply -f new-master-machine.yaml
验证新机器是否已创建:
$ oc get machines -n openshift-machine-api -o wide
输出示例
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE examplecluster-control-plane-0 Running 3h11m openshift-control-plane-0 baremetalhost:///openshift-machine-api/openshift-control-plane-0/da1ebe11-3ff2-41c5-b099-0aa41222964e externally provisioned 1 examplecluster-control-plane-1 Running 3h11m openshift-control-plane-1 baremetalhost:///openshift-machine-api/openshift-control-plane-1/d9f9acbc-329c-475e-8d81-03b20280a3e1 externally provisioned examplecluster-control-plane-2 Running 3h11m openshift-control-plane-2 baremetalhost:///openshift-machine-api/openshift-control-plane-2/3354bdac-61d8-410f-be5b-6a395b056135 externally provisioned examplecluster-compute-0 Running 165m openshift-compute-0 baremetalhost:///openshift-machine-api/openshift-compute-0/3d685b81-7410-4bb3-80ec-13a31858241f provisioned examplecluster-compute-1 Running 165m openshift-compute-1 baremetalhost:///openshift-machine-api/openshift-compute-1/0fdae6eb-2066-4241-91dc-e7ea72ab13b9 provisioned
- 1
- 新机器
clustername-8qw5l-master-3
会被创建,并在阶段从Provisioning
变为Running
后就绪。
创建新机器需要几分钟时间。当机器或节点返回一个健康状态时,etcd cluster Operator 将自动同步。
运行以下命令验证裸机主机是否被置备,且没有报告的错误:
$ oc get bmh -n openshift-machine-api
输出示例
$ oc get bmh -n openshift-machine-api NAME STATE CONSUMER ONLINE ERROR AGE openshift-control-plane-0 externally provisioned examplecluster-control-plane-0 true 4h48m openshift-control-plane-1 externally provisioned examplecluster-control-plane-1 true 4h48m openshift-control-plane-2 provisioned examplecluster-control-plane-3 true 47m openshift-compute-0 provisioned examplecluster-compute-0 true 4h48m openshift-compute-1 provisioned examplecluster-compute-1 true 4h48m
运行以下命令验证新节点是否已添加并处于就绪状态:
$ oc get nodes
输出示例
$ oc get nodes NAME STATUS ROLES AGE VERSION openshift-control-plane-0 Ready master 4h26m v1.24.0+9546431 openshift-control-plane-1 Ready master 4h26m v1.24.0+9546431 openshift-control-plane-2 Ready master 12m v1.24.0+9546431 openshift-compute-0 Ready worker 3h58m v1.24.0+9546431 openshift-compute-1 Ready worker 3h58m v1.24.0+9546431
输入以下命令重新打开仲裁保护:
$ oc patch etcd/cluster --type=merge -p '\{"spec": {"unsupportedConfigOverrides": null}}
您可以输入以下命令验证
unsupportedConfigOverrides
部分是否已从对象中删除:$ oc get etcd/cluster -oyaml
验证
验证所有 etcd pod 是否都正常运行。
在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc get pods -n openshift-etcd -o wide | grep etcd | grep -v guard
输出示例
etcd-openshift-control-plane-0 5/5 Running 0 105m etcd-openshift-control-plane-1 5/5 Running 0 107m etcd-openshift-control-plane-2 5/5 Running 0 103m
如果上一命令的输出只列出两个 pod,您可以手动强制重新部署 etcd。在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 1
- 1
forceRedeploymentReason
值必须是唯一的,这就是为什么附加时间戳的原因。
要验证是否有完全有三个 etcd 成员,连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称。在一个终端中使用
cluster-admin
用户连接到集群,运行以下命令:$ oc rsh -n openshift-etcd etcd-openshift-control-plane-0
查看成员列表:
sh-4.2# etcdctl member list -w table
输出示例
+------------------+---------+--------------------+---------------------------+---------------------------+-----------------+ | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | +------------------+---------+--------------------+---------------------------+---------------------------+-----------------+ | 7a8197040a5126c8 | started | openshift-control-plane-2 | https://192.168.10.11:2380 | https://192.168.10.11:2379 | false | | 8d5abe9669a39192 | started | openshift-control-plane-1 | https://192.168.10.10:2380 | https://192.168.10.10:2379 | false | | cc3830a72fc357f9 | started | openshift-control-plane-0 | https://192.168.10.9:2380 | https://192.168.10.9:2379 | false | +------------------+---------+--------------------+---------------------------+---------------------------+-----------------+
注意如果上一命令的输出列出了超过三个 etcd 成员,您必须删除不需要的成员。
运行以下命令,验证所有 etcd 成员是否健康:
# etcdctl endpoint health --cluster
输出示例
https://192.168.10.10:2379 is healthy: successfully committed proposal: took = 8.973065ms https://192.168.10.9:2379 is healthy: successfully committed proposal: took = 11.559829ms https://192.168.10.11:2379 is healthy: successfully committed proposal: took = 11.665203ms
运行以下命令,验证所有节点是否处于最新的修订版本:
$ oc get etcd -o=jsonpath='{range.items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
AllNodesAtLatestRevision