etcd


OpenShift Container Platform 4.19

使用 etcd 提供冗余

Red Hat OpenShift Documentation Team

摘要

本文档提供了有关使用 etcd 的说明,它可确保在 OpenShift Container Platform 中进行集群配置和弹性的可靠方法。

第 1 章 etcd 概述

etcd (发音为 et-see-dee)是一个一致的分布式键值存储,它会存储少量跨一个集群间的机器的数据,这些数据可以完全保持在内存中。作为许多项目的核心组件,etcd 也是 Kubernetes 的主要数据存储,这是容器编配的标准系统。

通过使用 etcd,您可以以多种方式获益:

  • 实现云原生应用程序的一致性运行时间,并在单个服务器失败的情况下仍然可以保持工作
  • 为 Kubernetes 存储和复制所有集群状态
  • 分发配置数据,以便为配置节点提供冗余和弹性
重要

默认的 etcd 配置可优化容器编配。按照设计目的使用可以获取最佳结果。

1.1. etcd 的工作原理

为了确保集群配置和管理的可靠方法,etcd 使用 etcd Operator。Operator 简化了在 Kubernetes 容器平台(如 OpenShift Container Platform 中)对 etcd 的使用。

另外,您可以使用 etcd Operator 为 OpenShift Container Platform control plane 部署和管理 etcd 集群。etcd Operator 通过以下方式管理集群状态:

  • 使用 Kubernetes API 观察集群状态
  • 分析当前状态和所需状态之间的区别
  • 通过 etcd 集群管理 API、Kubernetes API 或两者来更正不同之处

etcd 会维持集群状态,它会持续更新。这个状态会被持续保留,从而导致高频率的、大量的小更改。因此,使用快速、低延迟 I/O 支持 etcd 集群成员至关重要。有关 etcd 的最佳实践的更多信息,请参阅"推荐 etcd 实践"。

1.2. 了解 etcd 性能

由于一致的分布式键值存储作为复制节点集群运行,etcd 会按照 Raft 算法将一个节点选为领导(leader),其它为跟随者(follower)。领导机维护系统的当前状态,并确保跟随者有最新的信息。

领导节点负责日志复制。它处理从客户端传入的写入事务,并写一个 Raft 日志条目,然后再将其广播到跟随者。

当一个 etcd 客户端(如 kube-apiserver)连接到一个 etcd 成员,它在请求一个需要仲裁的操作(如写一个值),如果 etcd 成员是跟随者,它会返回一个信息声明相关的事务需要转给领导。

当 etcd 客户端从需要仲裁的领导请求一个操作(如写一个值),领导会保持客户端的连接,同时写入本地 Raft 日志,将日志广播到跟随者,并等待大多数跟随者确认已提交日志并且没有错误。领导将确认发送到 etcd 客户端并关闭会话。如果从跟随者收到失败通知且没有满足共识,则领导会将错误消息返回到客户端并关闭会话。

etcd 的 OpenShift Container Platform 计时器条件

OpenShift Container Platform 会维护已为每个平台优化的 etcd 计时器。OpenShift Container Platform 已规定了为各个平台供应商优化的验证值。带有 platform=noneplatform=metal 值的默认 etcd 计时器 参数如下:

- name: ETCD_ELECTION_TIMEOUT 
1

  value: "1000"
  ...
- name: ETCD_HEARTBEAT_INTERVAL 
2

  value: "100"
Copy to Clipboard Toggle word wrap
1
此超时是跟随者节点在尝试成为领导前需要等待的、没有接收到心跳信号的时长。
2
领导通知跟随者它仍是领导的频率。

这些参数不会为 control plane 或 etcd 提供所有信息。etcd 集群对磁盘延迟非常敏感。因为 etcd 必须在其日志中保留提议,所以来自其他进程的磁盘活动可能会导致长时间 fsync 延迟。因此,etcd 可能会丢失心跳,从而导致请求超时和临时领导丢失。在领导丢失和重新选举的过程中,Kubernetes API 无法处理任何请求,并可能出现对集群服务有影响的事件,并造成集群不稳定。

磁盘延迟对 etcd 的影响

etcd 集群对磁盘延迟非常敏感。要了解 control plane 环境中 etcd 遇到的磁盘延迟问题,请运行 Flexible I/O Tester (fio) 测试或套件,以检查 OpenShift Container Platform 中的 etcd 磁盘性能。

重要

仅使用 fio 测试来测量特定时间点的磁盘延迟。此测试没有考虑到在生产环境中 etcd 可能会遇到的长期磁盘行为和其他磁盘工作负载。

确保最终报告的磁盘状态适用于 etcd,如下例所示:

...
99th percentile of fsync is 5865472 ns
99th percentile of the fsync is within the suggested threshold: - 20 ms, the disk can be used to host etcd
Copy to Clipboard Toggle word wrap

当使用高延迟磁盘时,会显示磁盘不推荐用于 etcd 的信息,如下例所示:

...
99th percentile of fsync is 15865472 ns
99th percentile of the fsync is greater than the suggested value which is 20 ms, faster disks are suggested to host etcd for better performance
Copy to Clipboard Toggle word wrap

当集群部署跨越了多个数据中心,用于 etcd 的磁盘不满足推荐的延迟标准,则可能会出现对到服务有影响的失败情况。另外,control plane 可容忍的网络延迟会显著降低。

网络延迟和 jitter 对 etcd 的影响

使用最大传输单元 (MTU) 发现和验证部分中介绍的工具来获取平均网络延迟和最大网络延迟。

心跳(heartbeat)间隔的值应大约是成员之间平均的往返时间 (RTT) 的最大值,通常大约是往返时间的 1.5 倍。OpenShift Container Platform 的默认心跳间隔为 100 ms,推荐的 control plane 节点之间的 RTT 小于 33 ms,最大小于 66 ms (66 ms x 1.5 = 99 ms)。任何大于这些值的网络延迟都可能会导致服务影响事件和集群不稳定。

网络延迟由多种因素决定,包括传输网络技术决定,如 copper、Fiber、wireless 或 satellite,在传输网络中网络设备的数量和质量,以及其他因素。

要进行精确计算,在考虑网络延迟时需要考虑到网络 jitter。网络 jitter 对网络延迟的影响,或接收的数据包延迟的影响根据具体情况会有所不同。在高效的网络条件中,jitter 应该为零。网络 jitter 对 etcd 的网络延迟计算有影响,因为在一段时间内实际网络延迟应该是 RTT 加上或减去 Jitter。

例如,一个网络的最大延迟为 80 ms,jitter 为 30 ms,则可能会出现 110 ms 的延迟,这意味着 etcd 会丢失心跳。这种情况会导致请求超时和临时丢失领导。在领导丢失和重新选举的过程中,Kubernetes API 无法处理任何请求,并可能出现对集群服务有影响的事件,并造成集群不稳定。

共识延迟对 etcd 的影响

过程只在一个活跃的集群中运行。在规划集群部署时,应已完成磁盘或网络测试。该测试会在部署后验证和监控集群健康状况。

通过使用 etcdctl CLI,您可以观察到 etcd 达成共识的延迟。您必须识别其中一个 etcd pod,然后检索端点健康状况。

etcd peer 往返时间对性能的影响

etcd peer 往返时间与网络往返时间不同。此计算是一种端到端测试指标,它包括了如何在成员间快速进行复制的方式。

etcd peer 往返时间是一个指标数据,显示 etcd 完成在所有 etcd 成员间复制客户端请求的延迟。OpenShift Container Platform 控制台提供仪表板来视觉化各种 etcd 指标。在控制台中,点 ObserveDashboards。从下拉列表中,选择 etcd

总结了 etcd peer 往返时间的图表位于 etcd Dashboard 页面的末尾。

数据库大小对 etcd 的影响

etcd 数据库大小对完成 etcd 碎片整理过程的时间有之间影响。当 OpenShift Container Platform 检测到至少 45% 的碎片时会自动执行 etcd 碎片整理(一次在一个 etcd 成员中执行)。在进行碎片整理过程中,etcd 成员无法处理任何请求。对于较小的 etcd 数据库,碎片整理过程的时间一般会小于一秒。对于较大的 etcd 数据库,磁盘延迟会直接影响到碎片时间,从而导致额外的延迟,因为在进行碎片整理的过程中会阻止其它操作。

当网络分区在一段时间内隔离 control plane 节点时 etcd 数据库的大小是的一个考虑因素,control plane 需要在通讯重新建立后同步。

存在一个控制 etcd 数据库大小的最小选项,因为它依赖于系统中的 Operator 和应用程序。当您考虑系统运行的延迟范围时,请考虑同步或按 etcd 数据库大小进行碎片整理的影响。

影响的程度特定于部署。完成碎片处理的时间会在事务率中造成降级,因为 etcd 成员在碎片处理过程中无法接受更新。同样,对于有高的改变频率的大型数据库,etcd 重新同步的时间会影响到系统上的事务率和事务延迟。在计划影响类型时,请考虑以下两个示例。

第一个基于数据库大小的 etcd 碎片处理的影响示例是,将一个 1 GB etcd 数据库写入到一个较慢的 7200 RPM 磁盘,速度是每秒 80 Mb,这大约需要 1 分 40 秒。在这样的场景中,碎片整理过程所需的时间最少要比这个时间更长才能完成碎片整理。

第二个数据库大小对 etcd 同步影响的示例是,如果在其中一个 control plane 节点断开连接时更改了 etcd 数据库的 10%,则同步需要至少传输 100 MB。通过 1 Gbps 链接传输 100 MB 时会需要 800 ms。在使用 Kubernetes API 的常规事务的集群中,etcd 数据库大小越大,越可能出现网络不稳定的情况,会导致 control plane 不稳定。

在 OpenShift Container Platform 中,etcd 仪表板有一个图表,用于报告 etcd 数据库的大小。另外,您可以使用 etcdctl 工具从 CLI 获取数据库大小。

# oc get pods -n openshift-etcd -l app=etcd
Copy to Clipboard Toggle word wrap

输出示例

NAME      READY   STATUS    RESTARTS   AGE
etcd-m0   4/4     Running   4          22h
etcd-m1   4/4     Running   4          22h
etcd-m2   4/4     Running   4          22h
Copy to Clipboard Toggle word wrap

# oc exec -t etcd-m0 -- etcdctl endpoint status -w simple | cut -d, -f 1,3,4
Copy to Clipboard Toggle word wrap

输出示例

https://198.18.111.12:2379, 3.5.6, 1.1 GB
https://198.18.111.13:2379, 3.5.6, 1.1 GB
https://198.18.111.14:2379, 3.5.6, 1.1 GB
Copy to Clipboard Toggle word wrap

Kubernetes API 事务率对 etcd 的影响

当您使用扩展 control plane 时,Kebernetes API 事务率取决于特定部署的特性。它取决于 etcd 磁盘延迟、etcd 往返时间以及写入 API 的对象大小的组合。因此,当使用扩展 control plane 时,集群管理员需要测试环境,以确定其环境的可持续事务率。kube-burner 工具可用于此目的。

为您的环境确定 Kubernetes API 事务率

您无法在不测量 Kubernetes API 的情况下确定 Kubernetes API 的事务率。用于测试 control plane 的工具之一是 kube-burner。二进制文件提供了一个 OpenShift Container Platform 打包程序来测试 OpenShift Container Platform 集群。它用于测试集群或节点密度。对于测试 control plane,kube-burner ocp 有三个工作负载配置集:cluster-density, cluster-density-v2, 和 cluster-density-ms。每个工作负载配置集创建一系列资源,旨在加载控制。

第 3 章 etcd 的性能注意事项

为确保 OpenShift Container Platform 中 etcd 的最佳性能和可扩展性,您可以完成以下实践:

3.1. etcd 的节点扩展

通常,集群必须具有 3 个 control plane 节点。但是,如果您的集群安装在裸机平台上,则最多可有 5 个 control plane 节点。如果现有裸机集群少于 5 个 control plane 节点,您可以作为一个安装后任务对集群进行扩展。

例如,要在安装后从 3 个 control plane 节点扩展到 4 个,您可以添加主机并将其作为 control plane 节点安装。然后,etcd Operator 会相应地扩展,以考虑额外的 control plane 节点。

扩展集群到 4 个或 5 个 control plane 节点仅在裸机平台上可用。

有关如何使用 Assisted Installer 扩展 control plane 节点的更多信息,请参阅"使用 API 添加主机"和"将 control plane 节点放在健康集群中"。

下表显示了不同大小的集群的容错能力:

Expand
表 3.1. 按集群大小划分的容错
集群大小大多数故障容错

1 个节点

1

0

3 个节点

2

1

4 个节点

3

1

5 个节点

3

2

有关恢复仲裁丢失的更多信息,请参阅"恢复到之前的集群状态"。

3.2. 将 etcd 移动到不同的磁盘

您可以将 etcd 从共享磁盘移到独立磁盘,以防止或解决性能问题。

Machine Config Operator (MCO) 负责为 OpenShift Container Platform 4.19 容器存储挂载辅助磁盘。

注意

这个编码脚本只支持以下设备类型的设备名称:

SCSI 或 SATA
/dev/sd*
虚拟设备
/dev/vd*
NVMe
/dev/nvme*[0-9]*n*

限制:

  • 当新磁盘附加到集群时,etcd 数据库是 root 挂载的一部分。当主节点被重新创建时,它不是二级磁盘的一部分或预期的磁盘。因此,主节点不会创建单独的 /var/lib/etcd 挂载。

先决条件

  • 有集群的 etcd 数据备份。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用 cluster-admin 权限访问集群。
  • 在上传机器配置前添加额外的磁盘。
  • MachineConfigPool 必须与 metadata.labels[machineconfiguration.openshift.io/role] 匹配。这适用于控制器、worker 或自定义池。
注意

这个过程不会将 root 文件系统的部分内容(如 /var/ )移到已安装节点上的另一个磁盘或分区。

重要

使用 control plane 机器集时不支持这个过程。

流程

  1. 将新磁盘附加到集群,并在 debug shell 中运行 lsblk 命令来验证节点中是否检测到磁盘:

    $ oc debug node/<node_name>
    Copy to Clipboard Toggle word wrap
    # lsblk
    Copy to Clipboard Toggle word wrap

    记录下 lsblk 命令报告的新磁盘的设备名称。

  2. 创建以下脚本,并将其命名为 etcd-find-secondary-device.sh

    #!/bin/bash
    set -uo pipefail
    
    for device in <device_type_glob>; do 
    1
    
    /usr/sbin/blkid "${device}" &> /dev/null
     if [ $? == 2  ]; then
        echo "secondary device found ${device}"
        echo "creating filesystem for etcd mount"
        mkfs.xfs -L var-lib-etcd -f "${device}" &> /dev/null
        udevadm settle
        touch /etc/var-lib-etcd-mount
        exit
     fi
    done
    echo "Couldn't find secondary block device!" >&2
    exit 77
    Copy to Clipboard Toggle word wrap
    1
    <device_type_glob> 替换为您的块设备类型的 shell glob。对于 SCSI 或 SATA 驱动器,使用 /dev/sd*; 对于虚拟驱动器,使用 /dev/vd*; 对于 NVMe 驱动器,使用 /dev/nvme*[0-9]*n*
  3. etcd-find-secondary-device.sh 脚本创建一个 base64 编码的字符串,并记录它的内容:

    $ base64 -w0 etcd-find-secondary-device.sh
    Copy to Clipboard Toggle word wrap
  4. 创建名为 etcd-mc.ymlMachineConfig YAML 文件,其内容如下:

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: master
      name: 98-var-lib-etcd
    spec:
      config:
        ignition:
          version: 3.5.0
        storage:
          files:
            - path: /etc/find-secondary-device
              mode: 0755
              contents:
                source: data:text/plain;charset=utf-8;base64,<encoded_etcd_find_secondary_device_script> 
    1
    
        systemd:
          units:
            - name: find-secondary-device.service
              enabled: true
              contents: |
                [Unit]
                Description=Find secondary device
                DefaultDependencies=false
                After=systemd-udev-settle.service
                Before=local-fs-pre.target
                ConditionPathExists=!/etc/var-lib-etcd-mount
    
                [Service]
                RemainAfterExit=yes
                ExecStart=/etc/find-secondary-device
    
                RestartForceExitStatus=77
    
                [Install]
                WantedBy=multi-user.target
            - name: var-lib-etcd.mount
              enabled: true
              contents: |
                [Unit]
                Before=local-fs.target
    
                [Mount]
                What=/dev/disk/by-label/var-lib-etcd
                Where=/var/lib/etcd
                Type=xfs
                TimeoutSec=120s
    
                [Install]
                RequiredBy=local-fs.target
            - name: sync-var-lib-etcd-to-etcd.service
              enabled: true
              contents: |
                [Unit]
                Description=Sync etcd data if new mount is empty
                DefaultDependencies=no
                After=var-lib-etcd.mount var.mount
                Before=crio.service
    
                [Service]
                Type=oneshot
                RemainAfterExit=yes
                ExecCondition=/usr/bin/test ! -d /var/lib/etcd/member
                ExecStart=/usr/sbin/setsebool -P rsync_full_access 1
                ExecStart=/bin/rsync -ar /sysroot/ostree/deploy/rhcos/var/lib/etcd/ /var/lib/etcd/
                ExecStart=/usr/sbin/semanage fcontext -a -t container_var_lib_t '/var/lib/etcd(/.*)?'
                ExecStart=/usr/sbin/setsebool -P rsync_full_access 0
                TimeoutSec=0
    
                [Install]
                WantedBy=multi-user.target graphical.target
            - name: restorecon-var-lib-etcd.service
              enabled: true
              contents: |
                [Unit]
                Description=Restore recursive SELinux security contexts
                DefaultDependencies=no
                After=var-lib-etcd.mount
                Before=crio.service
    
                [Service]
                Type=oneshot
                RemainAfterExit=yes
                ExecStart=/sbin/restorecon -R /var/lib/etcd/
                TimeoutSec=0
    
                [Install]
                WantedBy=multi-user.target graphical.target
    Copy to Clipboard Toggle word wrap
    1
    <encoded_etcd_find_secondary_device_script> 替换为您记录的编码脚本内容。
  5. 应用创建的 MachineConfig YAML 文件:

    $ oc create -f etcd-mc.yml
    Copy to Clipboard Toggle word wrap

验证步骤

  • 在节点的 debug shell 中运行 grep /var/lib/etcd /proc/mounts 命令,以确保挂载磁盘:

    $ oc debug node/<node_name>
    Copy to Clipboard Toggle word wrap
    # grep -w "/var/lib/etcd" /proc/mounts
    Copy to Clipboard Toggle word wrap

    输出示例

    /dev/sdb /var/lib/etcd xfs rw,seclabel,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 0
    Copy to Clipboard Toggle word wrap

3.3. 分离 etcd 数据

对于大型、高密度的集群,如果键空间增长过大并超过空间配额,etcd 的性能将会受到影响。定期维护并处理碎片化的 etcd,以释放数据存储中的空间。监控 Prometheus 以了解 etcd 指标数据,并在需要时对其进行碎片处理;否则,etcd 可能会引发一个集群范围的警报,使集群进入维护模式,仅能接受对键的读和删除操作。

监控这些关键指标:

  • etcd_server_quota_backend_bytes,这是当前配额限制
  • etcd_mvcc_db_total_size_in_use_in_bytes,表示历史压缩后实际数据库使用量
  • etcd_mvcc_db_total_size_in_bytes 显示数据库大小,包括等待碎片整理的可用空间

在导致磁盘碎片的事件后(如 etcd 历史记录紧凑)对 etcd 数据进行清理以回收磁盘空间。

历史压缩将自动每五分钟执行一次,并在后端数据库中造成混乱。此碎片空间可供 etcd 使用,但主机文件系统不可用。您必须对碎片 etcd 进行碎片清除,才能使这个空间可供主机文件系统使用。

碎片清理会自动发生,但您也可以手动触发它。

注意

自动清理碎片非常适合大多数情况,因为 etcd operator 使用集群信息来确定用户最有效的操作。

3.3.1. 自动清理

etcd Operator 自动清理碎片磁盘。不需要人工干预。

查看以下日志之一来验证碎片整理过程是否成功:

  • etcd 日志
  • cluster-etcd-operator pod
  • Operator 状态错误日志
警告

自动清除可能会导致各种 OpenShift 核心组件中的领导选举失败,如 Kubernetes 控制器管理器,这会触发重启失败的组件。重启会有危害,并会触发对下一个正在运行的实例的故障切换,或者组件在重启后再次恢复工作。

成功进行碎片处理的日志输出示例

etcd member has been defragmented: <member_name>, memberID: <member_id>
Copy to Clipboard Toggle word wrap

进行碎片处理失败的日志输出示例

failed defrag on member: <member_name>, memberID: <member_id>: <error_message>
Copy to Clipboard Toggle word wrap

3.3.2. 手动清理

Prometheus 警报指示您需要手动进行碎片处理。该警报在两个情况下显示:

  • 当 etcd 使用超过 50% 的可用空间超过了 10 分钟
  • 当 etcd 活跃使用小于其数据库总大小的 50% 超过了 10 分钟

您还可以通过检查 etcd 数据库大小(MB)来决定是否需要进行碎片整理。通过 PromQL 表达 (etcd_mvcc_db_total_size_in_bytes - etcd_mvcc_db_total_size_in_use_in_bytes)/1024/1024 来释放空间。

警告

分离 etcd 是一个阻止性操作。在进行碎片处理完成前,etcd 成员将没有响应。因此,在每个下一个 pod 要进行碎片清理前,至少等待一分钟,以便集群可以恢复正常工作。

按照以下步骤对每个 etcd 成员上的 etcd 数据进行碎片处理。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 确定哪个 etcd 成员是领导成员,因为领导会进行最后的碎片处理。

    1. 获取 etcd pod 列表:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd -o wide
      Copy to Clipboard Toggle word wrap

      输出示例

      etcd-ip-10-0-159-225.example.redhat.com                3/3     Running     0          175m   10.0.159.225   ip-10-0-159-225.example.redhat.com   <none>           <none>
      etcd-ip-10-0-191-37.example.redhat.com                 3/3     Running     0          173m   10.0.191.37    ip-10-0-191-37.example.redhat.com    <none>           <none>
      etcd-ip-10-0-199-170.example.redhat.com                3/3     Running     0          176m   10.0.199.170   ip-10-0-199-170.example.redhat.com   <none>           <none>
      Copy to Clipboard Toggle word wrap

    2. 选择 pod 并运行以下命令来确定哪个 etcd 成员是领导:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com etcdctl endpoint status --cluster -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      Defaulting container name to etcdctl.
      Use 'oc describe pod/etcd-ip-10-0-159-225.example.redhat.com -n openshift-etcd' to see all of the containers in this pod.
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |         ENDPOINT          |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |  https://10.0.191.37:2379 | 251cd44483d811c3 |   3.5.9 |  104 MB |     false |      false |         7 |      91624 |              91624 |        |
      | https://10.0.159.225:2379 | 264c7c58ecbdabee |   3.5.9 |  104 MB |     false |      false |         7 |      91624 |              91624 |        |
      | https://10.0.199.170:2379 | 9ac311f93915cc79 |   3.5.9 |  104 MB |      true |      false |         7 |      91624 |              91624 |        |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      Copy to Clipboard Toggle word wrap

      基于此输出的 IS LEADER 列,https://10.0.199.170:2379 端点是领导。与上一步输出匹配此端点,领导的 pod 名称为 etcd-ip-10-0-199-170.example.redhat.com

  2. 清理 etcd 成员。

    1. 连接到正在运行的 etcd 容器,传递 不是 领导的 pod 的名称:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com
      Copy to Clipboard Toggle word wrap
    2. 取消设置 ETCDCTL_ENDPOINTS 环境变量:

      sh-4.4# unset ETCDCTL_ENDPOINTS
      Copy to Clipboard Toggle word wrap
    3. 清理 etcd 成员:

      sh-4.4# etcdctl --command-timeout=30s --endpoints=https://localhost:2379 defrag
      Copy to Clipboard Toggle word wrap

      输出示例

      Finished defragmenting etcd member[https://localhost:2379]
      Copy to Clipboard Toggle word wrap

      如果发生超时错误,增加 --command-timeout 的值,直到命令成功为止。

    4. 验证数据库大小是否已缩小:

      sh-4.4# etcdctl endpoint status -w table --cluster
      Copy to Clipboard Toggle word wrap

      输出示例

      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |         ENDPOINT          |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |  https://10.0.191.37:2379 | 251cd44483d811c3 |   3.5.9 |  104 MB |     false |      false |         7 |      91624 |              91624 |        |
      | https://10.0.159.225:2379 | 264c7c58ecbdabee |   3.5.9 |   41 MB |     false |      false |         7 |      91624 |              91624 |        | 
      1
      
      | https://10.0.199.170:2379 | 9ac311f93915cc79 |   3.5.9 |  104 MB |      true |      false |         7 |      91624 |              91624 |        |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      Copy to Clipboard Toggle word wrap

      本例显示这个 etcd 成员的数据库大小现在为 41 MB,而起始大小为 104 MB。

    5. 重复这些步骤以连接到其他 etcd 成员并进行碎片处理。最后才对领导进行碎片清除。

      至少要在碎片处理操作之间等待一分钟,以便 etcd pod 可以恢复。在 etcd pod 恢复前,etcd 成员不会响应。

  3. 如果因为超过空间配额而触发任何 NOSPACE 警告,请清除它们。

    1. 检查是否有 NOSPACE 警告:

      sh-4.4# etcdctl alarm list
      Copy to Clipboard Toggle word wrap

      输出示例

      memberID:12345678912345678912 alarm:NOSPACE
      Copy to Clipboard Toggle word wrap

    2. 清除警告:

      sh-4.4# etcdctl alarm disarm
      Copy to Clipboard Toggle word wrap

3.4. 为 etcd 设置调优参数

您可以将 control plane 硬件速度设置为 "Standard""Slower" 或默认值,即 ""

默认设置允许系统决定使用哪个速度。这个值允许从此功能不存在的版本进行升级,因为系统可以从之前的版本中选择值。

通过选择其中一个其他值,您要覆盖默认值。如果您看到由于超时或丢失了心跳而导致的很多领导选举机制,且您的系统被设置为 """Standard",请将硬件速度设置为 "Slower",使系统能够更好地接受增加延迟。

3.4.1. 更改硬件速度容错

要更改 etcd 的硬件速度容错功能,请完成以下步骤。

流程

  1. 输入以下命令来查看当前值:

    $ oc describe etcd/cluster | grep "Control Plane Hardware Speed"
    Copy to Clipboard Toggle word wrap

    输出示例

    Control Plane Hardware Speed:  <VALUE>
    Copy to Clipboard Toggle word wrap

    注意

    如果输出为空,则未设置该字段,并且应被视为默认值("")。

  2. 输入以下命令来更改值。将 <value> 替换为一个有效值:"""Standard""Slower":

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"controlPlaneHardwareSpeed": "<value>"}}'
    Copy to Clipboard Toggle word wrap

    下表显示了每个配置集的心跳间隔和领导选举超时。这些值可能随时更改。

    Expand

    profile

    ETCD_HEARTBEAT_INTERVAL

    ETCD_LEADER_ELECTION_TIMEOUT

    ""

    根据平台的不同而有所不同

    根据平台的不同而有所不同

    Standard(标准)

    100

    1000

    速度较慢

    500

    2500

  3. 查看输出:

    输出示例

    etcd.operator.openshift.io/cluster patched
    Copy to Clipboard Toggle word wrap

    如果您输入了有效值之外的任何值,则会显示错误输出。例如,如果您以值形式输入 "Faster",输出如下:

    输出示例

    The Etcd "cluster" is invalid: spec.controlPlaneHardwareSpeed: Unsupported value: "Faster": supported values: "", "Standard", "Slower"
    Copy to Clipboard Toggle word wrap

  4. 输入以下命令验证值是否已更改:

    $ oc describe etcd/cluster | grep "Control Plane Hardware Speed"
    Copy to Clipboard Toggle word wrap

    输出示例

    Control Plane Hardware Speed:  ""
    Copy to Clipboard Toggle word wrap

  5. 等待 etcd pod 推出:

    $ oc get pods -n openshift-etcd -w
    Copy to Clipboard Toggle word wrap

    以下输出显示了 master-0 的预期条目。继续之前,等到所有 master 都显示为 4/4 Running

    输出示例

    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     Pending             0          0s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     Pending             0          0s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     ContainerCreating   0          0s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     ContainerCreating   0          1s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           1/1     Running             0          2s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     Completed           0          34s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     Completed           0          36s
    installer-9-ci-ln-qkgs94t-72292-9clnd-master-0           0/1     Completed           0          36s
    etcd-guard-ci-ln-qkgs94t-72292-9clnd-master-0            0/1     Running             0          26m
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  4/4     Terminating         0          11m
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  4/4     Terminating         0          11m
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  0/4     Pending             0          0s
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  0/4     Init:1/3            0          1s
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  0/4     Init:2/3            0          2s
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  0/4     PodInitializing     0          3s
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  3/4     Running             0          4s
    etcd-guard-ci-ln-qkgs94t-72292-9clnd-master-0            1/1     Running             0          26m
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  3/4     Running             0          20s
    etcd-ci-ln-qkgs94t-72292-9clnd-master-0                  4/4     Running             0          20s
    Copy to Clipboard Toggle word wrap

  6. 输入以下命令查看值:

    $ oc describe -n openshift-etcd pod/<ETCD_PODNAME> | grep -e HEARTBEAT_INTERVAL -e ELECTION_TIMEOUT
    Copy to Clipboard Toggle word wrap
    注意

    这些值可能没有从默认值更改。

3.5. 增加 etcd 的数据库大小

您可以为每个 etcd 实例设置 gibibytes (GiB)中的磁盘配额。如果为 etcd 实例设置磁盘配额,您可以指定整数值(从 8 到 32)。默认值为 8。您只能指定增加的值。

如果您遇到 低空间 警报,则可能需要增加磁盘配额。此警报表示尽管进行自动压缩和碎片处理,对于 etcd, 集群太大了。如果您看到此警报,则需要立即增加磁盘配额,因为在 etcd 耗尽空间后,写入会失败。

如果遇到过量数据库增长警告,可能是需要提高磁盘配额的另一个场景是。此警报是一个警告,数据库可能会在接下来的四小时内增长过大。在这种情况下,请考虑增加磁盘配额,以便您最终不会遇到 低空间 警报,以及可能的写入失败问题。

如果您增加磁盘配额,您所指定的磁盘空间不会被立即保留。相反,如果需要,etcd 可能会增大到这个大小。确保 etcd 在专用磁盘上运行,该磁盘大于您为磁盘配额指定的值。

对于大型 etcd 数据库,control plane 节点必须有额外的内存和存储。因为您必须考虑 API 服务器缓存,所以至少是 etcd 数据库配置大小的 3 倍。

重要

为 etcd 增加数据库大小只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

3.5.1. 更改 etcd 数据库大小

要更改 etcd 的数据库大小,请完成以下步骤。

流程

  1. 输入以下命令检查每个 etcd 实例的磁盘配额的当前值:

    $ oc describe etcd/cluster | grep "Backend Quota"
    Copy to Clipboard Toggle word wrap

    输出示例

    Backend Quota Gi B: <value>
    Copy to Clipboard Toggle word wrap

  2. 输入以下命令更改磁盘配额的值:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"backendQuotaGiB": <value>}}'
    Copy to Clipboard Toggle word wrap

    输出示例

    etcd.operator.openshift.io/cluster patched
    Copy to Clipboard Toggle word wrap

验证

  1. 输入以下命令验证是否设置了磁盘配额的新值:

    $ oc describe etcd/cluster | grep "Backend Quota"
    Copy to Clipboard Toggle word wrap

    etcd Operator 会自动使用新值推出 etcd 实例。

  2. 输入以下命令验证 etcd pod 是否正在运行:

    $ oc get pods -n openshift-etcd
    Copy to Clipboard Toggle word wrap

    以下输出显示了预期的条目。

    输出示例

    NAME                                                   READY   STATUS      RESTARTS   AGE
    etcd-ci-ln-b6kfsw2-72292-mzwbq-master-0                4/4     Running     0          39m
    etcd-ci-ln-b6kfsw2-72292-mzwbq-master-1                4/4     Running     0          37m
    etcd-ci-ln-b6kfsw2-72292-mzwbq-master-2                4/4     Running     0          41m
    etcd-guard-ci-ln-b6kfsw2-72292-mzwbq-master-0          1/1     Running     0          51m
    etcd-guard-ci-ln-b6kfsw2-72292-mzwbq-master-1          1/1     Running     0          49m
    etcd-guard-ci-ln-b6kfsw2-72292-mzwbq-master-2          1/1     Running     0          54m
    installer-5-ci-ln-b6kfsw2-72292-mzwbq-master-1         0/1     Completed   0          51m
    installer-7-ci-ln-b6kfsw2-72292-mzwbq-master-0         0/1     Completed   0          46m
    installer-7-ci-ln-b6kfsw2-72292-mzwbq-master-1         0/1     Completed   0          44m
    installer-7-ci-ln-b6kfsw2-72292-mzwbq-master-2         0/1     Completed   0          49m
    installer-8-ci-ln-b6kfsw2-72292-mzwbq-master-0         0/1     Completed   0          40m
    installer-8-ci-ln-b6kfsw2-72292-mzwbq-master-1         0/1     Completed   0          38m
    installer-8-ci-ln-b6kfsw2-72292-mzwbq-master-2         0/1     Completed   0          42m
    revision-pruner-7-ci-ln-b6kfsw2-72292-mzwbq-master-0   0/1     Completed   0          43m
    revision-pruner-7-ci-ln-b6kfsw2-72292-mzwbq-master-1   0/1     Completed   0          43m
    revision-pruner-7-ci-ln-b6kfsw2-72292-mzwbq-master-2   0/1     Completed   0          43m
    revision-pruner-8-ci-ln-b6kfsw2-72292-mzwbq-master-0   0/1     Completed   0          42m
    revision-pruner-8-ci-ln-b6kfsw2-72292-mzwbq-master-1   0/1     Completed   0          42m
    revision-pruner-8-ci-ln-b6kfsw2-72292-mzwbq-master-2   0/1     Completed   0          42m
    Copy to Clipboard Toggle word wrap

  3. 输入以下命令验证 etcd pod 是否更新了磁盘配额值:

    $ oc describe -n openshift-etcd pod/<etcd_podname> | grep "ETCD_QUOTA_BACKEND_BYTES"
    Copy to Clipboard Toggle word wrap

    该值可能没有改变默认值 8

    输出示例

    ETCD_QUOTA_BACKEND_BYTES:                               8589934592
    Copy to Clipboard Toggle word wrap

    注意

    虽然您设置的值以 GiB 为单位的整数,但输出中显示的值将会转换为以字节为单位。

3.5.2. 故障排除

如果您在尝试增加 etcd 数据库大小时遇到问题,则以下故障排除步骤可能会有所帮助。

3.5.2.1. 值太小

如果您指定的值小于 8,您会看到以下出错信息:

$ oc patch etcd/cluster --type=merge -p '{"spec": {"backendQuotaGiB": 5}}'
Copy to Clipboard Toggle word wrap

错误信息示例

The Etcd "cluster" is invalid:
* spec.backendQuotaGiB: Invalid value: 5: spec.backendQuotaGiB in body should be greater than or equal to 8
* spec.backendQuotaGiB: Invalid value: "integer": etcd backendQuotaGiB may not be decreased
Copy to Clipboard Toggle word wrap

要解决这个问题,请指定 832 之间的一个整数值。

3.5.2.2. 值太大

如果您指定的值大于 32,您会看到以下出错信息:

$ oc patch etcd/cluster --type=merge -p '{"spec": {"backendQuotaGiB": 64}}'
Copy to Clipboard Toggle word wrap

错误信息示例

The Etcd "cluster" is invalid: spec.backendQuotaGiB: Invalid value: 64: spec.backendQuotaGiB in body should be less than or equal to 32
Copy to Clipboard Toggle word wrap

要解决这个问题,请指定 832 之间的一个整数值。

3.5.2.3. 值被减少

如果值设为 832 之间的有效值,则无法减少该值。否则,您会看到错误消息。

  1. 输入以下命令来查看当前的值:

    $ oc describe etcd/cluster | grep "Backend Quota"
    Copy to Clipboard Toggle word wrap

    输出示例

    Backend Quota Gi B: 10
    Copy to Clipboard Toggle word wrap

  2. 输入以下命令减少磁盘配额值:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"backendQuotaGiB": 8}}'
    Copy to Clipboard Toggle word wrap

    错误信息示例

    The Etcd "cluster" is invalid: spec.backendQuotaGiB: Invalid value: "integer": etcd backendQuotaGiB may not be decreased
    Copy to Clipboard Toggle word wrap

  3. 要解决这个问题,请指定大于 10 的整数。

第 4 章 备份和恢复 etcd 数据

4.1. 备份和恢复 etcd 数据

作为 OpenShift Container Platform 的键值存储,etcd 会保留所有资源对象的状态。

定期备份集群的 etcd 数据,并将其保存在 OpenShift Container Platform 环境之外的安全位置。不要在第一个证书轮转完成前(安装后的 24 小时内)进行 etcd 备份,否则备份将包含过期的证书。另外,建议您在非高峰期使用 etcd 备份,因为 etcd 快照有较高的 I/O 成本。

在更新集群之前,请务必进行 etcd 备份。在更新前进行备份非常重要,因为在恢复集群时,您必须使用从同一 z-stream 发行版本中获取的 etcd 备份。例如,OpenShift Container Platform 4.17.5 集群必须使用在 4.17.5 中进行的 etcd 备份。

重要

通过在 control plane 主机上执行一次备份脚本来备份集群的 etcd 数据。不要为每个 control plane 主机进行备份。

在进行了 etcd 备份后,就可以恢复到一个以前的集群状态

4.1.1. 备份 etcd 数据

按照以下步骤,通过创建 etcd 快照并备份静态 pod 的资源来备份 etcd 数据。这个备份可以被保存,并在以后需要时使用它来恢复 etcd 数据。

重要

只保存单一 control plane 主机的备份。不要从集群中的每个 control plane 主机进行备份。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您已检查是否启用了集群范围代理。

    提示

    您可以通过查看 oc get proxy cluster -o yaml 的输出来检查代理是否已启用。如果 httpProxyhttpsProxynoProxy 字段设置了值,则会启用代理。

流程

  1. 以 root 用户身份为 control plane 节点启动一个 debug 会话:

    $ oc debug --as-root node/<node_name>
    Copy to Clipboard Toggle word wrap
  2. 在 debug shell 中将根目录改为 /host

    sh-4.4# chroot /host
    Copy to Clipboard Toggle word wrap
  3. 如果启用了集群范围代理,请运行以下命令导出 NO_PROXYHTTP_PROXYHTTPS_PROXY 环境变量:

    $ export HTTP_PROXY=http://<your_proxy.example.com>:8080
    Copy to Clipboard Toggle word wrap
    $ export HTTPS_PROXY=https://<your_proxy.example.com>:8080
    Copy to Clipboard Toggle word wrap
    $ export NO_PROXY=<example.com>
    Copy to Clipboard Toggle word wrap
  4. 在 debug shell 中运行 cluster-backup.sh 脚本,并传递保存备份的位置。

    提示

    cluster-backup.sh 脚本作为 etcd Cluster Operator 的一个组件被维护,它是 etcdctl snapshot save 命令的包装程序(wrapper)。

    sh-4.4# /usr/local/bin/cluster-backup.sh /home/core/assets/backup
    Copy to Clipboard Toggle word wrap

    脚本输出示例

    found latest kube-apiserver: /etc/kubernetes/static-pod-resources/kube-apiserver-pod-6
    found latest kube-controller-manager: /etc/kubernetes/static-pod-resources/kube-controller-manager-pod-7
    found latest kube-scheduler: /etc/kubernetes/static-pod-resources/kube-scheduler-pod-6
    found latest etcd: /etc/kubernetes/static-pod-resources/etcd-pod-3
    ede95fe6b88b87ba86a03c15e669fb4aa5bf0991c180d3c6895ce72eaade54a1
    etcdctl version: 3.4.14
    API version: 3.4
    {"level":"info","ts":1624647639.0188997,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"/home/core/assets/backup/snapshot_2021-06-25_190035.db.part"}
    {"level":"info","ts":"2021-06-25T19:00:39.030Z","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"}
    {"level":"info","ts":1624647639.0301006,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"https://10.0.0.5:2379"}
    {"level":"info","ts":"2021-06-25T19:00:40.215Z","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"}
    {"level":"info","ts":1624647640.6032252,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"https://10.0.0.5:2379","size":"114 MB","took":1.584090459}
    {"level":"info","ts":1624647640.6047094,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"/home/core/assets/backup/snapshot_2021-06-25_190035.db"}
    Snapshot saved at /home/core/assets/backup/snapshot_2021-06-25_190035.db
    {"hash":3866667823,"revision":31407,"totalKey":12828,"totalSize":114446336}
    snapshot db and kube resources are successfully saved to /home/core/assets/backup
    Copy to Clipboard Toggle word wrap

    在这个示例中,在 control plane 主机上的 /home/core/assets/backup/ 目录中创建了两个文件:

    • snapshot_<datetimestamp>.db:这个文件是 etcd 快照。cluster-backup.sh 脚本确认其有效。
    • static_kuberesources_<datetimestamp>.tar.gz:此文件包含静态 pod 的资源。如果启用了 etcd 加密,它也包含 etcd 快照的加密密钥。

      注意

      如果启用了 etcd 加密,建议出于安全考虑,将第二个文件与 etcd 快照分开保存。但是,需要这个文件才能从 etcd 快照中进行恢复。

      请记住,etcd 仅对值进行加密,而不对键进行加密。这意味着资源类型、命名空间和对象名称是不加密的。

4.1.2. 创建自动的 etcd 备份

etcd 的自动备份功能支持重复备份和单一备份。重复备份会创建一个 cron 作业,该作业在每次作业触发时都启动一次备份。

重要

自动 etcd 备份是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

按照以下步骤为 etcd 启用自动备份。

警告

在集群中启用 TechPreviewNoUpgrade 功能集可防止次版本更新。TechPreviewNoUpgrade 功能集无法被禁用。不要在生产环境集群中启用此功能。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您可以访问 OpenShift CLI(oc)。

流程

  1. 使用以下内容创建名为 enable-tech-preview-no-upgrade.yamlFeatureGate 自定义资源 (CR) 文件:

    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster
    spec:
      featureSet: TechPreviewNoUpgrade
    Copy to Clipboard Toggle word wrap
  2. 应用 CR 并启用自动备份:

    $ oc apply -f enable-tech-preview-no-upgrade.yaml
    Copy to Clipboard Toggle word wrap
  3. 启用相关的 API 需要一些时间。运行以下命令,验证自定义资源定义 (CRD) 的创建:

    $ oc get crd | grep backup
    Copy to Clipboard Toggle word wrap

    输出示例

    backups.config.openshift.io 2023-10-25T13:32:43Z
    etcdbackups.operator.openshift.io 2023-10-25T13:32:04Z
    Copy to Clipboard Toggle word wrap

4.1.2.1. 创建单个自动 etcd 备份

按照以下步骤,通过创建并应用自定义资源 (CR) 来创建单个 etcd 备份。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您可以访问 OpenShift CLI(oc)。

流程

  • 如果动态置备的存储可用,请完成以下步骤以创建单个自动 etcd 备份:

    1. 创建名为 etcd-backup-pvc.yaml 的持久性卷声明 (PVC),其内容如下:

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: etcd-backup-pvc
        namespace: openshift-etcd
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 200Gi 
      1
      
        volumeMode: Filesystem
      Copy to Clipboard Toggle word wrap
      1 1
      PVC 可用的存储量。根据您的要求调整这个值。
    2. 运行以下命令来应用 PVC:

      $ oc apply -f etcd-backup-pvc.yaml
      Copy to Clipboard Toggle word wrap
    3. 运行以下命令验证 PVC 的创建:

      $ oc get pvc
      Copy to Clipboard Toggle word wrap

      输出示例

      NAME              STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
      etcd-backup-pvc   Bound                                                       51s
      Copy to Clipboard Toggle word wrap

      注意

      动态 PVC 处于 Pending 状态,直到它们被挂载为止。

    4. 创建名为 etcd-single-backup.yaml 的 CR 文件,其内容如下:

      apiVersion: operator.openshift.io/v1alpha1
      kind: EtcdBackup
      metadata:
        name: etcd-single-backup
        namespace: openshift-etcd
      spec:
        pvcName: etcd-backup-pvc 
      1
      Copy to Clipboard Toggle word wrap
      1
      保存备份的 PVC 名称。根据您的环境调整这个值。
    5. 应用 CR 以启动单个备份:

      $ oc apply -f etcd-single-backup.yaml
      Copy to Clipboard Toggle word wrap
  • 如果动态置备的存储不可用,请完成以下步骤来创建单个自动 etcd 备份:

    1. 创建名为 etcd-backup-local-storage.yamlStorageClass CR 文件,其内容如下:

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: etcd-backup-local-storage
      provisioner: kubernetes.io/no-provisioner
      volumeBindingMode: Immediate
      Copy to Clipboard Toggle word wrap
    2. 运行以下命令来应用 StorageClass CR:

      $ oc apply -f etcd-backup-local-storage.yaml
      Copy to Clipboard Toggle word wrap
    3. 创建名为 etcd-backup-pv-fs.yaml 的 PV,其内容类似以下示例:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: etcd-backup-pv-fs
      spec:
        capacity:
          storage: 100Gi 
      1
      
        volumeMode: Filesystem
        accessModes:
        - ReadWriteOnce
        persistentVolumeReclaimPolicy: Retain
        storageClassName: etcd-backup-local-storage
        local:
          path: /mnt
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
            - key: kubernetes.io/hostname
               operator: In
               values:
               - <example_master_node> 
      2
      Copy to Clipboard Toggle word wrap
      1
      PV 可用的存储量。根据您的要求调整这个值。
      2
      将此值替换为将此 PV 附加到的节点。
    4. 运行以下命令验证 PV 的创建:

      $ oc get pv
      Copy to Clipboard Toggle word wrap

      输出示例

      NAME                    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS                REASON   AGE
      etcd-backup-pv-fs       100Gi      RWO            Retain           Available           etcd-backup-local-storage            10s
      Copy to Clipboard Toggle word wrap

    5. 创建名为 etcd-backup-pvc.yaml 的 PVC,其内容如下:

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: etcd-backup-pvc
        namespace: openshift-etcd
      spec:
        accessModes:
        - ReadWriteOnce
        volumeMode: Filesystem
        resources:
          requests:
            storage: 10Gi 
      1
      Copy to Clipboard Toggle word wrap
      1
      PVC 可用的存储量。根据您的要求调整这个值。
    6. 运行以下命令来应用 PVC:

      $ oc apply -f etcd-backup-pvc.yaml
      Copy to Clipboard Toggle word wrap
    7. 创建名为 etcd-single-backup.yaml 的 CR 文件,其内容如下:

      apiVersion: operator.openshift.io/v1alpha1
      kind: EtcdBackup
      metadata:
        name: etcd-single-backup
        namespace: openshift-etcd
      spec:
        pvcName: etcd-backup-pvc 
      1
      Copy to Clipboard Toggle word wrap
      1
      将备份保存到的持久性卷声明 (PVC) 的名称。根据您的环境调整这个值。
    8. 应用 CR 以启动单个备份:

      $ oc apply -f etcd-single-backup.yaml
      Copy to Clipboard Toggle word wrap
4.1.2.2. 创建重复自动化 etcd 备份

按照以下步骤创建自动重复备份 etcd。

如果可能,使用动态置备的存储将创建的 etcd 备份数据保存在安全的外部位置。如果动态置备的存储不可用,请考虑将备份数据存储在 NFS 共享上,以便更易访问备份恢复。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您可以访问 OpenShift CLI(oc)。

流程

  1. 如果动态置备的存储可用,请完成以下步骤来创建自动重复备份:

    1. 创建名为 etcd-backup-pvc.yaml 的持久性卷声明 (PVC),其内容如下:

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: etcd-backup-pvc
        namespace: openshift-etcd
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 200Gi 
      1
      
        volumeMode: Filesystem
        storageClassName: etcd-backup-local-storage
      Copy to Clipboard Toggle word wrap
      1
      PVC 可用的存储量。根据您的要求调整这个值。
      注意

      每个供应商都需要更改 accessModesstorageClassName 密钥:

      Expand
      供应商accessModesstorageClassName value

      带有 versioned-installer-efc_operator-ci 配置集的 AWS

      - ReadWriteMany

      efs-sc

      Google Cloud Platform

      - ReadWriteMany

      filestore-csi

      Microsoft Azure

      - ReadWriteMany

      azurefile-csi

    2. 运行以下命令来应用 PVC:

      $ oc apply -f etcd-backup-pvc.yaml
      Copy to Clipboard Toggle word wrap
    3. 运行以下命令验证 PVC 的创建:

      $ oc get pvc
      Copy to Clipboard Toggle word wrap

      输出示例

      NAME              STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
      etcd-backup-pvc   Bound                                                       51s
      Copy to Clipboard Toggle word wrap

      注意

      动态 PVC 处于 Pending 状态,直到它们被挂载为止。

  2. 如果动态置备的存储不可用,请完成以下步骤来创建本地存储 PVC:

    警告

    如果您删除或丢失对包含存储备份数据的节点的访问,可能会丢失数据。

    1. 创建名为 etcd-backup-local-storage.yamlStorageClass CR 文件,其内容如下:

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: etcd-backup-local-storage
      provisioner: kubernetes.io/no-provisioner
      volumeBindingMode: Immediate
      Copy to Clipboard Toggle word wrap
    2. 运行以下命令来应用 StorageClass CR:

      $ oc apply -f etcd-backup-local-storage.yaml
      Copy to Clipboard Toggle word wrap
    3. 从应用的 StorageClass 中创建一个名为 etcd-backup-pv-fs.yaml 的 PV,其内容类似以下示例:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: etcd-backup-pv-fs
      spec:
        capacity:
          storage: 100Gi 
      1
      
        volumeMode: Filesystem
        accessModes:
        - ReadWriteMany
        persistentVolumeReclaimPolicy: Delete
        storageClassName: etcd-backup-local-storage
        local:
          path: /mnt/
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - <example_master_node> 
      2
      Copy to Clipboard Toggle word wrap
      1
      PV 可用的存储量。根据您的要求调整这个值。
      2
      将这个值替换为要附加此 PV 的 master 节点。
      提示

      运行以下命令来列出可用的节点:

      $ oc get nodes
      Copy to Clipboard Toggle word wrap
    4. 运行以下命令验证 PV 的创建:

      $ oc get pv
      Copy to Clipboard Toggle word wrap

      输出示例

      NAME                    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS                REASON   AGE
      etcd-backup-pv-fs       100Gi      RWX            Delete           Available           etcd-backup-local-storage            10s
      Copy to Clipboard Toggle word wrap

    5. 创建名为 etcd-backup-pvc.yaml 的 PVC,其内容如下:

      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: etcd-backup-pvc
      spec:
        accessModes:
        - ReadWriteMany
        volumeMode: Filesystem
        resources:
          requests:
            storage: 10Gi 
      1
      
        storageClassName: etcd-backup-local-storage
      Copy to Clipboard Toggle word wrap
      1
      PVC 可用的存储量。根据您的要求调整这个值。
    6. 运行以下命令来应用 PVC:

      $ oc apply -f etcd-backup-pvc.yaml
      Copy to Clipboard Toggle word wrap
  3. 创建名为 etcd-recurring-backups.yaml 的自定义资源定义 (CRD) 文件。创建的 CRD 的内容定义自动备份的调度和保留类型。

    • 对于带有 15 个保留备份的 RetentionNumber 的默认保留类型,请使用类似以下示例的内容:

      apiVersion: config.openshift.io/v1alpha1
      kind: Backup
      metadata:
        name: etcd-recurring-backup
      spec:
        etcd:
          schedule: "20 4 * * *" 
      1
      
          timeZone: "UTC"
          pvcName: etcd-backup-pvc
      Copy to Clipboard Toggle word wrap
      1
      用于重复备份的 CronTab 调度。根据您的需要调整这个值。
    • 要使用基于最大备份数的保留,请在 etcd 键中添加以下键值对:

      spec:
        etcd:
          retentionPolicy:
            retentionType: RetentionNumber 
      1
      
            retentionNumber:
              maxNumberOfBackups: 5 
      2
      Copy to Clipboard Toggle word wrap
      1
      保留类型。如果未指定,则默认为 RetentionNumber
      2
      要保留的最大备份数量。根据您的需要调整这个值。如果未指定,则默认为保留 15 个备份。
      警告

      已知问题会导致保留备份的数量大于配置的值。

    • 要根据备份的文件大小保留,请使用:

      spec:
        etcd:
          retentionPolicy:
            retentionType: RetentionSize
            retentionSize:
              maxSizeOfBackupsGb: 20 
      1
      Copy to Clipboard Toggle word wrap
      1
      以 GB 为单位保留备份的最大文件大小。根据您的需要调整这个值。如果未指定,则默认为 10 GB。
      警告

      已知问题会导致保留备份的最大大小超过配置的值 10 GB。

  4. 运行以下命令,创建 CRD 定义的 cron 作业:

    $ oc create -f etcd-recurring-backup.yaml
    Copy to Clipboard Toggle word wrap
  5. 要查找创建的 cron 任务,请运行以下命令:

    $ oc get cronjob -n openshift-etcd
    Copy to Clipboard Toggle word wrap

4.2. 替换不健康的 etcd 成员

替换单个不健康的 etcd 成员的过程取决于 etcd 成员是否不健康(因为机器没有运行或节点未就绪,或者 etcd pod 处于 crashlooping 状态)。

注意

如果您丢失了大多数 control plane 主机,请按照灾难恢复流程恢复到以前的一个集群状态,而不是这个过程。

如果 control plane 证书在被替换的成员中无效,则必须遵循从已过期 control plane 证书中恢复的步骤,而不是此过程。

如果 control plane 节点丢失并且创建了一个新节点,etcd 集群 Operator 将处理生成新 TLS 证书并将节点添加为 etcd 成员。

4.2.1. 找出一个不健康的 etcd 成员

您可以识别集群是否有不健康的 etcd 成员。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已进行 etcd 备份。如需更多信息,请参阅"恢复 etcd 数据"。

流程

  1. 使用以下命令检查 EtcdMembersAvailable 状态条件的状态:

    $ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="EtcdMembersAvailable")]}{.message}{"\n"}{end}'
    Copy to Clipboard Toggle word wrap
  2. 查看输出:

    2 of 3 members are available, ip-10-0-131-183.ec2.internal is unhealthy
    Copy to Clipboard Toggle word wrap

    这个示例输出显示 ip-10-0-131-183.ec2.internal etcd 成员不健康。

4.2.2. 确定不健康的 etcd 成员的状态

替换不健康 etcd 成员的步骤取决于 etcd 的以下状态:

  • 机器没有运行或者该节点未就绪
  • etcd pod 处于 crashlooping 状态

此流程决定了 etcd 成员处于哪个状态。这可让您了解替换不健康的 etcd 成员要遵循的步骤。

注意

如果您知道机器没有运行或节点未就绪,但它们应该很快返回健康状态,那么您就不需要执行替换 etcd 成员的流程。当机器或节点返回一个健康状态时,etcd cluster Operator 将自动同步。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您已找到不健康的 etcd 成员。

流程

  1. 检查 机器是否没有运行:

    $ oc get machines -A -ojsonpath='{range .items[*]}{@.status.nodeRef.name}{"\t"}{@.status.providerStatus.instanceState}{"\n"}' | grep -v running
    Copy to Clipboard Toggle word wrap

    输出示例

    ip-10-0-131-183.ec2.internal  stopped 
    1
    Copy to Clipboard Toggle word wrap

    1
    此输出列出了节点以及节点机器的状态。如果状态不是 running则代表机器没有运行

    如果机器没有运行,按照替换机器没有运行或节点没有就绪的非健康 etcd 成员过程进行操作。

  2. 确定 节点是否未就绪

    如果以下任何一种情况是正确的,则代表节点没有就绪

    • 如果机器正在运行,检查节点是否不可访问:

      $ oc get nodes -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{"\t"}{range .spec.taints[*]}{.key}{" "}' | grep unreachable
      Copy to Clipboard Toggle word wrap

      输出示例

      ip-10-0-131-183.ec2.internal	node-role.kubernetes.io/master node.kubernetes.io/unreachable node.kubernetes.io/unreachable 
      1
      Copy to Clipboard Toggle word wrap

      1
      如果节点带有 unreachable 污点,则节点没有就绪
    • 如果该节点仍然可访问,则检查该节点是否列为 NotReady:

      $ oc get nodes -l node-role.kubernetes.io/master | grep "NotReady"
      Copy to Clipboard Toggle word wrap

      输出示例

      ip-10-0-131-183.ec2.internal   NotReady   master   122m   v1.32.3 
      1
      Copy to Clipboard Toggle word wrap

      1
      如果节点列表为 NotReady,则 该节点没有就绪

    如果节点没有就绪,按照替换机器没有运行或节点没有就绪的 etcd 成员的步骤进行操作。

  3. 确定 etcd Pod 是否处于 crashlooping 状态

    如果机器正在运行并且节点已就绪,请检查 etcd pod 是否处于 crashlooping 状态。

    1. 验证所有 control plane 节点都列为 Ready

      $ oc get nodes -l node-role.kubernetes.io/master
      Copy to Clipboard Toggle word wrap

      输出示例

      NAME                           STATUS   ROLES    AGE     VERSION
      ip-10-0-131-183.ec2.internal   Ready    master   6h13m   v1.32.3
      ip-10-0-164-97.ec2.internal    Ready    master   6h13m   v1.32.3
      ip-10-0-154-204.ec2.internal   Ready    master   6h13m   v1.32.3
      Copy to Clipboard Toggle word wrap

    2. 检查 etcd pod 的状态是否为 ErrorCrashLoopBackOff:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd
      Copy to Clipboard Toggle word wrap

      输出示例

      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
      Copy to Clipboard Toggle word wrap

      1
      由于此 pod 的状态是 Error,因此 etcd pod 为 crashlooping 状态

    如果 etcd pod 为 crashlooping 状态,请按照替换 etcd pod 处于 crashlooping 状态的不健康的 etcd 成员的步骤进行操作。

4.2.3. 替换不健康的 etcd 成员

根据不健康的 etcd 成员的状态,使用以下一个流程:

  • 替换机器没有运行或节点未就绪的不健康 etcd 成员
  • 在不健康集群中安装主 control plane 节点
  • 替换其 etcd Pod 处于 crashlooping 状态的不健康 etcd 成员
  • 替换不健康的裸机 etcd 成员

此流程详细介绍了替换因机器没有运行或节点未就绪造成不健康的 etcd 成员的步骤。

注意

如果您的集群使用 control plane 机器集,请参阅"为 etcd 恢复 control plane 机器集"中的"恢复降级的 etcd Operator"。

先决条件

  • 您已找出不健康的 etcd 成员。
  • 您已确认机器没有运行,或者该节点未就绪。

    重要

    您必须等待其他 control plane 节点关闭。control plane 节点必须保持关闭状态,直到替换完不健康的 etcd 成员为止。

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已进行 etcd 备份。

    重要

    在执行此步骤前,进行 etcd 备份,以便在遇到任何问题时可以恢复集群。

流程

  1. 删除不健康的成员。

    1. 选择一个不在受影响节点上的 pod:

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd
      Copy to Clipboard Toggle word wrap

      输出示例

      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
      Copy to Clipboard Toggle word wrap

    2. 连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
      Copy to Clipboard Toggle word wrap
    3. 查看成员列表:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+------------------------------+---------------------------+---------------------------+
      |        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 |
      +------------------+---------+------------------------------+---------------------------+---------------------------+
      Copy to Clipboard Toggle word wrap

      记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。$ etcdctl endpoint health 命令将列出已删除的成员,直到完成替换过程并添加了新成员。

    4. 通过向 etcdctl member remove 命令提供 ID 来删除不健康的 etcd 成员 :

      sh-4.2# etcdctl member remove 6fc1e7c9db35841d
      Copy to Clipboard Toggle word wrap

      输出示例

      Member 6fc1e7c9db35841d removed from cluster ead669ce1fbfb346
      Copy to Clipboard Toggle word wrap

    5. 再次查看成员列表,并确认成员已被删除:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+------------------------------+---------------------------+---------------------------+
      |        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 |
      +------------------+---------+------------------------------+---------------------------+---------------------------+
      Copy to Clipboard Toggle word wrap

      现在您可以退出节点 shell。

  2. 输入以下命令关闭仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
    Copy to Clipboard Toggle word wrap

    此命令可确保您可以成功重新创建机密并推出静态 pod。

    重要

    关闭仲裁保护后,在剩余的 etcd 实例进行重启以使配置改变生效期间,集群可能无法访问。

    注意

    在只使用两个成员运行时,etcd 将无法容忍任何成员失败。重启剩余的成员会破坏仲裁,并导致集群出现停机问题。由于可能导致停机的配置更改,仲裁保护可以防止 etcd 重启,因此必须禁用它才能完成这个过程。

  3. 运行以下命令来删除受影响的节点:

    $ oc delete node <node_name>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ oc delete node ip-10-0-131-183.ec2.internal
    Copy to Clipboard Toggle word wrap

  4. 删除已删除的不健康 etcd 成员的旧 secret。

    1. 列出已删除的不健康 etcd 成员的 secret。

      $ oc get secrets -n openshift-etcd | grep ip-10-0-131-183.ec2.internal 
      1
      Copy to Clipboard Toggle word wrap
      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
      Copy to Clipboard Toggle word wrap

    2. 删除已删除的不健康 etcd 成员的 secret。

      1. 删除 peer(对等)secret:

        $ oc delete secret -n openshift-etcd etcd-peer-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
      2. 删除 serving secret:

        $ oc delete secret -n openshift-etcd etcd-serving-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
      3. 删除 metrics secret:

        $ oc delete secret -n openshift-etcd etcd-serving-metrics-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
  5. 输入以下命令检查 control plane 机器集是否存在:

    $ oc -n openshift-machine-api get controlplanemachineset
    Copy to Clipboard Toggle word wrap
    • 如果 control plane 机器集存在,则删除并重新创建 control plane 机器。重新创建此机器后,会强制一个新修订版本并自动扩展 etcd。如需更多信息,请参阅"替换没有运行或节点未就绪"的不健康 etcd 成员"。

      如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建控制平面节点时使用的相同方法创建新的控制平面。

      1. 获取不健康成员的机器。

        在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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
        Copy to Clipboard Toggle word wrap

        1
        这是不健康节点的 control plane 机器 ip-10-0-131-183.ec2.internal
      2. 删除不健康成员的机器:

        $ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 
        1
        Copy to Clipboard Toggle word wrap
        1
        为不健康的节点指定 control plane 机器的名称。

        删除不健康成员机器后会自动置备新机器。

      3. 验证新机器是否已创建:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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
        Copy to Clipboard Toggle word wrap

        1
        新机器 clustername-8qw5l-master-3 将被创建,并当阶段从 Provisioning 变为 Running 后就可以使用。

        创建新机器可能需要几分钟时间。当机器或节点返回健康状态时,etcd 集群 Operator 会自动同步。

        注意

        验证您用于机器集的子网 ID,以确保它们最终在正确的可用区中。

    • 如果 control plane 机器集不存在,请删除和重新创建 control plane 机器。重新创建此机器后,会强制一个新修订版本并自动扩展 etcd。

      如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建控制平面节点时使用的相同方法创建新的控制平面。

      1. 获取不健康成员的机器。

        在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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
        Copy to Clipboard Toggle word wrap

        1
        这是不健康节点的 control plane 机器 ip-10-0-131-183.ec2.internal
      2. 将机器配置保存到文件系统中的一个文件中:

        $ oc get machine clustername-8qw5l-master-0 \ 
        1
        
            -n openshift-machine-api \
            -o yaml \
            > new-master-machine.yaml
        Copy to Clipboard Toggle word wrap
        1
        为不健康的节点指定 control plane 机器的名称。
      3. 编辑上一步中创建的 new-master-machine.yaml 文件,以分配新名称并删除不必要的字段。

        1. 删除整个 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
          Copy to Clipboard Toggle word wrap
        2. metadata.name 字段更改为新名称。

          保留与旧机器相同的基础名称,并将结尾的号更改为下一个可用数字。在本例中,clustername-8qw5l-master-0 改为 clustername-8qw5l-master-3

          例如:

          apiVersion: machine.openshift.io/v1beta1
          kind: Machine
          metadata:
            ...
            name: clustername-8qw5l-master-3
            ...
          Copy to Clipboard Toggle word wrap
        3. 删除 spec.providerID 字段:

            providerID: aws:///us-east-1a/i-0fdb85790d76d0c3f
          Copy to Clipboard Toggle word wrap
      4. 删除不健康成员的机器:

        $ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 
        1
        Copy to Clipboard Toggle word wrap
        1
        为不健康的节点指定 control plane 机器的名称。
      5. 验证机器是否已删除:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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
        Copy to Clipboard Toggle word wrap

      6. 使用 new-master-machine.yaml 文件创建新机器:

        $ oc apply -f new-master-machine.yaml
        Copy to Clipboard Toggle word wrap
      7. 验证新机器是否已创建:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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
        Copy to Clipboard Toggle word wrap

        1
        新机器 clustername-8qw5l-master-3 将被创建,并当阶段从 Provisioning 变为 Running 后就可以使用。

        创建新机器可能需要几分钟时间。当机器或节点返回健康状态时,etcd 集群 Operator 会自动同步。

  6. 输入以下命令重新打开仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
    Copy to Clipboard Toggle word wrap
  7. 您可以输入以下命令验证 unsupportedConfigOverrides 部分是否已从对象中删除:

    $ oc get etcd/cluster -oyaml
    Copy to Clipboard Toggle word wrap
  8. 如果使用单节点 OpenShift,请重启该节点。否则,您可能会在 etcd 集群 Operator 中遇到以下错误:

    输出示例

    EtcdCertSignerControllerDegraded: [Operation cannot be fulfilled on secrets "etcd-peer-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-metrics-sno-0": the object has been modified; please apply your changes to the latest version and try again]
    Copy to Clipboard Toggle word wrap

验证

  1. 验证所有 etcd pod 是否都正常运行。

    在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc -n openshift-etcd get pods -l k8s-app=etcd
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    Copy to Clipboard Toggle word wrap

    如果上一命令的输出只列出两个 pod,您可以手动强制重新部署 etcd。在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 
    1
    Copy to Clipboard Toggle word wrap
    1
    forceRedeploymentReason 值必须是唯一的,这就是为什么附加时间戳的原因。
  2. 验证只有三个 etcd 成员。

    1. 连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
      Copy to Clipboard Toggle word wrap
    2. 查看成员列表:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+------------------------------+---------------------------+---------------------------+
      |        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 |
      +------------------+---------+------------------------------+---------------------------+---------------------------+
      Copy to Clipboard Toggle word wrap

      如果上一命令的输出列出了超过三个 etcd 成员,您必须删除不需要的成员。

      警告

      确保删除正确的 etcd 成员;如果删除了正常的 etcd 成员则有可能会导致仲裁丢失。

此流程详细介绍了替换因 etcd pod 处于 crashlooping 状态造成不健康的 etcd 成员的步骤。

先决条件

  • 您已找出不健康的 etcd 成员。
  • 已确认 etcd pod 处于 crashlooping 状态。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已进行 etcd 备份。

    重要

    执行此流程前务必要进行 etcd 备份,以便在遇到任何问题时可以恢复集群。

流程

  1. 停止处于 crashlooping 状态的 etcd pod。

    1. 对处于 crashlooping 状态的节点进行调试。

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc debug node/ip-10-0-131-183.ec2.internal 
      1
      Copy to Clipboard Toggle word wrap
      1
      使用不健康节点的名称来替换它。
    2. 将您的根目录改为 /host

      sh-4.2# chroot /host
      Copy to Clipboard Toggle word wrap
    3. 将现有 etcd pod 文件从 Kubelet 清单目录中移出:

      sh-4.2# mkdir /var/lib/etcd-backup
      Copy to Clipboard Toggle word wrap
      sh-4.2# mv /etc/kubernetes/manifests/etcd-pod.yaml /var/lib/etcd-backup/
      Copy to Clipboard Toggle word wrap
    4. 将 etcd 数据目录移到不同的位置:

      sh-4.2# mv /var/lib/etcd/ /tmp
      Copy to Clipboard Toggle word wrap

      现在您可以退出节点 shell。

  2. 删除不健康的成员。

    1. 选择一个不在受影响节点上的 pod。

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd
      Copy to Clipboard Toggle word wrap

      输出示例

      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
      Copy to Clipboard Toggle word wrap

    2. 连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称。

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
      Copy to Clipboard Toggle word wrap
    3. 查看成员列表:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+------------------------------+---------------------------+---------------------------+
      |        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 |
      +------------------+---------+------------------------------+---------------------------+---------------------------+
      Copy to Clipboard Toggle word wrap

      记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。

    4. 通过向 etcdctl member remove 命令提供 ID 来删除不健康的 etcd 成员 :

      sh-4.2# etcdctl member remove 62bcf33650a7170a
      Copy to Clipboard Toggle word wrap

      输出示例

      Member 62bcf33650a7170a removed from cluster ead669ce1fbfb346
      Copy to Clipboard Toggle word wrap

    5. 再次查看成员列表,并确认成员已被删除:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+------------------------------+---------------------------+---------------------------+
      |        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 |
      +------------------+---------+------------------------------+---------------------------+---------------------------+
      Copy to Clipboard Toggle word wrap

      现在您可以退出节点 shell。

  3. 输入以下命令关闭仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
    Copy to Clipboard Toggle word wrap

    此命令可确保您可以成功重新创建机密并推出静态 pod。

  4. 删除已删除的不健康 etcd 成员的旧 secret。

    1. 列出已删除的不健康 etcd 成员的 secret。

      $ oc get secrets -n openshift-etcd | grep ip-10-0-131-183.ec2.internal 
      1
      Copy to Clipboard Toggle word wrap
      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
      Copy to Clipboard Toggle word wrap

    2. 删除已删除的不健康 etcd 成员的 secret。

      1. 删除 peer(对等)secret:

        $ oc delete secret -n openshift-etcd etcd-peer-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
      2. 删除 serving secret:

        $ oc delete secret -n openshift-etcd etcd-serving-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
      3. 删除 metrics secret:

        $ oc delete secret -n openshift-etcd etcd-serving-metrics-ip-10-0-131-183.ec2.internal
        Copy to Clipboard Toggle word wrap
  5. 强制 etcd 重新部署。

    在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "single-master-recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 
    1
    Copy to Clipboard Toggle word wrap
    1
    forceRedeploymentReason 值必须是唯一的,这就是为什么附加时间戳的原因。

    当 etcd 集群 Operator 执行重新部署时,它会确保所有 control plane 节点都有可正常工作的 etcd pod。

  6. 输入以下命令重新打开仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
    Copy to Clipboard Toggle word wrap
  7. 您可以输入以下命令验证 unsupportedConfigOverrides 部分是否已从对象中删除:

    $ oc get etcd/cluster -oyaml
    Copy to Clipboard Toggle word wrap
  8. 如果使用单节点 OpenShift,请重启该节点。否则,您可能会在 etcd 集群 Operator 中遇到以下错误:

    输出示例

    EtcdCertSignerControllerDegraded: [Operation cannot be fulfilled on secrets "etcd-peer-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-metrics-sno-0": the object has been modified; please apply your changes to the latest version and try again]
    Copy to Clipboard Toggle word wrap

验证

  • 确认新成员可用且健康。

    1. 连接到正在运行的 etcd 容器。

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc rsh -n openshift-etcd etcd-ip-10-0-154-204.ec2.internal
      Copy to Clipboard Toggle word wrap
    2. 验证所有成员是否健康:

      sh-4.2# etcdctl endpoint health
      Copy to Clipboard Toggle word wrap

      输出示例

      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
      Copy to Clipboard Toggle word wrap

此流程详细介绍了替换因机器没有运行或节点未就绪造成不健康的裸机 etcd 成员的步骤。

如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行。否则,您必须使用最初创建控制平面节点时使用的相同方法创建新的控制平面。

先决条件

  • 您已找出不健康的裸机 etcd 成员。
  • 您已确认机器没有运行,或者该节点未就绪。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已进行 etcd 备份。

    重要

    执行此流程前务必要进行 etcd 备份,以便在遇到任何问题时可以恢复集群。

流程

  1. 验证并删除不健康的成员。

    1. 选择一个不在受影响节点上的 pod:

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd -o wide
      Copy to Clipboard Toggle word wrap

      输出示例

      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>
      Copy to Clipboard Toggle word wrap

    2. 连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称:

      在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

      $ oc rsh -n openshift-etcd etcd-openshift-control-plane-0
      Copy to Clipboard Toggle word wrap
    3. 查看成员列表:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+--------------------+---------------------------+---------------------------+---------------------+
      | 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 |
      +------------------+---------+--------------------+---------------------------+---------------------------+---------------------+
      Copy to Clipboard Toggle word wrap

      记录不健康的 etcd 成员的 ID 和名称,因为稍后需要这些值。etcdctl endpoint health 命令将列出已删除的成员,直到完成替换过程并添加了新成员。

    4. 通过向 etcdctl member remove 命令提供 ID 来删除不健康的 etcd 成员 :

      警告

      确保删除正确的 etcd 成员;如果删除了正常的 etcd 成员则有可能会导致仲裁丢失。

      sh-4.2# etcdctl member remove 7a8197040a5126c8
      Copy to Clipboard Toggle word wrap

      输出示例

      Member 7a8197040a5126c8 removed from cluster b23536c33f2cdd1b
      Copy to Clipboard Toggle word wrap

    5. 再次查看成员列表,并确认成员已被删除:

      sh-4.2# etcdctl member list -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+
      | ID               | STATUS  | NAME                      | PEER ADDRS                  | CLIENT ADDRS                | IS LEARNER |
      +------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+
      | cc3830a72fc357f9 | 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 |
      +------------------+---------+--------------------+---------------------------+---------------------------+-------------------------+
      Copy to Clipboard Toggle word wrap

      现在您可以退出节点 shell。

      重要

      删除成员后,在剩余的 etcd 实例重启时,集群可能无法访问。

  2. 输入以下命令关闭仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
    Copy to Clipboard Toggle word wrap

    此命令可确保您可以成功重新创建机密并推出静态 pod。

  3. 运行以下命令,删除已删除的不健康 etcd 成员的旧 secret。

    1. 列出已删除的不健康 etcd 成员的 secret。

      $ oc get secrets -n openshift-etcd | grep openshift-control-plane-2
      Copy to Clipboard Toggle word wrap

      传递您之前在这个过程中记录的不健康 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
      Copy to Clipboard Toggle word wrap
    2. 删除已删除的不健康 etcd 成员的 secret。

      1. 删除 peer(对等)secret:

        $ oc delete secret etcd-peer-openshift-control-plane-2 -n openshift-etcd
        
        secret "etcd-peer-openshift-control-plane-2" deleted
        Copy to Clipboard Toggle word wrap
      2. 删除 serving secret:

        $ oc delete secret etcd-serving-metrics-openshift-control-plane-2 -n openshift-etcd
        
        secret "etcd-serving-metrics-openshift-control-plane-2" deleted
        Copy to Clipboard Toggle word wrap
      3. 删除 metrics secret:

        $ oc delete secret etcd-serving-openshift-control-plane-2 -n openshift-etcd
        
        secret "etcd-serving-openshift-control-plane-2" deleted
        Copy to Clipboard Toggle word wrap
  4. 获取不健康成员的机器。

    在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc get machines -n openshift-machine-api -o wide
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    Copy to Clipboard Toggle word wrap

    1
    这是不健康节点的 control plane 机器,examplecluster-control-plane-2
  5. 运行以下命令,确保 Bare Metal Operator 可用:

    $ oc get clusteroperator baremetal
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME        VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE   MESSAGE
    baremetal   4.19.0    True        False         False      3d15h
    Copy to Clipboard Toggle word wrap

  6. 运行以下命令来删除旧的 BareMetalHost 对象:

    $ oc delete bmh openshift-control-plane-2 -n openshift-machine-api
    Copy to Clipboard Toggle word wrap

    输出示例

    baremetalhost.metal3.io "openshift-control-plane-2" deleted
    Copy to Clipboard Toggle word wrap

  7. 运行以下命令来删除不健康成员的机器:

    $ oc delete machine -n openshift-machine-api examplecluster-control-plane-2
    Copy to Clipboard Toggle word wrap

    删除 BareMetalHostMachine 对象后,Machine Controller 会自动删除 Node 对象。

    如果删除机器因任何原因或者命令被移动而延迟而延迟而延迟,您可以通过删除机器对象终结器字段来强制删除。

    重要

    不要通过按 Ctrl+c 中断机器删除。您必须允许命令继续完成。打开一个新的终端窗口来编辑并删除 finalizer 字段。

    删除不健康成员机器后会自动置备新机器。

    1. 运行以下命令来编辑机器配置:

      $ oc edit machine -n openshift-machine-api examplecluster-control-plane-2
      Copy to Clipboard Toggle word wrap
    2. 删除 Machine 自定义资源中的以下字段,然后保存更新的文件:

      finalizers:
      - machine.machine.openshift.io
      Copy to Clipboard Toggle word wrap

      输出示例

      machine.machine.openshift.io/examplecluster-control-plane-2 edited
      Copy to Clipboard Toggle word wrap

  8. 运行以下命令验证机器是否已删除:

    $ oc get machines -n openshift-machine-api -o wide
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    Copy to Clipboard Toggle word wrap

  9. 运行以下命令验证节点是否已删除:

    $ oc get nodes
    
    NAME                     STATUS ROLES   AGE   VERSION
    openshift-control-plane-0 Ready master 3h24m v1.32.3
    openshift-control-plane-1 Ready master 3h24m v1.32.3
    openshift-compute-0       Ready worker 176m v1.32.3
    openshift-compute-1       Ready worker 176m v1.32.3
    Copy to Clipboard Toggle word wrap
  10. 创建新的 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/disk/by-id/scsi-<serial_number>
      userData:
        name: master-user-data-managed
        namespace: openshift-machine-api
    EOF
    Copy to Clipboard Toggle word wrap
    注意

    用户名和密码可从其他裸机主机的 secret 中找到。bmc:address 中使用的协议可以从其他 bmh 对象获取。

    重要

    如果您从现有 control plane 主机重复使用 BareMetalHost 对象定义,请不要将 external Provisioned 字段保留为 true

    如果 OpenShift Container Platform 安装程序置备,现有 control plane BareMetalHost 对象可能会将 externallyProvisioned 标记设为 true

    检查完成后,BareMetalHost 对象会被创建并可用置备。

  11. 使用可用的 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
    Copy to Clipboard Toggle word wrap
    1. 验证新机器是否已创建:

      $ oc get machines -n openshift-machine-api -o wide
      Copy to Clipboard Toggle word wrap

      输出示例

      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
      Copy to Clipboard Toggle word wrap

      1
      新机器 clustername-8qw5l-master-3 会被创建,并在阶段从 Provisioning 变为 Running 后就绪。

      创建新机器需要几分钟时间。当机器或节点返回一个健康状态时,etcd cluster Operator 将自动同步。

    2. 运行以下命令验证裸机主机是否被置备,且没有报告的错误:

      $ oc get bmh -n openshift-machine-api
      Copy to Clipboard Toggle word wrap

      输出示例

      $ 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
      Copy to Clipboard Toggle word wrap

    3. 运行以下命令验证新节点是否已添加并处于就绪状态:

      $ oc get nodes
      Copy to Clipboard Toggle word wrap

      输出示例

      $ oc get nodes
      NAME                     STATUS ROLES   AGE   VERSION
      openshift-control-plane-0 Ready master 4h26m v1.32.3
      openshift-control-plane-1 Ready master 4h26m v1.32.3
      openshift-control-plane-2 Ready master 12m   v1.32.3
      openshift-compute-0       Ready worker 3h58m v1.32.3
      openshift-compute-1       Ready worker 3h58m v1.32.3
      Copy to Clipboard Toggle word wrap

  12. 输入以下命令重新打开仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
    Copy to Clipboard Toggle word wrap
  13. 您可以输入以下命令验证 unsupportedConfigOverrides 部分是否已从对象中删除:

    $ oc get etcd/cluster -oyaml
    Copy to Clipboard Toggle word wrap
  14. 如果使用单节点 OpenShift,请重启该节点。否则,您可能会在 etcd 集群 Operator 中遇到以下错误:

    输出示例

    EtcdCertSignerControllerDegraded: [Operation cannot be fulfilled on secrets "etcd-peer-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-sno-0": the object has been modified; please apply your changes to the latest version and try again, Operation cannot be fulfilled on secrets "etcd-serving-metrics-sno-0": the object has been modified; please apply your changes to the latest version and try again]
    Copy to Clipboard Toggle word wrap

验证

  1. 验证所有 etcd pod 是否都正常运行。

    在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc -n openshift-etcd get pods -l k8s-app=etcd
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    Copy to Clipboard Toggle word wrap

    如果上一命令的输出只列出两个 pod,您可以手动强制重新部署 etcd。在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 
    1
    Copy to Clipboard Toggle word wrap
    1
    forceRedeploymentReason 值必须是唯一的,这就是为什么附加时间戳的原因。

    要验证是否有完全有三个 etcd 成员,连接到正在运行的 etcd 容器,传递没有在受影响节点上的 pod 的名称。在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

    $ oc rsh -n openshift-etcd etcd-openshift-control-plane-0
    Copy to Clipboard Toggle word wrap
  2. 查看成员列表:

    sh-4.2# etcdctl member list -w table
    Copy to Clipboard Toggle word wrap

    输出示例

    +------------------+---------+--------------------+---------------------------+---------------------------+-----------------+
    |        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 |
    +------------------+---------+--------------------+---------------------------+---------------------------+-----------------+
    Copy to Clipboard Toggle word wrap

    注意

    如果上一命令的输出列出了超过三个 etcd 成员,您必须删除不需要的成员。

  3. 运行以下命令,验证所有 etcd 成员是否健康:

    # etcdctl endpoint health --cluster
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    Copy to Clipboard Toggle word wrap

  4. 运行以下命令,验证所有节点是否处于最新的修订版本:

    $ oc get etcd -o=jsonpath='{range.items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
    Copy to Clipboard Toggle word wrap
    AllNodesAtLatestRevision
    Copy to Clipboard Toggle word wrap

4.3. 灾难恢复

灾难恢复文档为管理员提供了如何从 OpenShift Container Platform 集群可能出现的几个灾难情形中恢复的信息。作为管理员,您可能需要遵循以下一个或多个步骤将集群恢复为工作状态。

重要

灾难恢复要求您至少有一个健康的 control plane 主机。

4.3.1. 仲裁恢复

您可以使用 quorum-restore.sh 脚本来恢复因为仲裁丢失而离线的集群中的 etcd 仲裁。当 quorum 丢失时,OpenShift Container Platform API 将变为只读。恢复仲裁后,OpenShift Container Platform API 会返回读/写模式。

4.3.1.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 访问权限。

流程

  1. 选择一个要用作恢复主机的 control plane 主机。您可以在此主机上运行恢复操作。

    1. 运行以下命令列出正在运行的 etcd pod:

      $ oc get pods -n openshift-etcd -l app=etcd --field-selector="status.phase==Running"
      Copy to Clipboard Toggle word wrap
    2. 选择 pod 并运行以下命令来获取其 IP 地址:

      $ oc exec -n openshift-etcd <etcd-pod> -c etcdctl -- etcdctl endpoint status -w table
      Copy to Clipboard Toggle word wrap

      记录在不是 learner,且具有最高 Raft 索引的成员的 IP 地址。

    3. 运行以下命令并记录与所选 etcd 成员的 IP 地址对应的节点名称:

      $ oc get nodes -o jsonpath='{range .items[*]}[{.metadata.name},{.status.addresses[?(@.type=="InternalIP")].address}]{end}'
      Copy to Clipboard Toggle word wrap
  2. 使用 SSH 连接到所选恢复节点,并运行以下命令来恢复 etcd 仲裁:

    $ sudo -E /usr/local/bin/quorum-restore.sh
    Copy to Clipboard Toggle word wrap

    几分钟后,关闭的节点会自动与运行恢复脚本的节点同步。任何剩余的在线节点都会自动重新加入由 quorum-restore.sh 脚本创建的新 etcd 集群。这个过程需要几分钟时间。

  3. 退出 SSH 会话。
  4. 如果有任何节点离线,则返回三节点配置。对离线的每个节点重复此步骤,以删除并重新创建它们。重新创建机器后,会强制一个新修订版本,etcd 会自动扩展。

    • 如果使用用户置备的裸机安装,您可以使用最初创建它时使用的相同方法重新创建 control plane 机器。如需更多信息,请参阅"在裸机上安装用户置备的集群"。

      警告

      不要为恢复主机删除并重新创建机器。

    • 如果您正在运行安装程序置备的基础架构,或者您使用 Machine API 创建机器,请按照以下步骤执行:

      警告

      不要为恢复主机删除并重新创建机器。

      对于安装程序置备的基础架构上的裸机安装,不会重新创建 control plane 机器。如需更多信息,请参阅"替换裸机控制平面节点"。

      1. 为其中一个离线节点获取机器。

        在一个终端中使用 cluster-admin 用户连接到集群,运行以下命令:

        $ oc get machines -n openshift-machine-api -o wide
        Copy to Clipboard Toggle word wrap

        输出示例

        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-143-125.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-154-194.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
        Copy to Clipboard Toggle word wrap

        1
        这是离线节点的 control plane 机器 ip-10-0-131-183.ec2.internal
      2. 运行以下命令来删除离线节点的机器:

        $ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 
        1
        Copy to Clipboard Toggle word wrap
        1
        为离线节点指定 control plane 机器的名称。

        删除离线节点的机器后会自动置备新机器。

  5. 运行以下命令验证新机器是否已创建:

    $ oc get machines -n openshift-machine-api -o wide
    Copy to Clipboard Toggle word wrap

    输出示例

    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-143-125.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-154-194.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-173-171.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
    Copy to Clipboard Toggle word wrap

    1
    新机器 clustername-8qw5l-master-3 会被创建,并在阶段从 Provisioning 变为 Running 后就绪。

    创建新机器可能需要几分钟时间。当机器或节点返回健康状态时,etcd 集群 Operator 将自动同步。

    1. 对离线的每个节点重复这些步骤。
  6. 运行以下命令等待 control plane 恢复:

    $ oc adm wait-for-stable-cluster
    Copy to Clipboard Toggle word wrap
    注意

    control plane 最多可能需要 15 分钟才能恢复。

故障排除

  • 如果推出 etcd 静态 pod 的过程没有进展,您可以通过运行以下命令来强制从 etcd 集群 Operator 重新部署:

    $ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
    Copy to Clipboard Toggle word wrap
注意

如果大多数 control plane 节点仍可用,且有 etcd 仲裁,则替换单个不健康的 etcd 成员

4.3.2. 恢复到一个以前的集群状态

要将集群恢复到以前的状态,您必须已通过创建快照来备份 etcd 数据。您将需要使用此快照来还原集群状态。如需更多信息,请参阅"恢复 etcd 数据"。

如果适用,可能还需要从过期的 control plane 证书中恢复

警告

在一个正在运行的集群中恢复到以前的集群状态是破坏性的,而不稳定的操作。这仅应作为最后的手段使用。

在执行恢复前,请参阅 "About restoring to a previous cluster state" 以了解有关对集群的影响的更多信息。

4.3.2.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 捆绑包。

4.3.2.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>.dbstatic_kuberesources_<datetimestamp>.tar.gz

流程

  1. 运行以下命令,使用 SSH 连接到单一节点,并将 etcd 备份复制到 /home/core 目录中:

    $ cp <etcd_backup_directory> /home/core
    Copy to Clipboard Toggle word wrap
  2. 在单一节点中运行以下命令从以前的备份中恢复集群:

    $ sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd_backup_directory>
    Copy to Clipboard Toggle word wrap
  3. 退出 SSH 会话。
  4. 运行以下命令监控 control plane 的恢复进度:

    $ oc adm wait-for-stable-cluster
    Copy to Clipboard Toggle word wrap
    注意

    control plane 最多可能需要 15 分钟才能恢复。

您可以使用保存的 etcd 备份来恢复以前的集群状态,或恢复丢失了大多数 control plane 主机的集群。

对于高可用性 (HA) 集群,三节点集群需要在两个主机上关闭 etcd,以避免出现集群分割的情况。在四节点和五个节点 HA 集群中,您必须关闭三个主机。仲裁只需要具有多数节点的情况。三节点 HA 集群中,仲裁最少需要两个节点。在四节点和五个节点 HA 集群中,仲裁需要的最小节点数为三。如果您从恢复主机上的备份启动新集群,其他 etcd 成员可能仍然可以组成仲裁并继续服务。

注意

如果您的集群使用 control plane 机器集,请参阅"为 etcd 恢复 control plane 机器集"中的"恢复降级的 etcd Operator"。对于单一节点上的 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>.dbstatic_kuberesources_<datetimestamp>.tar.gz
  • 节点必须能够访问或可引导。
重要

对于非恢复 control plane 节点,不需要建立 SSH 连接或停止静态 pod。您可以逐个删除并重新创建其他非恢复 control plane 机器。

流程

  1. 选择一个要用作恢复主机的 control plane 主机。这是在其中运行恢复操作的主机。
  2. 建立到每个 control plane 节点(包括恢复主机)的 SSH 连接。

    恢复过程启动后,kube-apiserver 将无法访问,因此您无法访问 control plane 节点。因此,建议在一个单独的终端中建立到每个control plane 主机的 SSH 连接。

    重要

    如果没有完成这个步骤,将无法访问 control plane 主机来完成恢复过程,您将无法从这个状态恢复集群。

  3. 使用 SSH 连接到每个 control plane 节点,并运行以下命令来禁用 etcd:

    $ sudo -E /usr/local/bin/disable-etcd.sh
    Copy to Clipboard Toggle word wrap
  4. 将 etcd 备份目录复制复制到恢复 control plane 主机上。

    此流程假设您将 backup 目录(其中包含 etcd 快照和静态 pod 资源)复制到恢复 control plane 主机的 /home/core/ 目录中。

  5. 运行以下命令,使用 SSH 连接到恢复主机并从以前的备份中恢复集群:

    $ sudo -E /usr/local/bin/cluster-restore.sh /home/core/<etcd-backup-directory>
    Copy to Clipboard Toggle word wrap
  6. 退出 SSH 会话。
  7. API 响应后,通过运行nning 来关闭 etcd Operator 仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
    Copy to Clipboard Toggle word wrap
  8. 运行以下命令监控 control plane 的恢复进度:

    $ oc adm wait-for-stable-cluster
    Copy to Clipboard Toggle word wrap
    注意

    control plane 最多可能需要 15 分钟才能恢复。

  9. 恢复后,运行以下命令来启用仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
    Copy to Clipboard Toggle word wrap

故障排除

如果推出 etcd 静态 pod 的过程没有进展,您可以通过运行以下命令来强制从 cluster-etcd-operator 重新部署:

$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$(date --rfc-3339=ns )"'"}}' --type=merge
Copy to Clipboard Toggle word wrap
4.3.2.4. 从 etcd 备份手动恢复集群

恢复过程在 "Restoring to a previous cluster state" 部分中介绍:

  • 需要 2 个 control plane 节点的完整重新创建,这可能是使用 UPI 安装方法安装的集群的一个复杂步骤,因为 UPI 安装不会为 control plane 节点创建任何 MachineControlPlaneMachineset
  • 使用脚本 /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>.dbstatic_kuberesources_<datetimestamp>.tar.gz

流程

  1. 使用 SSH 连接到每个 control plane 节点。

    恢复过程启动后,Kubernetes API 服务器将无法访问,因此您无法访问 control plane 节点。因此,建议针对每个 control plane 主机都使用一个单独的终端来进行 SSH 连接。

    重要

    如果没有完成这个步骤,将无法访问 control plane 主机来完成恢复过程,您将无法从这个状态恢复集群。

  2. 将 etcd 备份目录复制到每个 control plane 主机上。

    此流程假设您将 backup 目录(其中包含 etcd 快照和静态 pod 资源)复制到每个 control plane 主机的 /home/core/assets 目录中。如果尚未存在,您可能需要创建此 assets 文件夹。

  3. 停止所有 control plane 节点上的静态 pod;一次只针对一个主机进行。

    1. 将现有 Kubernetes API Server 静态 pod 清单从 kubelet 清单目录中移出。

      $ mkdir -p /root/manifests-backup
      $ mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /root/manifests-backup/
      Copy to Clipboard Toggle word wrap
    2. 使用以下命令验证 Kubernetes API 服务器容器是否已停止:

      $ crictl ps | grep kube-apiserver | grep -E -v "operator|guard"
      Copy to Clipboard Toggle word wrap

      命令输出应该为空。如果它不是空的,请等待几分钟后再重新检查。

    3. 如果 Kubernetes API 服务器容器仍在运行,使用以下命令手动终止它们:

      $ crictl stop <container_id>
      Copy to Clipboard Toggle word wrap
    4. kube-controller-manager-pod.yamlkube-scheduler-pod.yaml 最后为 etcd-pod.yaml 重复相同的步骤,。

      1. 使用以下命令停止 kube-controller-manager pod:

        $ mv /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /root/manifests-backup/
        Copy to Clipboard Toggle word wrap
      2. 使用以下命令检查容器是否已停止:

        $ crictl ps | grep kube-controller-manager | grep -E -v "operator|guard"
        Copy to Clipboard Toggle word wrap
      3. 使用以下命令停止 kube-scheduler pod:

        $ mv /etc/kubernetes/manifests/kube-scheduler-pod.yaml /root/manifests-backup/
        Copy to Clipboard Toggle word wrap
      4. 使用以下命令检查容器是否已停止:

        $ crictl ps | grep kube-scheduler | grep -E -v "operator|guard"
        Copy to Clipboard Toggle word wrap
      5. 使用以下命令停止 etcd pod:

        $ mv /etc/kubernetes/manifests/etcd-pod.yaml /root/manifests-backup/
        Copy to Clipboard Toggle word wrap
      6. 使用以下命令检查容器是否已停止:

        $ crictl ps | grep etcd | grep -E -v "operator|guard"
        Copy to Clipboard Toggle word wrap
  4. 在每个 control plane 主机上,保存当前的 etcd 数据(将它移到 backup 目录中):

    $ mkdir /home/core/assets/old-member-data
    $ mv /var/lib/etcd/member /home/core/assets/old-member-data
    Copy to Clipboard Toggle word wrap

    etcd 备份恢复无法正常工作,且 etcd 集群必须恢复到当前状态,则这些数据将很有用。

  5. 为每个 control plane 主机找到正确的 etcd 参数。

    1. <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: ").+(?=")'
      Copy to Clipboard Toggle word wrap
    2. <UUID> 的值可使用以下命令在 control plane 主机中生成:

      $ uuidgen
      Copy to Clipboard Toggle word wrap
      注意

      <UUID> 的值必须只生成一次。在一个 control plane 主机上生成 UUID 后,请不要在其他主机上再次生成它。相同的 UUID 会在后续步骤中的所有 control plane 主机上使用。

    3. ETCD_NODE_PEER_URL 的值应设置为类似以下示例:

      https://<IP_CURRENT_HOST>:2380
      Copy to Clipboard Toggle word wrap

      正确的 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 '(?<=").+(?=")'
      Copy to Clipboard Toggle word wrap
    4. <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> 
      1
      Copy to Clipboard Toggle word wrap

      1
      指定每个 control plane 主机中的 ETCD_NODE_PEER_URL 值。

      <ETCD_INITIAL_CLUSTER> 值在所有 control plane 主机上都是相同的。在后续步骤中,每个 control plane 主机都需要使用相同的值。

  6. 从备份中重新生成 etcd 数据库。

    此类操作必须在每个 control plane 主机上执行。

    1. 使用以下命令将 etcd 备份复制到 /var/lib/etcd 目录中:

      $ cp /home/core/assets/backup/<snapshot_yyyy-mm-dd_hhmmss>.db /var/lib/etcd
      Copy to Clipboard Toggle word wrap
    2. 在继续操作前,识别正确的 etcdctl 镜像。使用以下命令从 pod 清单的备份中检索镜像:

      $ jq -r '.spec.containers[]|select(.name=="etcdctl")|.image' /root/manifests-backup/etcd-pod.yaml
      Copy to Clipboard Toggle word wrap
      $ podman run --rm -it --entrypoint="/bin/bash" -v /var/lib/etcd:/var/lib/etcd:z <image-hash>
      Copy to Clipboard Toggle word wrap
    3. 检查 etcdctl 工具的版本是创建备份的 etcd 服务器的版本:

      $ etcdctl version
      Copy to Clipboard Toggle word wrap
    4. 运行以下命令重新生成 etcd 数据库,为当前主机使用正确的值:

      $ ETCDCTL_API=3 /usr/bin/etcdctl snapshot restore /var/lib/etcd/<snapshot_yyyy-mm-dd_hhmmss>.db \
        --name "<ETCD_NAME>" \
        --initial-cluster="<ETCD_INITIAL_CLUSTER>" \
        --initial-cluster-token "openshift-etcd-<UUID>" \
        --initial-advertise-peer-urls "<ETCD_NODE_PEER_URL>" \
        --data-dir="/var/lib/etcd/restore-<UUID>" \
        --skip-hash-check=true
      Copy to Clipboard Toggle word wrap
      注意

      在重新生成 etcd 数据库时,引号是必需的。

  7. 记录下在 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}
    Copy to Clipboard Toggle word wrap

    1. 退出容器。
    2. 在其他 control plane 主机上重复这些步骤,检查 added member 日志中的值对于所有 control plane 主机都是一样的。
  8. 将重新生成的 etcd 数据库移到默认位置。

    此类操作必须在每个 control plane 主机上执行。

    1. 将重新生成的数据库(上一个 etcdctl snapshot restore 命令创建的 member 文件夹)移到默认的 etcd 位置 /var/lib/etcd

      $ mv /var/lib/etcd/restore-<UUID>/member /var/lib/etcd
      Copy to Clipboard Toggle word wrap
    2. /var/lib/etcd 目录中恢复 /var/lib/etcd/member 文件夹的 SELinux 上下文:

      $ restorecon -vR /var/lib/etcd/
      Copy to Clipboard Toggle word wrap
    3. 删除剩下的文件和目录:

      $ rm -rf /var/lib/etcd/restore-<UUID>
      Copy to Clipboard Toggle word wrap
      $ rm /var/lib/etcd/<snapshot_yyyy-mm-dd_hhmmss>.db
      Copy to Clipboard Toggle word wrap
      重要

      完成后,/var/lib/etcd 目录只能包含文件夹 member

    4. 在其他 control plane 主机上重复这些步骤。
  9. 重启 etcd 集群。

    1. 必须在所有 control plane 主机上执行以下步骤,但一次只针对一个主机执行
    2. etcd 静态 pod 清单移回到 kubelet 清单目录,以便 kubelet 启动相关的容器:

      $ mv /tmp/etcd-pod.yaml /etc/kubernetes/manifests
      Copy to Clipboard Toggle word wrap
    3. 验证所有 etcd 容器是否已启动:

      $ crictl ps | grep etcd | grep -v operator
      Copy to Clipboard Toggle word wrap

      输出示例

      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 Toggle word wrap

      如果这个命令的输出为空,请等待几分钟,然后再次检查。

  10. 检查 etcd 集群的状态。

    1. 在任何 control plane 主机上,使用以下命令检查 etcd 集群的状态:

      $ crictl exec -it $(crictl ps | grep etcdctl | awk '{print $1}') etcdctl endpoint status -w table
      Copy to Clipboard Toggle word wrap

      输出示例

      +--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |         ENDPOINT         |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
      +--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      | https://10.0.89.133:2379 | 682e4a83a0cec6c0 |   3.5.0 |   67 MB |      true |      false |         2 |        218 |                218 |        |
      |  https://10.0.92.74:2379 | 450bcf6999538512 |   3.5.0 |   67 MB |     false |      false |         2 |        218 |                218 |        |
      | https://10.0.93.129:2379 | 358efa9c1d91c3d6 |   3.5.0 |   67 MB |     false |      false |         2 |        218 |                218 |        |
      +--------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      Copy to Clipboard Toggle word wrap

  11. 重启其他静态 pod。

    必须在所有 control plane 主机上执行以下步骤,但一次只针对一个主机执行。

    1. 将 Kubernetes API Server 静态 pod 清单重新移到 kubelet 清单目录中,以便 kubelet 使用命令启动相关的容器:

      $ mv /root/manifests-backup/kube-apiserver-pod.yaml /etc/kubernetes/manifests
      Copy to Clipboard Toggle word wrap
    2. 验证所有 Kubernetes API 服务器容器是否已启动:

      $ crictl ps | grep kube-apiserver | grep -v operator
      Copy to Clipboard Toggle word wrap
      注意

      如果以下命令的输出为空,请等待几分钟,然后再次检查。

    3. kube-controller-manager-pod.yamlkube-scheduler-pod.yaml 文件重复相同的步骤。

      1. 使用以下命令重启所有节点中的 kubelet:

        $ systemctl restart kubelet
        Copy to Clipboard Toggle word wrap
      2. 使用以下命令启动剩余的 control plane pod:

        $ mv /root/manifests-backup/kube-* /etc/kubernetes/manifests/
        Copy to Clipboard Toggle word wrap
      3. 检查 kube-apiserverkube-schedulerkube-controller-manager pod 是否已正确启动:

        $ crictl ps | grep -E 'kube-(apiserver|scheduler|controller-manager)' | grep -v -E 'operator|guard'
        Copy to Clipboard Toggle word wrap
      4. 使用以下命令擦除 OVN 数据库:

        for NODE in  $(oc get node -o name | sed 's:node/::g')
        do
          oc debug node/${NODE} -- chroot /host /bin/bash -c  'rm -f /var/lib/ovn-ic/etc/ovn*.db && systemctl restart ovs-vswitchd ovsdb-server'
          oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-node --field-selector=spec.nodeName=${NODE} --wait
          oc -n openshift-ovn-kubernetes wait pod -l app=ovnkube-node --field-selector=spec.nodeName=${NODE} --for condition=ContainersReady --timeout=600s
        done
        Copy to Clipboard Toggle word wrap

如果您的 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 引用不再存在的设备。

    要解决这个问题,管理员必须:

    1. 手动删除带有无效设备的 PV。
    2. 从对应节点中删除符号链接。
    3. 删除 LocalVolumeLocalVolumeSet 对象(请参阅 StorageConfiguring persistent storagePersistent storage → Persistent storageDeleting the Local Storage Operator Resources)。

4.3.3. 从 control plane 证书已过期的情况下恢复

集群可以从过期的 control plane 证书中自动恢复。

但是,您需要手动批准待处理的 node-bootstrapper 证书签名请求(CSR)来恢复 kubelet 证书。对于用户置备的安装,您可能需要批准待处理的 kubelet 服务 CSR。

使用以下步骤批准待处理的 CSR:

流程

  1. 获取当前 CSR 列表:

    $ oc get csr
    Copy to Clipboard Toggle word wrap

    输出示例

    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
    csr-4hl85   13m    kubernetes.io/kube-apiserver-client-kubelet   system:serviceaccount:openshift-machine-config-operator:node-bootstrapper   Pending 
    2
    
    csr-zhhhp   3m8s   kubernetes.io/kube-apiserver-client-kubelet   system:serviceaccount:openshift-machine-config-operator:node-bootstrapper   Pending
    ...
    Copy to Clipboard Toggle word wrap

    1
    一个待处理的 kubelet 服务 CSR(用于用户置备的安装)。
    2
    一个待处理的 node-bootstrapper CSR。
  2. 查看一个 CSR 的详细信息以验证其是否有效:

    $ oc describe csr <csr_name> 
    1
    Copy to Clipboard Toggle word wrap
    1
    <csr_name> 是当前 CSR 列表中 CSR 的名称。
  3. 批准每个有效的 node-bootstrapper CSR:

    $ oc adm certificate approve <csr_name>
    Copy to Clipboard Toggle word wrap
  4. 对于用户置备的安装,请批准每个有效的 kubelet 服务 CSR:

    $ oc adm certificate approve <csr_name>
    Copy to Clipboard Toggle word wrap

4.3.4. 测试恢复过程

测试恢复过程非常重要,以确保您的自动化和工作负载安全处理新的集群状态。由于 etcd 仲裁的复杂性,以及 etcd Operator 会尝试自动修复,通常很难正确地使您的集群进入一个可以恢复的状态。

警告

必须有到集群的 SSH 访问权限。如果无法进行 SSH 访问,您的集群可能完全丢失。

先决条件

  • 有到 control plane 主机的 SSH 访问权限。
  • 已安装 OpenShift CLI(oc)。

流程

  1. 使用 SSH 连接到每个非恢复节点,并运行以下命令来禁用 etcd 和 kubelet 服务:

    1. 运行以下命令来禁用 etcd:

      $ sudo /usr/local/bin/disable-etcd.sh
      Copy to Clipboard Toggle word wrap
    2. 运行以下命令来删除 etcd 的变量数据:

      $ sudo rm -rf /var/lib/etcd
      Copy to Clipboard Toggle word wrap
    3. 运行以下命令来禁用 kubelet 服务:

      $ sudo systemctl disable kubelet.service
      Copy to Clipboard Toggle word wrap
  2. 退出每个 SSH 会话。
  3. 运行以下命令,以确保您的非恢复节点处于 NOT READY 状态:

    $ oc get nodes
    Copy to Clipboard Toggle word wrap
  4. 按照"恢复到以前的集群状态"中的步骤来恢复集群。
  5. 恢复集群和 API 响应后,使用 SSH 连接到每个非恢复节点并启用 kubelet 服务:

    $ sudo systemctl enable kubelet.service
    Copy to Clipboard Toggle word wrap
  6. 退出每个 SSH 会话。
  7. 运行以下命令,观察您的节点返回 READY 状态:

    $ oc get nodes
    Copy to Clipboard Toggle word wrap
  8. 运行以下命令验证 etcd 是否可用:

    $ oc get pods -n openshift-etcd
    Copy to Clipboard Toggle word wrap

第 5 章 启用 etcd 加密

5.1. 关于 etcd 加密

默认情况下,OpenShift Container Platform 不加密 etcd 数据。在集群中启用对 etcd 进行加密的功能可为数据的安全性提供额外的保护层。例如,如果 etcd 备份暴露给不应该获得这个数据的人员,它会帮助保护敏感数据。

启用 etcd 加密时,以下 OpenShift API 服务器和 Kubernetes API 服务器资源将被加密:

  • Secrets
  • 配置映射
  • Routes
  • OAuth 访问令牌
  • OAuth 授权令牌

当您启用 etcd 加密时,会创建加密密钥。您必须具有这些密钥才能从 etcd 备份中恢复。

注意

etcd 加密只加密值,而不加密键。资源类型、命名空间和对象名称是未加密的。

如果在备份过程中启用了 etcd 加密,static_kuberesources_<datetimestamp>.tar.gz 文件包含 etcd 快照的加密密钥。为安全起见,请将此文件与 etcd 快照分开存储。但是,需要这个文件才能从相应的 etcd 快照恢复以前的 etcd 状态。

5.2. 支持的加密类型

在 OpenShift Container Platform 中,支持以下加密类型来加密 etcd 数据:

AES-CBC
使用带有 PKCS#7 padding 和 32 字节密钥的 AES-CBC 来执行加密。加密密钥每周轮转。
AES-GCM
使用带有随机 nonce 和 32 字节密钥的 AES-GCM 来执行加密。加密密钥每周轮转。

5.3. 启用 etcd 加密

您可以启用 etcd 加密来加密集群中的敏感资源。

警告

在初始加密过程完成前,不要备份 etcd 资源。如果加密过程还没有完成,则备份可能只被部分加密。

启用 etcd 加密后,可能会出现一些更改:

  • etcd 加密可能会影响几个资源的内存消耗。
  • 您可能会注意到对备份性能具有临时影响,因为领导必须提供备份服务。
  • 磁盘 I/O 可能会影响接收备份状态的节点。

您可以在 AES-GCM 或 AES-CBC 加密中加密 etcd 数据库。

注意

要将 etcd 数据库从一个加密类型迁移到另一个加密类型,您可以修改 API 服务器的 spec.encryption.type 字段。将 etcd 数据迁移到新的加密类型会自动进行。

先决条件

  • 使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 修改 APIServer 对象:

    $ oc edit apiserver
    Copy to Clipboard Toggle word wrap
  2. spec.encryption.type 字段设置为 aesgcmaescbc

    spec:
      encryption:
        type: aesgcm 
    1
    Copy to Clipboard Toggle word wrap
    1
    设置为 aesgcm 用于 AES-GCM 加密,或设置为 aescbc 用于 AES-CBC 加密。
  3. 保存文件以使改变生效。

    加密过程开始。根据 etcd 数据库的大小,这个过程可能需要 20 分钟或更长时间才能完成。

  4. 验证 etcd 加密是否成功。

    1. 查看 OpenShift API 服务器的 Encrypted 状态条件,以验证其资源是否已成功加密:

      $ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功加密后输出显示 EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: routes.route.openshift.io
      Copy to Clipboard Toggle word wrap

      如果输出显示 EncryptionInProgress,加密仍在进行中。等待几分钟后重试。

    2. 查看 Kubernetes API 服务器的 Encrypted 状态条件,以验证其资源是否已成功加密:

      $ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功加密后输出显示 EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: secrets, configmaps
      Copy to Clipboard Toggle word wrap

      如果输出显示 EncryptionInProgress,加密仍在进行中。等待几分钟后重试。

    3. 查看 OpenShift OAuth API 服务器的 Encrypted 状态条件,以验证其资源是否已成功加密:

      $ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功加密后输出显示 EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: oauthaccesstokens.oauth.openshift.io, oauthauthorizetokens.oauth.openshift.io
      Copy to Clipboard Toggle word wrap

      如果输出显示 EncryptionInProgress,加密仍在进行中。等待几分钟后重试。

5.4. 禁用 etcd 加密

您可以在集群中禁用 etcd 数据的加密。

先决条件

  • 使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 修改 APIServer 对象:

    $ oc edit apiserver
    Copy to Clipboard Toggle word wrap
  2. encryption 字段类型设置为 identity

    spec:
      encryption:
        type: identity 
    1
    Copy to Clipboard Toggle word wrap
    1
    identity 类型是默认值,意味着没有执行任何加密。
  3. 保存文件以使改变生效。

    解密过程开始。根据集群的大小,这个过程可能需要 20 分钟或更长的时间才能完成。

  4. 验证 etcd 解密是否成功。

    1. 查看 OpenShift API 服务器的 Encrypted 状态条件,以验证其资源是否已成功解密:

      $ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功解密后输出显示 DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted
      Copy to Clipboard Toggle word wrap

      如果输出显示 DecryptionInProgress,解密仍在进行中。等待几分钟后重试。

    2. 查看 Kubernetes API 服务器的 Encrypted 状态条件,以验证其资源是否已成功解密:

      $ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功解密后输出显示 DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted
      Copy to Clipboard Toggle word wrap

      如果输出显示 DecryptionInProgress,解密仍在进行中。等待几分钟后重试。

    3. 查看 OpenShift OAuth API 服务器的 Encrypted 状态条件,以验证其资源是否已成功解密:

      $ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
      Copy to Clipboard Toggle word wrap

      在成功解密后输出显示 DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted
      Copy to Clipboard Toggle word wrap

      如果输出显示 DecryptionInProgress,解密仍在进行中。等待几分钟后重试。

Legal Notice

Copyright © 2025 Red Hat

OpenShift documentation is licensed under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0).

Modified versions must remove all Red Hat trademarks.

Portions adapted from https://github.com/kubernetes-incubator/service-catalog/ with modifications by Red Hat.

Red Hat, Red Hat Enterprise Linux, the Red Hat logo, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.

Java® is a registered trademark of Oracle and/or its affiliates.

XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.

MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.

Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.

The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation’s permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.

All other trademarks are the property of their respective owners.

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat