×

安装 OpenShift Container Platform 后,您可以根据需要进一步扩展和定制集群。

可用的集群定制

您在部署 OpenShift Container Platform 集群后完成大部分集群配置和定制。许多配置资源可用。

如果您在 IBM Z® 上安装集群,则并非所有功能都可用。

您可以修改配置资源来配置集群的主要功能,例如镜像注册表、网络配置、镜像构建行为和身份提供程序。

有关您可以使用这些资源控制的设置的当前文档,请使用oc explain命令,例如oc explain builds --api-version=config.openshift.io/v1

集群配置资源

所有集群配置资源都是全局范围的(不是命名空间的),并命名为cluster

资源名称 描述

apiserver.config.openshift.io

提供 API 服务器配置,例如证书和证书颁发机构

authentication.config.openshift.io

控制集群的身份提供程序和身份验证配置。

build.config.openshift.io

控制集群上所有构建的默认和强制配置

console.config.openshift.io

配置 Web 控制台界面的行为,包括注销行为

featuregate.config.openshift.io

启用FeatureGates,以便您可以使用技术预览功能。

image.config.openshift.io

配置如何处理特定镜像注册表(允许、不允许、不安全、CA 详细信息)。

ingress.config.openshift.io

路由相关的配置详细信息,例如路由的默认域名。

oauth.config.openshift.io

配置身份提供程序和其他与内部 OAuth 服务器流程相关的行为。

project.config.openshift.io

配置项目创建方式,包括项目模板。

proxy.config.openshift.io

定义需要外部网络访问的组件使用的代理。注意:并非所有组件当前都使用此值。

scheduler.config.openshift.io

配置调度程序行为,例如配置文件和默认节点选择器。

运营商配置资源

这些配置资源是集群范围的实例,名为cluster,它控制特定组件的行为,如同由特定运营商拥有。

资源名称 描述

consoles.operator.openshift.io

控制控制台外观,例如品牌定制

config.imageregistry.operator.openshift.io

配置OpenShift 镜像注册表设置,例如公共路由、日志级别、代理设置、资源约束、副本计数和存储类型。

config.samples.operator.openshift.io

配置示例运营商以控制在集群上安装哪些示例镜像流和模板。

其他配置资源

这些配置资源表示特定组件的单个实例。在某些情况下,您可以通过创建多个资源实例来请求多个实例。在其他情况下,运营商只能在特定命名空间中使用特定资源实例名称。有关如何以及何时可以创建其他资源实例的详细信息,请参阅特定组件文档。

资源名称 实例名称 命名空间 描述

alertmanager.monitoring.coreos.com

main

openshift-monitoring

控制Alertmanager部署参数。

ingresscontroller.operator.openshift.io

default

openshift-ingress-operator

配置Ingress 运算符行为,例如域名、副本数、证书和控制器位置。

信息资源

您可以使用这些资源来检索有关集群的信息。某些配置可能需要您直接编辑这些资源。

资源名称 实例名称 描述

clusterversion.config.openshift.io

version

在 OpenShift Container Platform 4.17 中,您不得为生产集群自定义ClusterVersion资源。请改用以下流程来更新集群

dns.config.openshift.io

cluster

您无法修改集群的 DNS 设置。您可以检查 DNS 运算符状态

infrastructure.config.openshift.io

cluster

允许集群与其云提供商交互的配置详细信息。

network.config.openshift.io

cluster

安装后您无法修改集群网络。要自定义您的网络,请按照以下流程在安装过程中进行网络自定义

添加工作节点

部署 OpenShift Container Platform 集群后,您可以添加工作节点以扩展集群资源。根据安装方法和集群的环境,您可以通过不同的方式添加工作节点。

向本地集群添加工作节点

对于本地集群,您可以使用 OpenShift Container Platform 命令行界面 (oc) 生成 ISO 镜像来添加工作节点,然后可以使用该镜像引导目标集群中的一个或多个节点。无论您如何安装集群,都可以使用此过程。

您可以一次添加一个或多个节点,同时使用更复杂的配置(例如静态网络配置)自定义每个节点,或者您只需指定每个节点的 MAC 地址。在 ISO 生成期间未指定的任何配置都将从目标集群检索并应用于新节点。

引导 ISO 镜像时还会执行预检验证检查,以便在您尝试引导每个节点之前告知您导致故障的问题。

向安装程序预配的基础设施集群添加工作节点

对于安装程序预配的基础设施集群,您可以手动或自动调整 MachineSet 对象的规模以匹配可用裸机主机的数量。

要添加裸机主机,您必须配置所有网络先决条件,配置关联的 baremetalhost 对象,然后将工作节点预配到集群。您可以手动添加裸机主机,也可以使用 Web 控制台添加。

向用户预配的基础设施集群添加工作节点

对于用户预配的基础设施集群,您可以使用 RHEL 或 RHCOS ISO 镜像并使用集群 Ignition 配置文件将其连接到您的集群来添加工作节点。对于 RHEL 工作节点,以下示例使用 Ansible playbook 将工作节点添加到集群。对于 RHCOS 工作节点,以下示例使用 ISO 镜像和网络引导将工作节点添加到集群。

向由 Assisted Installer 管理的集群添加工作节点

对于由 Assisted Installer 管理的集群,您可以使用 Red Hat OpenShift 集群管理器控制台、Assisted Installer REST API 或手动使用 ISO 镜像和集群 Ignition 配置文件添加工作节点。

向由 Kubernetes 多集群引擎管理的集群添加工作节点

对于由 Kubernetes 多集群引擎管理的集群,您可以使用专用的多集群引擎控制台添加工作节点。

调整工作节点

如果您在部署期间错误地调整了工作节点的大小,请通过创建一组或多组新的计算机器集来调整它们,将其扩展,然后缩减原始计算机器集,然后再将其删除。

了解计算机器集和机器配置池之间的区别

MachineSet 对象描述了关于云或机器提供程序的 OpenShift Container Platform 节点。

MachineConfigPool 对象允许 MachineConfigController 组件定义和提供升级环境中机器的状态。

MachineConfigPool 对象允许用户配置如何将升级推出到机器配置池中的 OpenShift Container Platform 节点。

NodeSelector 对象可以用对 MachineSet 对象的引用替换。

手动缩放计算机器集

要添加或删除计算机器集中的机器实例,您可以手动缩放计算机器集。

此指南与完全自动化的、安装程序预配的基础设施安装相关。自定义的、用户预配的基础设施安装没有计算机器集。

先决条件
  • 安装 OpenShift Container Platform 集群和 oc 命令行。

  • 以具有 cluster-admin 权限的用户身份登录 oc

步骤
  1. 通过运行以下命令查看集群中的计算机器集

    $ oc get machinesets.machine.openshift.io -n openshift-machine-api

    计算机器集以 <clusterid>-worker-<aws-region-az> 的形式列出。

  2. 通过运行以下命令查看集群中的计算机器

    $ oc get machines.machine.openshift.io -n openshift-machine-api
  3. 通过运行以下命令设置要删除的计算机器上的注释

    $ oc annotate machines.machine.openshift.io/<machine_name> -n openshift-machine-api machine.openshift.io/delete-machine="true"
  4. 通过运行以下命令之一来缩放计算机器集

    $ oc scale --replicas=2 machinesets.machine.openshift.io <machineset> -n openshift-machine-api

    或者

    $ oc edit machinesets.machine.openshift.io <machineset> -n openshift-machine-api

    或者您可以应用以下 YAML 来缩放计算机器集

    apiVersion: machine.openshift.io/v1beta1
    kind: MachineSet
    metadata:
      name: <machineset>
      namespace: openshift-machine-api
    spec:
      replicas: 2

    您可以向上或向下缩放计算机器集。新机器需要几分钟才能可用。

    默认情况下,机器控制器会尝试排空由机器支持的节点,直到成功为止。在某些情况下,例如 pod 扰乱预算配置错误,排空操作可能无法成功。如果排空操作失败,则机器控制器无法继续删除机器。

    您可以通过在特定机器中添加注释 machine.openshift.io/exclude-node-draining 来跳过排空节点。

验证
  • 通过运行以下命令验证是否删除了目标机器

    $ oc get machines.machine.openshift.io

计算机器集删除策略

RandomNewestOldest 是三个受支持的删除选项。默认值为 Random,这意味着在缩减计算机器集时,会随机选择并删除机器。可以通过修改特定的计算机器集来根据用例设置删除策略。

spec:
  deletePolicy: <delete_policy>
  replicas: <desired_replica_count>

还可以通过向感兴趣的机器添加注释 machine.openshift.io/delete-machine=true 来优先删除特定机器,而不管删除策略如何。

默认情况下,OpenShift Container Platform 路由器 pod 部署在工作节点上。因为路由器需要访问某些集群资源(包括 Web 控制台),所以除非您首先重新定位路由器 pod,否则不要将工作节点计算机器集缩放到 0

自定义计算机器集可用于需要在特定节点上运行服务并使控制器在工作节点计算机器集缩减时忽略这些服务的用例。这可以防止服务中断。

创建默认的集群范围节点选择器

您可以将默认的集群范围节点选择器与节点上的标签一起用于将集群中创建的所有 pod 限制到特定节点。

使用集群范围节点选择器时,在该集群中创建 pod 时,OpenShift Container Platform 会将默认节点选择器添加到 pod 并将 pod 调度到具有匹配标签的节点上。

您可以通过编辑调度程序操作符自定义资源 (CR) 来配置集群范围的节点选择器。您可以向节点、计算机器集或机器配置添加标签。将标签添加到计算机器集可确保如果节点或机器出现故障,新节点将具有该标签。如果节点或机器出现故障,则添加到节点或机器配置的标签不会持久化。

您可以向 Pod 添加额外的键值对。但是,您不能为默认键添加不同的值。

步骤

添加默认集群范围节点选择器

  1. 编辑调度程序操作符 CR 以添加默认集群范围节点选择器

    $ oc edit scheduler cluster
    包含节点选择器的调度程序操作符 CR 示例
    apiVersion: config.openshift.io/v1
    kind: Scheduler
    metadata:
      name: cluster
    ...
    spec:
      defaultNodeSelector: type=user-node,region=east (1)
      mastersSchedulable: false
    1 添加具有适当的<key>:<value>对的节点选择器。

    进行此更改后,等待openshift-kube-apiserver项目中的 Pod 重新部署。这可能需要几分钟时间。默认集群范围节点选择器只有在 Pod 重新部署后才会生效。

  2. 使用计算机器集或直接编辑节点来向节点添加标签

    • 在创建节点时,使用计算机器集向计算机器集管理的节点添加标签

      1. 运行以下命令向MachineSet对象添加标签

        $ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]'  -n openshift-machine-api (1)
        1 为每个标签添加<key>/<value>对。

        例如

        $ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]'  -n openshift-machine-api

        或者,您可以应用以下 YAML 来向计算机器集添加标签

        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
        metadata:
          name: <machineset>
          namespace: openshift-machine-api
        spec:
          template:
            spec:
              metadata:
                labels:
                  region: "east"
                  type: "user-node"
      2. 使用oc edit命令验证标签是否已添加到MachineSet对象

        例如

        $ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api
        MachineSet对象示例
        apiVersion: machine.openshift.io/v1beta1
        kind: MachineSet
          ...
        spec:
          ...
          template:
            metadata:
          ...
            spec:
              metadata:
                labels:
                  region: east
                  type: user-node
          ...
      3. 通过缩减到0然后扩容节点来重新部署与该计算机器集关联的节点

        例如

        $ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
        $ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
      4. 当节点准备就绪并可用后,使用oc get命令验证标签是否已添加到节点

        $ oc get nodes -l <key>=<value>

        例如

        $ oc get nodes -l type=user-node
        示例输出
        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp   Ready    worker   61s   v1.30.3
    • 直接向节点添加标签

      1. 编辑节点的Node对象

        $ oc label nodes <name> <key>=<value>

        例如,要为节点添加标签

        $ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east

        或者,您可以应用以下 YAML 来向节点添加标签

        kind: Node
        apiVersion: v1
        metadata:
          name: <node_name>
          labels:
            type: "user-node"
            region: "east"
      2. 使用oc get命令验证标签是否已添加到节点

        $ oc get nodes -l <key>=<value>,<key>=<value>

        例如

        $ oc get nodes -l type=user-node,region=east
        示例输出
        NAME                                       STATUS   ROLES    AGE   VERSION
        ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49   Ready    worker   17m   v1.30.3

使用工作节点延迟配置文件提高高延迟环境中的集群稳定性

如果集群管理员已执行延迟测试以进行平台验证,他们可以发现需要调整集群的操作以确保在高延迟情况下保持稳定性。集群管理员只需要更改文件中记录的一个参数,该参数控制影响监督进程读取状态和解释集群健康状况的四个参数。仅更改一个参数即可以简单易维护的方式进行集群调整。

Kubelet进程是监控集群健康状况的起点。Kubelet为OpenShift Container Platform集群中的所有节点设置状态值。Kubernetes控制器管理器 (kube controller) 默认每10秒读取一次状态值。如果kube controller无法读取节点状态值,则在配置的时间段后会失去与该节点的联系。默认行为是

  1. 控制平面上的节点控制器将节点健康状况更新为不健康,并将节点就绪条件标记为未知

  2. 作为响应,调度程序停止向该节点调度 Pod。

  3. 节点生命周期控制器添加具有NoExecute效果的node.kubernetes.io/unreachable污点到节点,并在默认情况下五分钟后安排对节点上任何Pod的驱逐。

如果您的网络容易出现延迟问题,尤其是在网络边缘有节点的情况下,此行为可能会导致问题。在某些情况下,由于网络延迟,Kubernetes控制器管理器可能无法从健康节点接收更新。即使节点处于健康状态,Kubelet也会驱逐节点上的 Pod。

为避免此问题,您可以使用工作节点延迟配置文件来调整Kubelet和Kubernetes控制器管理器在采取行动之前等待状态更新的频率。这些调整有助于确保即使控制平面和工作节点之间的网络延迟不是最佳的,您的集群也能正常运行。

这些工作节点延迟配置文件包含三组参数,这些参数预定义了经过仔细调整的值,以控制集群对延迟增加的反应。无需手动实验寻找最佳值。

您可以在安装集群时或在任何时候注意到集群网络延迟增加时配置工作节点延迟配置文件。

了解工作节点延迟配置文件

工作节点延迟配置文件包含四类经过仔细调整的参数。实现这些值的四个参数是node-status-update-frequencynode-monitor-grace-perioddefault-not-ready-toleration-secondsdefault-unreachable-toleration-seconds。这些参数可以使用允许您控制集群对延迟问题的反应的值,而无需使用手动方法确定最佳值。

不支持手动设置这些参数。参数设置不正确会对集群稳定性产生不利影响。

所有工作节点延迟配置文件都配置以下参数

node-status-update-frequency

指定 kubelet 多久向 API 服务器发布一次节点状态。

node-monitor-grace-period

指定 Kubernetes 控制器管理器在将节点标记为不健康并在节点上添加node.kubernetes.io/not-readynode.kubernetes.io/unreachable污点之前等待 kubelet 更新的时间(以秒为单位)。

default-not-ready-toleration-seconds

指定将节点标记为不健康后,Kube API 服务器操作符在从该节点驱逐 Pod 之前等待的时间(以秒为单位)。

default-unreachable-toleration-seconds

指定将节点标记为不可达后,Kube API 服务器操作符在从该节点驱逐 Pod 之前等待的时间(以秒为单位)。

以下操作符监控对工作节点延迟配置文件的更改并做出相应的响应

  • 机器配置操作符 (MCO) 更新工作节点上的node-status-update-frequency参数。

  • Kubernetes 控制器管理器更新控制平面节点上的node-monitor-grace-period参数。

  • Kubernetes API 服务器操作符更新控制平面节点上的default-not-ready-toleration-secondsdefault-unreachable-toleration-seconds参数。

虽然默认配置在大多数情况下都能正常工作,但 OpenShift Container Platform 还提供了另外两个工作节点延迟配置文件,用于网络延迟高于平常的情况。以下部分描述了三个工作节点延迟配置文件

默认工作节点延迟配置文件

使用Default配置文件,每个Kubelet每10秒(node-status-update-frequency)更新一次其状态。Kube Controller Manager每5秒检查一次Kubelet的状态。

Kubernetes 控制器管理器等待 40 秒 (node-monitor-grace-period) 来获取来自 Kubelet 的状态更新,之后才会认为 Kubelet 不健康。如果 Kubernetes 控制器管理器无法获取状态更新,则会为该节点添加 node.kubernetes.io/not-readynode.kubernetes.io/unreachable taint 并驱逐该节点上的 Pod。

如果 Pod 位于带有 NoExecute taint 的节点上,则 Pod 会根据 tolerationSeconds 运行。如果节点没有 taint,则会在 300 秒后被驱逐 (Kube API Serverdefault-not-ready-toleration-secondsdefault-unreachable-toleration-seconds 设置)。

配置文件 组件 参数

默认值

kubelet

node-status-update-frequency

10s

Kubelet 控制器管理器

node-monitor-grace-period

40s

Kubernetes API 服务器操作员

default-not-ready-toleration-seconds

300s

Kubernetes API 服务器操作员

default-unreachable-toleration-seconds

300s

中等工作负载延迟配置文件

如果网络延迟略高于通常情况,请使用 MediumUpdateAverageReaction 配置文件。

MediumUpdateAverageReaction 配置文件将 kubelet 更新频率降低到 20 秒,并将 Kubernetes 控制器管理器等待这些更新的时间更改为 2 分钟。该节点上 Pod 的驱逐时间缩短为 60 秒。如果 Pod 具有 tolerationSeconds 参数,则驱逐将等待该参数指定的时间。

Kubernetes 控制器管理器等待 2 分钟才会认为节点不健康。再过一分钟,驱逐过程开始。

配置文件 组件 参数

MediumUpdateAverageReaction

kubelet

node-status-update-frequency

20s

Kubelet 控制器管理器

node-monitor-grace-period

2m

Kubernetes API 服务器操作员

default-not-ready-toleration-seconds

60s

Kubernetes API 服务器操作员

default-unreachable-toleration-seconds

60s

低工作负载延迟配置文件

如果网络延迟极高,请使用 LowUpdateSlowReaction 配置文件。

LowUpdateSlowReaction 配置文件将 kubelet 更新频率降低到 1 分钟,并将 Kubernetes 控制器管理器等待这些更新的时间更改为 5 分钟。该节点上 Pod 的驱逐时间缩短为 60 秒。如果 Pod 具有 tolerationSeconds 参数,则驱逐将等待该参数指定的时间。

Kubernetes 控制器管理器等待 5 分钟才会认为节点不健康。再过一分钟,驱逐过程开始。

配置文件 组件 参数

LowUpdateSlowReaction

kubelet

node-status-update-frequency

1m

Kubelet 控制器管理器

node-monitor-grace-period

5m

Kubernetes API 服务器操作员

default-not-ready-toleration-seconds

60s

Kubernetes API 服务器操作员

default-unreachable-toleration-seconds

60s

使用和更改工作负载延迟配置文件

要更改工作负载延迟配置文件以应对网络延迟,请编辑 node.config 对象以添加配置文件的名称。随着延迟的增加或减少,您可以随时更改配置文件。

您必须一次更改一个工作负载延迟配置文件。例如,您不能直接从 Default 配置文件切换到 LowUpdateSlowReaction 工作负载延迟配置文件。您必须首先从 Default 工作负载延迟配置文件切换到 MediumUpdateAverageReaction 配置文件,然后再切换到 LowUpdateSlowReaction。同样,当返回到 Default 配置文件时,您必须首先从低配置文件切换到中等配置文件,然后再切换到 Default

您还可以在安装 OpenShift Container Platform 集群时配置工作负载延迟配置文件。

步骤

要从默认工作负载延迟配置文件切换

  1. 切换到中等工作负载延迟配置文件

    1. 编辑 node.config 对象

      $ oc edit nodes.config/cluster
    2. 添加 spec.workerLatencyProfile: MediumUpdateAverageReaction

      node.config 对象示例
      apiVersion: config.openshift.io/v1
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v1
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        workerLatencyProfile: MediumUpdateAverageReaction (1)
      
      # ...
      1 指定中等工作负载延迟策略。

      在应用更改期间,每个工作节点上的调度都被禁用。

  2. 可选:切换到低工作负载延迟配置文件

    1. 编辑 node.config 对象

      $ oc edit nodes.config/cluster
    2. spec.workerLatencyProfile 值更改为 LowUpdateSlowReaction

      node.config 对象示例
      apiVersion: config.openshift.io/v1
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v1
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        workerLatencyProfile: LowUpdateSlowReaction (1)
      
      # ...
      1 指定使用低工作负载延迟策略。

在应用更改期间,每个工作节点上的调度都被禁用。

验证
  • 当所有节点都返回到 Ready 状态时,您可以使用以下命令查看 Kubernetes 控制器管理器以确保已应用该策略

    $ oc get KubeControllerManager -o yaml | grep -i workerlatency -A 5 -B 5
    示例输出
    # ...
        - lastTransitionTime: "2022-07-11T19:47:10Z"
          reason: ProfileUpdated
          status: "False"
          type: WorkerLatencyProfileProgressing
        - lastTransitionTime: "2022-07-11T19:47:10Z" (1)
          message: all static pod revision(s) have updated latency profile
          reason: ProfileUpdated
          status: "True"
          type: WorkerLatencyProfileComplete
        - lastTransitionTime: "2022-07-11T19:20:11Z"
          reason: AsExpected
          status: "False"
          type: WorkerLatencyProfileDegraded
        - lastTransitionTime: "2022-07-11T19:20:36Z"
          status: "False"
    # ...
    1 指定配置文件已应用并处于活动状态。

要将中等配置文件更改为默认配置文件或将默认配置文件更改为中等配置文件,请编辑 node.config 对象并将 spec.workerLatencyProfile 参数设置为相应的值。

管理控制平面机器

控制平面机器集 提供了用于管理控制平面机器的功能,类似于计算机器集为计算机器提供的功能。集群上控制平面机器集的可用性和初始状态取决于您的云提供商和您安装的 OpenShift Container Platform 版本。有关更多信息,请参阅 控制平面机器集入门

为生产环境创建基础设施机器集

您可以创建一个计算机器集来创建仅托管基础设施组件(例如默认路由器、集成容器镜像注册表以及集群指标和监控组件)的机器。这些基础设施机器不计入运行环境所需的订阅总数。

在生产部署中,建议您部署至少三个计算机器集来容纳基础设施组件。OpenShift Logging 和 Red Hat OpenShift Service Mesh 都部署 Elasticsearch,这需要在不同的节点上安装三个实例。为了实现高可用性,可以将这些节点部署到不同的可用区。这种配置需要三个不同的计算机器集,每个可用区一个。在没有多个可用区的全球 Azure 区域中,您可以使用可用性集来确保高可用性。

有关基础设施节点以及哪些组件可以在基础设施节点上运行的信息,请参阅 创建基础设施机器集

要创建基础设施节点,您可以 使用机器集为节点分配标签使用机器配置池

有关您可以与这些过程一起使用的机器集示例,请参阅 为不同的云创建机器集

将特定的节点选择器应用于所有基础设施组件会导致 OpenShift Container Platform 将这些工作负载调度到具有该标签的节点上

创建计算机器集

除了安装程序创建的计算机器集之外,您还可以创建自己的计算机器集,以动态管理您选择的特定工作负载的机器计算资源。

先决条件
  • 部署 OpenShift Container Platform 集群。

  • 安装 OpenShift CLI (oc)。

  • 以具有 cluster-admin 权限的用户身份登录 oc

步骤
  1. 创建一个新的 YAML 文件,其中包含计算机器集自定义资源 (CR) 示例,并将其命名为<file_name>.yaml

    确保设置<clusterID><role> 参数值。

  2. 可选:如果您不确定为特定字段设置哪个值,您可以检查集群中现有的计算机器集。

    1. 要列出集群中的计算机器集,请运行以下命令:

      $ oc get machinesets -n openshift-machine-api
      示例输出
      NAME                                DESIRED   CURRENT   READY   AVAILABLE   AGE
      agl030519-vplxk-worker-us-east-1a   1         1         1       1           55m
      agl030519-vplxk-worker-us-east-1b   1         1         1       1           55m
      agl030519-vplxk-worker-us-east-1c   1         1         1       1           55m
      agl030519-vplxk-worker-us-east-1d   0         0                             55m
      agl030519-vplxk-worker-us-east-1e   0         0                             55m
      agl030519-vplxk-worker-us-east-1f   0         0                             55m
    2. 要查看特定计算机器集自定义资源 (CR) 的值,请运行以下命令:

      $ oc get machineset <machineset_name> \
        -n openshift-machine-api -o yaml
      示例输出
      apiVersion: machine.openshift.io/v1beta1
      kind: MachineSet
      metadata:
        labels:
          machine.openshift.io/cluster-api-cluster: <infrastructure_id> (1)
        name: <infrastructure_id>-<role> (2)
        namespace: openshift-machine-api
      spec:
        replicas: 1
        selector:
          matchLabels:
            machine.openshift.io/cluster-api-cluster: <infrastructure_id>
            machine.openshift.io/cluster-api-machineset: <infrastructure_id>-<role>
        template:
          metadata:
            labels:
              machine.openshift.io/cluster-api-cluster: <infrastructure_id>
              machine.openshift.io/cluster-api-machine-role: <role>
              machine.openshift.io/cluster-api-machine-type: <role>
              machine.openshift.io/cluster-api-machineset: <infrastructure_id>-<role>
          spec:
            providerSpec: (3)
              ...
      1 集群基础设施 ID。
      2 默认节点标签。

      对于具有用户预配基础设施的集群,计算机器集只能创建workerinfra 类型机器。

      3 计算机器集 CR 的<providerSpec> 部分中的值是特定于平台的。有关 CR 中<providerSpec> 参数的更多信息,请参阅您的提供商的示例计算机器集 CR 配置。
  3. 运行以下命令创建MachineSet CR:

    $ oc create -f <file_name>.yaml
验证
  • 运行以下命令查看计算机器集列表:

    $ oc get machineset -n openshift-machine-api
    示例输出
    NAME                                DESIRED   CURRENT   READY   AVAILABLE   AGE
    agl030519-vplxk-infra-us-east-1a    1         1         1       1           11m
    agl030519-vplxk-worker-us-east-1a   1         1         1       1           55m
    agl030519-vplxk-worker-us-east-1b   1         1         1       1           55m
    agl030519-vplxk-worker-us-east-1c   1         1         1       1           55m
    agl030519-vplxk-worker-us-east-1d   0         0                             55m
    agl030519-vplxk-worker-us-east-1e   0         0                             55m
    agl030519-vplxk-worker-us-east-1f   0         0                             55m

    当新的计算机器集可用时,DESIREDCURRENT 值匹配。如果计算机器集不可用,请等待几分钟,然后再次运行该命令。

创建基础设施节点

请参阅为安装程序预配的基础设施环境或控制平面节点由机器 API 管理的任何集群创建基础设施机器集。

集群的要求规定必须预配基础设施节点(也称为infra 节点)。安装程序仅提供控制平面节点和工作节点的预配。工作节点可以通过标签指定为基础设施节点或应用程序节点(也称为app 节点)。

步骤
  1. 为要充当应用程序节点的工作节点添加标签

    $ oc label node <node-name> node-role.kubernetes.io/app=""
  2. 为要充当基础设施节点的工作节点添加标签

    $ oc label node <node-name> node-role.kubernetes.io/infra=""
  3. 检查适用的节点是否现在具有infra 角色和app 角色

    $ oc get nodes
  4. 创建一个默认的集群范围节点选择器。默认节点选择器应用于在所有命名空间中创建的 Pod。这会与 Pod 上任何现有的节点选择器相交,从而进一步限制 Pod 的选择器。

    如果默认节点选择器键与 Pod 标签的键冲突,则不会应用默认节点选择器。

    但是,请勿设置可能导致 Pod 无法调度的默认节点选择器。例如,当 Pod 的标签设置为不同的节点角色(例如node-role.kubernetes.io/master="")时,将默认节点选择器设置为特定节点角色(例如node-role.kubernetes.io/infra="")可能会导致 Pod 无法调度。因此,在将默认节点选择器设置为特定节点角色时,请谨慎操作。

    或者,您可以使用项目节点选择器来避免集群范围的节点选择器键冲突。

    1. 编辑Scheduler 对象

      $ oc edit scheduler cluster
    2. 添加带有适当节点选择器的defaultNodeSelector 字段

      apiVersion: config.openshift.io/v1
      kind: Scheduler
      metadata:
        name: cluster
      spec:
        defaultNodeSelector: node-role.kubernetes.io/infra="" (1)
      # ...
      1 此示例节点选择器默认情况下将 Pod 部署到基础设施节点。
    3. 保存文件以应用更改。

您现在可以将基础设施资源移动到新标记的infra 节点。

其他资源
  • 有关如何配置项目节点选择器以避免集群范围的节点选择器键冲突的信息,请参阅 项目节点选择器

为基础设施机器创建机器配置池

如果需要基础设施机器具有专用配置,则必须创建一个 infra 池。

如果自定义机器配置池与默认工作程序池配置引用相同的文件或单元,则会覆盖默认工作程序池配置。

步骤
  1. 为要分配为具有特定标签的 infra 节点的节点添加标签

    $ oc label node <node_name> <label>
    $ oc label node ci-ln-n8mqwr2-f76d1-xscn2-worker-c-6fmtx node-role.kubernetes.io/infra=
  2. 创建一个机器配置池,其中包含工作程序角色和自定义角色作为机器配置选择器

    $ cat infra.mcp.yaml
    示例输出
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      name: infra
    spec:
      machineConfigSelector:
        matchExpressions:
          - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,infra]} (1)
      nodeSelector:
        matchLabels:
          node-role.kubernetes.io/infra: "" (2)
    1 添加工作程序角色和您的自定义角色。
    2 将您添加到节点的标签添加为nodeSelector

    自定义机器配置池继承自工作程序池的机器配置。自定义池使用针对工作程序池的目标任何机器配置,但还增加了仅针对自定义池部署更改的功能。因为自定义池继承自工作程序池的资源,所以对工作程序池的任何更改也会影响自定义池。

  3. 拥有 YAML 文件后,您可以创建机器配置池

    $ oc create -f infra.mcp.yaml
  4. 检查机器配置以确保基础设施配置已成功呈现

    $ oc get machineconfig
    示例输出
    NAME                                                        GENERATEDBYCONTROLLER                      IGNITIONVERSION   CREATED
    00-master                                                   365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    00-worker                                                   365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    01-master-container-runtime                                 365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    01-master-kubelet                                           365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    01-worker-container-runtime                                 365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    01-worker-kubelet                                           365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    99-master-1ae2a1e0-a115-11e9-8f14-005056899d54-registries   365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    99-master-ssh                                                                                          3.2.0             31d
    99-worker-1ae64748-a115-11e9-8f14-005056899d54-registries   365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             31d
    99-worker-ssh                                                                                          3.2.0             31d
    rendered-infra-4e48906dca84ee702959c71a53ee80e7             365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             23m
    rendered-master-072d4b2da7f88162636902b074e9e28e            5b6fb8349a29735e48446d435962dec4547d3090   3.2.0             31d
    rendered-master-3e88ec72aed3886dec061df60d16d1af            02c07496ba0417b3e12b78fb32baf6293d314f79   3.2.0             31d
    rendered-master-419bee7de96134963a15fdf9dd473b25            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             17d
    rendered-master-53f5c91c7661708adce18739cc0f40fb            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             13d
    rendered-master-a6a357ec18e5bce7f5ac426fc7c5ffcd            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             7d3h
    rendered-master-dc7f874ec77fc4b969674204332da037            5b6fb8349a29735e48446d435962dec4547d3090   3.2.0             31d
    rendered-worker-1a75960c52ad18ff5dfa6674eb7e533d            5b6fb8349a29735e48446d435962dec4547d3090   3.2.0             31d
    rendered-worker-2640531be11ba43c61d72e82dc634ce6            5b6fb8349a29735e48446d435962dec4547d3090   3.2.0             31d
    rendered-worker-4e48906dca84ee702959c71a53ee80e7            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             7d3h
    rendered-worker-4f110718fe88e5f349987854a1147755            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             17d
    rendered-worker-afc758e194d6188677eb837842d3b379            02c07496ba0417b3e12b78fb32baf6293d314f79   3.2.0             31d
    rendered-worker-daa08cc1e8f5fcdeba24de60cd955cc3            365c1cfd14de5b0e3b85e0fc815b0060f36ab955   3.2.0             13d

    您应该会看到一个新的机器配置,其前缀为rendered-infra-*

  5. 可选:要将更改部署到自定义池,请创建一个使用自定义池名称作为标签(例如infra)的机器配置。请注意,这不是必需的,仅出于教学目的而显示。通过这种方式,您可以应用仅特定于 infra 节点的任何自定义配置。

    创建新的机器配置池后,MCO 会为该池生成新的渲染配置,并且该池的相关节点将重新启动以应用新配置。

    1. 创建一个机器配置

      $ cat infra.mc.yaml
      示例输出
      apiVersion: machineconfiguration.openshift.io/v1
      kind: MachineConfig
      metadata:
        name: 51-infra
        labels:
          machineconfiguration.openshift.io/role: infra (1)
      spec:
        config:
          ignition:
            version: 3.2.0
          storage:
            files:
            - path: /etc/infratest
              mode: 0644
              contents:
                source: data:,infra
      1 将您添加到节点的标签添加为nodeSelector
    2. 将机器配置应用于 infra 标记的节点

      $ oc create -f infra.mc.yaml
  6. 确认您的新的机器配置池可用

    $ oc get mcp
    示例输出
    NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
    infra    rendered-infra-60e35c2e99f42d976e084fa94da4d0fc    True      False      False      1              1                   1                     0                      4m20s
    master   rendered-master-9360fdb895d4c131c7c4bebbae099c90   True      False      False      3              3                   3                     0                      91m
    worker   rendered-worker-60e35c2e99f42d976e084fa94da4d0fc   True      False      False      2              2                   2                     0                      91m

    在此示例中,工作节点已更改为 infra 节点。

其他资源

将机器集资源分配给基础设施节点

创建基础设施机器集后,workerinfra 角色将应用于新的 infra 节点。即使也应用了worker 角色,具有infra 角色的节点也不会计入运行环境所需的订阅总数。

但是,当为 infra 节点分配 worker 角色时,用户工作负载可能会意外地分配给 infra 节点。为避免这种情况,您可以对 infra 节点应用污点,并对要控制的 Pod 应用容忍。

使用污点和容忍绑定基础设施节点工作负载

如果您的基础设施节点已分配infraworker角色,则必须配置该节点以使其不分配用户工作负载。

建议保留为基础设施节点创建的双重infra,worker标签,并使用污点和容忍度来管理调度用户工作负载的节点。如果从节点中删除worker标签,则必须创建一个自定义池来管理它。除非有自定义池,否则MCO无法识别标签不是masterworker的节点。如果不存在选择自定义标签的自定义池,则保留worker标签允许节点由默认的工作机配置池管理。infra标签会向集群传达它不计入订阅总数的信息。

先决条件
  • 在OpenShift Container Platform集群中配置额外的MachineSet对象。

步骤
  1. 向基础设施节点添加污点以阻止在其上调度用户工作负载

    1. 确定节点是否具有污点

      $ oc describe nodes <node_name>
      示例输出
      oc describe node ci-ln-iyhx092-f76d1-nvdfm-worker-b-wln2l
      Name:               ci-ln-iyhx092-f76d1-nvdfm-worker-b-wln2l
      Roles:              worker
       ...
      Taints:             node-role.kubernetes.io/infra:NoSchedule
       ...

      此示例显示该节点具有污点。您可以继续执行下一步,在您的Pod中添加容忍度。

    2. 如果您尚未配置污点以阻止在其上调度用户工作负载

      $ oc adm taint nodes <node_name> <key>=<value>:<effect>

      例如

      $ oc adm taint nodes node1 node-role.kubernetes.io/infra=reserved:NoSchedule

      您可以选择应用以下YAML来添加污点

      kind: Node
      apiVersion: v1
      metadata:
        name: <node_name>
        labels:
          ...
      spec:
        taints:
          - key: node-role.kubernetes.io/infra
            effect: NoSchedule
            value: reserved
        ...

      此示例在node1上放置一个污点,该污点具有键node-role.kubernetes.io/infra和污点效果NoSchedule。具有NoSchedule效果的节点仅调度容忍该污点的Pod,但允许现有Pod保留在节点上调度。

      如果使用调度程序,则违反节点污点的Pod可能会被从集群中驱逐。

    3. 除了上面带有NoSchedule效果的污点外,还要添加具有NoExecute效果的污点

      $ oc adm taint nodes <node_name> <key>=<value>:<effect>

      例如

      $ oc adm taint nodes node1 node-role.kubernetes.io/infra=reserved:NoExecute

      您可以选择应用以下YAML来添加污点

      kind: Node
      apiVersion: v1
      metadata:
        name: <node_name>
        labels:
          ...
      spec:
        taints:
          - key: node-role.kubernetes.io/infra
            effect: NoExecute
            value: reserved
        ...

      此示例在node1上放置一个污点,该污点具有键node-role.kubernetes.io/infra和污点效果NoExecute。具有NoExecute效果的节点仅调度容忍该污点的Pod。此效果将删除节点上任何没有匹配容忍度的现有Pod。

  2. 为要在基础设施节点上调度的Pod配置(如路由器、注册表和监控工作负载)添加容忍度。将以下代码添加到Pod对象规范中

    tolerations:
      - effect: NoSchedule (1)
        key: node-role.kubernetes.io/infra (2)
        value: reserved (3)
      - effect: NoExecute (4)
        key: node-role.kubernetes.io/infra (5)
        operator: Exists (6)
        value: reserved (7)
    1 指定您添加到节点的效果。
    2 指定您添加到节点的键。
    3 指定您添加到节点的键值对污点的值。
    4 指定您添加到节点的效果。
    5 指定您添加到节点的键。
    6 指定Exists运算符以要求节点上存在具有键node-role.kubernetes.io/infra的污点。
    7 指定您添加到节点的键值对污点的值。

    此容忍度与oc adm taint命令创建的污点匹配。具有此容忍度的Pod可以调度到基础设施节点上。

    将通过OLM安装的Operator的Pod移动到基础设施节点并非总是可能的。移动Operator Pod的能力取决于每个Operator的配置。

  3. 使用调度程序将Pod调度到基础设施节点。有关详细信息,请参阅有关“控制Pod放置到节点”的文档。

其他资源

将资源移动到基础设施机器集

默认情况下,一些基础设施资源已部署在您的集群中。您可以将它们移动到您创建的基础设施机器集。

移动路由器

您可以将路由器Pod部署到不同的计算机器集。默认情况下,Pod部署到工作节点。

先决条件
  • 在OpenShift Container Platform集群中配置额外的计算机器集。

步骤
  1. 查看路由器Operator的IngressController自定义资源

    $ oc get ingresscontroller default -n openshift-ingress-operator -o yaml

    命令输出类似于以下文本

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      creationTimestamp: 2019-04-18T12:35:39Z
      finalizers:
      - ingresscontroller.operator.openshift.io/finalizer-ingresscontroller
      generation: 1
      name: default
      namespace: openshift-ingress-operator
      resourceVersion: "11341"
      selfLink: /apis/operator.openshift.io/v1/namespaces/openshift-ingress-operator/ingresscontrollers/default
      uid: 79509e05-61d6-11e9-bc55-02ce4781844a
    spec: {}
    status:
      availableReplicas: 2
      conditions:
      - lastTransitionTime: 2019-04-18T12:36:15Z
        status: "True"
        type: Available
      domain: apps.<cluster>.example.com
      endpointPublishingStrategy:
        type: LoadBalancerService
      selector: ingresscontroller.operator.openshift.io/deployment-ingresscontroller=default
  2. 编辑ingresscontroller资源并将nodeSelector更改为使用infra标签

    $ oc edit ingresscontroller default -n openshift-ingress-operator
      spec:
        nodePlacement:
          nodeSelector: (1)
            matchLabels:
              node-role.kubernetes.io/infra: ""
          tolerations:
          - effect: NoSchedule
            key: node-role.kubernetes.io/infra
            value: reserved
          - effect: NoExecute
            key: node-role.kubernetes.io/infra
            value: reserved
    1 将具有适当值的nodeSelector参数添加到要移动的组件。您可以使用所示格式的nodeSelector,也可以使用<key>: <value>对,具体取决于为节点指定的值。如果您向基础设施节点添加了污点,也请添加匹配的容忍度。
  3. 确认路由器Pod正在infra节点上运行。

    1. 查看路由器Pod列表,并记下正在运行的Pod的节点名称

      $ oc get pod -n openshift-ingress -o wide
      示例输出
      NAME                              READY     STATUS        RESTARTS   AGE       IP           NODE                           NOMINATED NODE   READINESS GATES
      router-default-86798b4b5d-bdlvd   1/1      Running       0          28s       10.130.2.4   ip-10-0-217-226.ec2.internal   <none>           <none>
      router-default-955d875f4-255g8    0/1      Terminating   0          19h       10.129.2.4   ip-10-0-148-172.ec2.internal   <none>           <none>

      在此示例中,正在运行的Pod位于ip-10-0-217-226.ec2.internal节点上。

    2. 查看正在运行的Pod的节点状态

      $ oc get node <node_name> (1)
      1 指定从Pod列表中获得的<node_name>
      示例输出
      NAME                          STATUS  ROLES         AGE   VERSION
      ip-10-0-217-226.ec2.internal  Ready   infra,worker  17h   v1.30.3

      因为角色列表包含infra,所以Pod正在正确的节点上运行。

移动默认注册表

您可以配置注册表Operator将其Pod部署到不同的节点。

先决条件
  • 在OpenShift Container Platform集群中配置额外的计算机器集。

步骤
  1. 查看config/instance对象

    $ oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
    示例输出
    apiVersion: imageregistry.operator.openshift.io/v1
    kind: Config
    metadata:
      creationTimestamp: 2019-02-05T13:52:05Z
      finalizers:
      - imageregistry.operator.openshift.io/finalizer
      generation: 1
      name: cluster
      resourceVersion: "56174"
      selfLink: /apis/imageregistry.operator.openshift.io/v1/configs/cluster
      uid: 36fd3724-294d-11e9-a524-12ffeee2931b
    spec:
      httpSecret: d9a012ccd117b1e6616ceccb2c3bb66a5fed1b5e481623
      logging: 2
      managementState: Managed
      proxy: {}
      replicas: 1
      requests:
        read: {}
        write: {}
      storage:
        s3:
          bucket: image-registry-us-east-1-c92e88cad85b48ec8b312344dff03c82-392c
          region: us-east-1
    status:
    ...
  2. 编辑config/instance对象

    $ oc edit configs.imageregistry.operator.openshift.io/cluster
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              namespaces:
              - openshift-image-registry
              topologyKey: kubernetes.io/hostname
            weight: 100
      logLevel: Normal
      managementState: Managed
      nodeSelector: (1)
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    1 将具有适当值的nodeSelector参数添加到要移动的组件。您可以使用所示格式的nodeSelector,也可以使用<key>: <value>对,具体取决于为节点指定的值。如果您向基础设施节点添加了污点,也请添加匹配的容忍度。
  3. 验证注册表Pod已移动到基础设施节点。

    1. 运行以下命令以识别注册表Pod所在的节点

      $ oc get pods -o wide -n openshift-image-registry
    2. 确认节点具有您指定的标签

      $ oc describe node <node_name>

      查看命令输出并确认node-role.kubernetes.io/infraLABELS列表中。

移动监控解决方案

监控堆栈包括多个组件,包括Prometheus、Thanos Querier和Alertmanager。集群监控Operator管理此堆栈。要将监控堆栈重新部署到基础设施节点,您可以创建并应用自定义ConfigMap。

步骤
  1. 编辑cluster-monitoring-config ConfigMap并将nodeSelector更改为使用infra标签

    $ oc edit configmap cluster-monitoring-config -n openshift-monitoring
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cluster-monitoring-config
      namespace: openshift-monitoring
    data:
      config.yaml: |+
        alertmanagerMain:
          nodeSelector: (1)
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        prometheusK8s:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        prometheusOperator:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        metricsServer:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        kubeStateMetrics:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        telemeterClient:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        openshiftStateMetrics:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        thanosQuerier:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
        monitoringPlugin:
          nodeSelector:
            node-role.kubernetes.io/infra: ""
          tolerations:
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoSchedule
          - key: node-role.kubernetes.io/infra
            value: reserved
            effect: NoExecute
    1 将具有适当值的nodeSelector参数添加到要移动的组件。您可以使用所示格式的nodeSelector,也可以使用<key>: <value>对,具体取决于为节点指定的值。如果您向基础设施节点添加了污点,也请添加匹配的容忍度。
  2. 观察监控Pod移动到新机器

    $ watch 'oc get pod -n openshift-monitoring -o wide'
  3. 如果某个组件未移动到infra节点,请删除包含此组件的Pod

    $ oc delete pod -n openshift-monitoring <pod>

    已删除Pod中的组件将在infra节点上重新创建。

将自动缩放应用于您的集群

将自动缩放应用于OpenShift Container Platform集群涉及部署集群自动缩放器,然后为集群中的每种机器类型部署机器自动缩放器。

配置Linux cgroup

从 OpenShift Container Platform 4.14 版本开始,OpenShift Container Platform 在您的集群中使用Linux 控制组版本 2 (cgroup v2)。如果您在 OpenShift Container Platform 4.13 或更早版本中使用 cgroup v1,迁移到 OpenShift Container Platform 4.14 或更高版本不会自动将您的 cgroup 配置更新到版本 2。OpenShift Container Platform 4.14 或更高版本的新安装将默认使用 cgroup v2。但是,您可以在安装时启用Linux 控制组版本 1 (cgroup v1)。

cgroup v2 是当前版本的 Linux cgroup API。cgroup v2 比 cgroup v1 提供了几项改进,包括统一的层次结构、更安全的子树委派、新功能(例如压力停滞信息)以及增强的资源管理和隔离。但是,cgroup v2 与 cgroup v1 的 CPU、内存和 I/O 管理特性不同。因此,某些工作负载在运行 cgroup v2 的集群上的内存或 CPU 使用情况可能略有不同。

您可以根据需要在 cgroup v1 和 cgroup v2 之间切换。在 OpenShift Container Platform 中启用 cgroup v1 会禁用集群中的所有 cgroup v2 控制器和层次结构。

cgroup v1 是一个已弃用的功能。OpenShift Container Platform 中仍然包含已弃用的功能,并且继续受支持;但是,它将在该产品的未来版本中删除,不建议用于新的部署。

有关 OpenShift Container Platform 中已弃用或删除的主要功能的最新列表,请参阅 OpenShift Container Platform 发行说明中的“已弃用和删除的功能”部分。

先决条件
  • 您有一个运行 OpenShift Container Platform 集群,该集群使用 4.12 或更高版本。

  • 您已以具有管理权限的用户身份登录到集群。

步骤
  1. 在节点上启用 cgroup v1

    1. 编辑 node.config 对象

      $ oc edit nodes.config/cluster
    2. 添加 spec.cgroupMode: "v1"

      node.config 对象示例
      apiVersion: config.openshift.io/v2
      kind: Node
      metadata:
        annotations:
          include.release.openshift.io/ibm-cloud-managed: "true"
          include.release.openshift.io/self-managed-high-availability: "true"
          include.release.openshift.io/single-node-developer: "true"
          release.openshift.io/create-only: "true"
        creationTimestamp: "2022-07-08T16:02:51Z"
        generation: 1
        name: cluster
        ownerReferences:
        - apiVersion: config.openshift.io/v2
          kind: ClusterVersion
          name: version
          uid: 36282574-bf9f-409e-a6cd-3032939293eb
        resourceVersion: "1865"
        uid: 0c0f7a4c-4307-4187-b591-6155695ac85b
      spec:
        cgroupMode: "v1" (1)
      ...
      1 启用 cgroup v1。
验证
  1. 检查机器配置以查看是否添加了新的机器配置

    $ oc get mc
    示例输出
    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    97-master-generated-kubelet                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-generated-kubelet                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23d4317815a5f854bd3553d689cfe2e9   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             10s (1)
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-dcc7f1b92892d34db74d6832bcc9ccd4   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             10s
    1 如预期的那样创建了新的机器配置。
  2. 检查是否将新的 kernelArguments 添加到新的机器配置中

    $ oc describe mc <name>
    cgroup v1 的示例输出
    apiVersion: machineconfiguration.openshift.io/v2
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 05-worker-kernelarg-selinuxpermissive
    spec:
      kernelArguments:
        systemd.unified_cgroup_hierarchy=0 (1)
        systemd.legacy_systemd_cgroup_controller=1 (2)
    
    1 禁用 cgroup v2。
    2 在 systemd 中启用 cgroup v1。
  3. 检查节点以查看节点上的调度是否已禁用。这表示正在应用更改

    $ oc get nodes
    示例输出
    NAME                                       STATUS                     ROLES    AGE   VERSION
    ci-ln-fm1qnwt-72292-99kt6-master-0         Ready,SchedulingDisabled   master   58m   v1.30.3
    ci-ln-fm1qnwt-72292-99kt6-master-1         Ready                      master   58m   v1.30.3
    ci-ln-fm1qnwt-72292-99kt6-master-2         Ready                      master   58m   v1.30.3
    ci-ln-fm1qnwt-72292-99kt6-worker-a-h5gt4   Ready,SchedulingDisabled   worker   48m   v1.30.3
    ci-ln-fm1qnwt-72292-99kt6-worker-b-7vtmd   Ready                      worker   48m   v1.30.3
    ci-ln-fm1qnwt-72292-99kt6-worker-c-rhzkv   Ready                      worker   48m   v1.30.3
  4. 节点返回到就绪状态后,启动该节点的调试会话

    $ oc debug node/<node_name>
  5. /host设置为调试 shell 中的根目录

    sh-4.4# chroot /host
  6. 检查节点上是否存在sys/fs/cgroup/cgroup2fs文件。此文件由 cgroup v1 创建

    $ stat -c %T -f /sys/fs/cgroup
    示例输出
    cgroup2fs

使用 FeatureGates 启用技术预览功能

您可以通过编辑FeatureGate自定义资源 (CR) 来为集群中的所有节点启用当前技术预览功能的子集。

了解功能开关

您可以使用FeatureGate自定义资源 (CR) 在集群中启用特定的功能集。功能集是默认情况下未启用的 OpenShift Container Platform 功能的集合。

您可以使用FeatureGate CR 激活以下功能集

  • TechPreviewNoUpgrade。此功能集是当前技术预览功能的子集。此功能集允许您在测试集群上启用这些技术预览功能,您可以在其中对其进行全面测试,同时在生产集群上禁用这些功能。

    在您的集群上启用TechPreviewNoUpgrade功能集是不可撤消的,并且会阻止次要版本更新。您不应在生产集群上启用此功能集。

    此功能集启用了以下技术预览功能

    • 外部云提供商。为 vSphere、AWS、Azure 和 GCP 上的集群启用对外部云提供商的支持。对 OpenStack 的支持已达到 GA 级别。这是一个内部功能,大多数用户不需要与之交互。(ExternalCloudProvider

    • 节点上的交换内存。按节点启用 OpenShift Container Platform 工作负载的交换内存使用。(NodeSwap

    • OpenStack 机器 API 提供程序。此开关无效,计划在未来版本中从此功能集中删除。(MachineAPIProviderOpenStack

    • Insights 运算符。启用InsightsDataGather CRD,允许用户配置一些 Insights 数据收集选项。此功能集还启用DataGather CRD,允许用户按需运行 Insights 数据收集。(InsightsConfigAPI

    • 动态资源分配 API。启用用于请求和共享 pod 和容器之间资源的新 API。这是一个内部功能,大多数用户不需要与之交互。(DynamicResourceAllocation

    • Pod 安全准入强制执行。为 Pod 安全准入启用受限强制模式。如果 Pod 违反 Pod 安全标准,则不会仅记录警告,而是会拒绝 Pod。(OpenShiftPodSecurityAdmission

    • StatefulSet Pod 可用性升级限制。允许用户定义更新期间状态集 Pod 的最大不可用数量,从而减少应用程序停机时间。(MaxUnavailableStatefulSet

    • gcpLabelsTags

    • vSphereStaticIPs

    • routeExternalCertificate

    • automatedEtcdBackup

    • gcpClusterHostedDNS

    • vSphereControlPlaneMachineset

    • dnsNameResolver

    • machineConfigNodes

    • metricsServer

    • installAlternateInfrastructureAWS

    • mixedCPUsAllocation

    • managedBootImages

    • onClusterBuild

    • signatureStores

    • SigstoreImageVerification

    • DisableKubeletCloudCredentialProviders

    • BareMetalLoadBalancer

    • ClusterAPIInstallAWS

    • ClusterAPIInstallAzure

    • ClusterAPIInstallNutanix

    • ClusterAPIInstallOpenStack

    • ClusterAPIInstallVSphere

    • HardwareSpeed

    • KMSv1

    • NetworkDiagnosticsConfig

    • VSphereDriverConfiguration

    • ExternalOIDC

    • ChunkSizeMiB

    • ClusterAPIInstallGCP

    • ClusterAPIInstallPowerVS

    • EtcdBackendQuota

    • InsightsConfig

    • InsightsOnDemandDataGather

    • MetricsCollectionProfiles

    • NewOLM

    • NodeDisruptionPolicy

    • PinnedImages

    • PlatformOperators

    • ServiceAccountTokenNodeBinding

    • TranslateStreamCloseWebsocketRequests

    • UpgradeStatus

    • VSphereMultiVCenters

    • VolumeGroupSnapshot

    • AdditionalRoutingCapabilities

    • BootcNodeManagement

    • ClusterMonitoringConfig

    • DNSNameResolver

    • ManagedBootImagesAWS

    • NetworkSegmentation

    • OVNObservability

    • PersistentIPsForVirtualization

    • ProcMountType

    • RouteAdvertisements

    • UserNamespacesSupport

    • AWSEFSDriverVolumeMetrics

    • AlibabaPlatform

    • AzureWorkloadIdentity

    • BuildCSIVolumes

    • CloudDualStackNodeIPs

    • ExternalCloudProviderAzure

    • ExternalCloudProviderExternal

    • ExternalCloudProviderGCP

    • IngressControllerLBSubnetsAWS

    • MultiArchInstallAWS

    • MultiArchInstallGCP

    • NetworkLiveMigration

    • PrivateHostedZoneAWS

    • SetEIPForNLBIngressController

    • ValidatingAdmissionPolicy

使用 Web 控制台启用功能集

您可以使用 OpenShift Container Platform Web 控制台通过编辑FeatureGate自定义资源 (CR) 来为集群中的所有节点启用功能集。

步骤

要启用功能集

  1. 在 OpenShift Container Platform Web 控制台中,切换到**管理**→**自定义资源定义**页面。

  2. 在**自定义资源定义**页面上,单击**FeatureGate**。

  3. 在**自定义资源定义详细信息**页面上,单击**实例**选项卡。

  4. 点击**集群**功能开关,然后点击**YAML**选项卡。

  5. 编辑**集群**实例以添加特定的功能集。

    在您的集群上启用TechPreviewNoUpgrade功能集是不可撤消的,并且会阻止次要版本更新。您不应在生产集群上启用此功能集。

    示例功能开关自定义资源
    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster (1)
    # ...
    spec:
      featureSet: TechPreviewNoUpgrade (2)
    1 FeatureGate CR 的名称必须为cluster
    2 添加要启用的功能集。
    • TechPreviewNoUpgrade启用特定的技术预览功能。

    保存更改后,将创建新的机器配置,机器配置池将更新,并且在应用更改期间,每个节点上的调度将被禁用。

验证

节点恢复到就绪状态后,您可以查看节点上的kubelet.conf文件来验证功能开关是否已启用。

  1. 在 Web 控制台中,从**管理员**角度导航到**计算** → **节点**。

  2. 选择一个节点。

  3. 在**节点详细信息**页面中,点击**终端**。

  4. 在终端窗口中,将根目录更改为/host

    sh-4.2# chroot /host
  5. 查看kubelet.conf文件。

    sh-4.2# cat /etc/kubernetes/kubelet.conf
    示例输出
    # ...
    featureGates:
      InsightsOperatorPullingSCA: true,
      LegacyNodeRoleBehavior: false
    # ...

    列为true的功能已在您的集群中启用。

    列出的功能会根据 OpenShift Container Platform 版本而有所不同。

使用 CLI 启用功能集

您可以使用 OpenShift CLI (oc) 通过编辑FeatureGate自定义资源 (CR) 来为集群中的所有节点启用功能集。

先决条件
  • 您已安装 OpenShift CLI (oc)。

步骤

要启用功能集

  1. 编辑名为clusterFeatureGate CR。

    $ oc edit featuregate cluster

    在您的集群上启用TechPreviewNoUpgrade功能集是不可撤消的,并且会阻止次要版本更新。您不应在生产集群上启用此功能集。

    示例 FeatureGate 自定义资源
    apiVersion: config.openshift.io/v1
    kind: FeatureGate
    metadata:
      name: cluster (1)
    # ...
    spec:
      featureSet: TechPreviewNoUpgrade (2)
    1 FeatureGate CR 的名称必须为cluster
    2 添加要启用的功能集。
    • TechPreviewNoUpgrade启用特定的技术预览功能。

    保存更改后,将创建新的机器配置,机器配置池将更新,并且在应用更改期间,每个节点上的调度将被禁用。

验证

节点恢复到就绪状态后,您可以查看节点上的kubelet.conf文件来验证功能开关是否已启用。

  1. 在 Web 控制台中,从**管理员**角度导航到**计算** → **节点**。

  2. 选择一个节点。

  3. 在**节点详细信息**页面中,点击**终端**。

  4. 在终端窗口中,将根目录更改为/host

    sh-4.2# chroot /host
  5. 查看kubelet.conf文件。

    sh-4.2# cat /etc/kubernetes/kubelet.conf
    示例输出
    # ...
    featureGates:
      InsightsOperatorPullingSCA: true,
      LegacyNodeRoleBehavior: false
    # ...

    列为true的功能已在您的集群中启用。

    列出的功能会根据 OpenShift Container Platform 版本而有所不同。

etcd 任务

备份 etcd、启用或禁用 etcd 加密或整理 etcd 数据。

如果您部署了裸机集群,则可以将集群扩展到 5 个节点作为安装后任务的一部分。有关更多信息,请参阅 etcd 的节点扩展

关于 etcd 加密

默认情况下,OpenShift Container Platform 中的 etcd 数据未加密。您可以为集群启用 etcd 加密以提供额外的數據安全层。例如,如果 etcd 备份暴露给错误的方,它可以帮助保护敏感数据丢失。

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

  • 密钥

  • 配置映射

  • 路由

  • OAuth 访问令牌

  • OAuth 授权令牌

启用 etcd 加密后,将创建加密密钥。您必须拥有这些密钥才能从 etcd 备份中恢复。

Etcd 加密仅加密值,不加密密钥。资源类型、命名空间和对象名称未加密。

如果在备份期间启用了 etcd 加密,则static_kuberesources_<datetimestamp>.tar.gz文件包含 etcd 快照的加密密钥。出于安全原因,请将此文件与 etcd 快照分开存储。但是,此文件是根据相应的 etcd 快照恢复 etcd 以前状态所必需的。

支持的加密类型

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

AES-CBC

使用带 PKCS#7 填充和 32 字节密钥的 AES-CBC 执行加密。加密密钥每周轮换一次。

AES-GCM

使用带随机 nonce 和 32 字节密钥的 AES-GCM 执行加密。加密密钥每周轮换一次。

启用 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
  2. spec.encryption.type字段设置为aesgcmaescbc

    spec:
      encryption:
        type: aesgcm (1)
    1 对于 AES-GCM 加密,设置为aesgcm;对于 AES-CBC 加密,设置为aescbc
  3. 保存文件以应用更改。

    加密过程开始。此过程的完成时间可能需要 20 分钟或更长时间,具体取决于 etcd 数据库的大小。

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

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

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

      成功加密后,输出显示EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: routes.route.openshift.io

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

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

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

      成功加密后,输出显示EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: secrets, configmaps

      如果输出显示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"}'

      成功加密后,输出显示EncryptionCompleted

      EncryptionCompleted
      All resources encrypted: oauthaccesstokens.oauth.openshift.io, oauthauthorizetokens.oauth.openshift.io

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

禁用 etcd 加密

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

先决条件
  • 以具有cluster-admin角色的用户身份访问集群。

步骤
  1. 修改APIServer对象。

    $ oc edit apiserver
  2. encryption字段类型设置为identity

    spec:
      encryption:
        type: identity (1)
    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"}'

      成功解密后,输出显示DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted

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

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

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

      成功解密后,输出显示DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted

      如果输出显示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"}'

      成功解密后,输出显示DecryptionCompleted

      DecryptionCompleted
      Encryption mode set to identity and everything is decrypted

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

备份 etcd 数据

请按照以下步骤通过创建 etcd 快照并备份静态 pod 的资源来备份 etcd 数据。如果需要稍后恢复 etcd,可以保存此备份并在以后使用。

仅保存来自单个控制平面主机的备份。请勿从集群中的每个控制平面主机进行备份。

先决条件
  • 您可以以具有cluster-admin角色的用户身份访问集群。

  • 您已检查集群范围代理是否已启用。

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

步骤
  1. 以 root 用户身份启动控制平面节点的调试会话。

    $ oc debug --as-root node/<node_name>
  2. 在调试 shell 中将根目录更改为/host

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

    $ export HTTP_PROXY=http://<your_proxy.example.com>:8080
    $ export HTTPS_PROXY=https://<your_proxy.example.com>:8080
    $ export NO_PROXY=<example.com>
  4. 在调试 shell 中运行cluster-backup.sh脚本,并传入要保存备份的位置。

    cluster-backup.sh脚本作为 etcd 集群操作员的组件维护,它是etcdctl snapshot save命令的包装器。

    sh-4.4# /usr/local/bin/cluster-backup.sh /home/core/assets/backup
    示例脚本输出
    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

    在本例中,会在控制平面主机上的/home/core/assets/backup/目录中创建两个文件。

    • snapshot_<datetimestamp>.db:此文件是 etcd 快照。cluster-backup.sh 脚本会确认其有效性。

    • static_kuberesources_<datetimestamp>.tar.gz:此文件包含静态 Pod 的资源。如果启用了 etcd 加密,它还包含 etcd 快照的加密密钥。

      出于安全原因,如果启用了 etcd 加密,建议将第二个文件与 etcd 快照分开存储。但是,此文件是用于从 etcd 快照恢复的必需文件。

      请记住,etcd 加密只加密值,不加密键。这意味着资源类型、命名空间和对象名称未加密。

碎片整理 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 运算符使用集群信息来确定对用户最有效的操作。

自动碎片整理

etcd 运算符会自动碎片整理磁盘。无需手动干预。

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

  • etcd 日志

  • cluster-etcd-operator pod

  • 运算符状态错误日志

自动碎片整理可能会导致各种 OpenShift 核心组件(例如 Kubernetes 控制器管理器)出现领导者选举失败,从而触发失败组件的重启。重启是无害的,它要么触发故障转移到下一个正在运行的实例,要么组件在重启后恢复工作。

成功碎片整理的示例日志输出
etcd member has been defragmented: <member_name>, memberID: <member_id>
碎片整理失败的示例日志输出
failed defrag on member: <member_name>, memberID: <member_id>: <error_message>

手动碎片整理

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
      示例输出
      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>
    2. 选择一个 pod 并运行以下命令以确定哪个 etcd 成员是领导者。

      $ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com etcdctl endpoint status --cluster -w table
      示例输出
      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 |        |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

      根据此输出的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
    2. 取消设置ETCDCTL_ENDPOINTS环境变量。

      sh-4.4# unset ETCDCTL_ENDPOINTS
    3. 碎片整理 etcd 成员。

      sh-4.4# etcdctl --command-timeout=30s --endpoints=https://127.0.0.1:2379 defrag
      示例输出
      Finished defragmenting etcd member[https://127.0.0.1:2379]

      如果出现超时错误,请增加--command-timeout的值,直到命令成功。

    4. 验证数据库大小是否已减小。

      sh-4.4# etcdctl endpoint status -w table --cluster
      示例输出
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
      |         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 |        |
      +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

      此示例显示,此 etcd 成员的数据库大小现在为 41 MB,而不是初始大小 104 MB。

    5. 重复这些步骤以连接到其他每个 etcd 成员并对其进行碎片整理。始终最后碎片整理领导者。

      碎片整理操作之间至少等待一分钟,以允许 etcd pod 恢复。在 etcd pod 恢复之前,etcd 成员将不会响应。

  3. 如果由于超过空间配额而触发了任何NOSPACE警报,请清除它们。

    1. 检查是否存在任何NOSPACE警报。

      sh-4.4# etcdctl alarm list
      示例输出
      memberID:12345678912345678912 alarm:NOSPACE
    2. 清除警报。

      sh-4.4# etcdctl alarm disarm

恢复到以前的集群状态

您可以使用保存的etcd备份来恢复以前的集群状态或恢复已丢失大部分控制平面主机的集群。

如果您的集群使用控制平面机器集,请参阅“控制平面机器集故障排除”以获取更简单的etcd恢复过程。

恢复集群时,必须使用从同一 z 流版本中获取的etcd备份。例如,OpenShift Container Platform 4.7.2 集群必须使用从 4.7.2 获取的etcd备份。

先决条件
  • 通过基于证书的kubeconfig文件(例如安装过程中使用的文件)访问集群作为具有cluster-admin角色的用户。

  • 一个健康的控制平面主机,用作恢复主机。

  • 对控制平面主机的 SSH 访问。

  • 一个备份目录,其中包含etcd快照和静态 Pod 的资源(来自同一备份)。目录中的文件名必须采用以下格式:snapshot_<datetimestamp>.dbstatic_kuberesources_<datetimestamp>.tar.gz

对于非恢复控制平面节点,不需要建立 SSH 连接或停止静态 Pod。您可以逐个删除和重新创建其他非恢复控制平面机器。

步骤
  1. 选择一个控制平面主机用作恢复主机。您将在该主机上运行恢复操作。

  2. 建立到每个控制平面节点(包括恢复主机)的 SSH 连接。

    恢复过程开始后,kube-apiserver 将变得不可访问,因此您无法访问控制平面节点。因此,建议在单独的终端中建立到每个控制平面主机的 SSH 连接。

    如果您不完成此步骤,您将无法访问控制平面主机以完成恢复过程,并且您将无法从这种状态恢复集群。

  3. etcd备份目录复制到恢复控制平面主机。

    此过程假设您已将包含etcd快照和静态 Pod 资源的backup目录复制到恢复控制平面主机的/home/core/目录。

  4. 停止任何其他控制平面节点上的静态 Pod。

    您无需停止恢复主机上的静态 Pod。

    1. 访问非恢复主机的控制平面主机。

    2. 通过运行以下命令,将现有的 etcd pod 文件移出 kubelet 清单目录:

      $ sudo mv -v /etc/kubernetes/manifests/etcd-pod.yaml /tmp
    3. 使用以下命令验证etcd Pod 是否已停止:

      $ sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"

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

    4. 通过运行以下命令,将现有的kube-apiserver文件移出 kubelet 清单目录:

      $ sudo mv -v /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
    5. 运行以下命令验证kube-apiserver容器是否已停止:

      $ sudo crictl ps | grep kube-apiserver | egrep -v "operator|guard"

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

    6. 使用以下命令将现有的kube-controller-manager文件移出 kubelet 清单目录:

      $ sudo mv -v /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /tmp
    7. 运行以下命令验证kube-controller-manager容器是否已停止:

      $ sudo crictl ps | grep kube-controller-manager | egrep -v "operator|guard"

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

    8. 使用以下命令将现有的kube-scheduler文件移出 kubelet 清单目录:

      $ sudo mv -v /etc/kubernetes/manifests/kube-scheduler-pod.yaml /tmp
    9. 使用以下命令验证kube-scheduler容器是否已停止:

      $ sudo crictl ps | grep kube-scheduler | egrep -v "operator|guard"

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

    10. 使用以下示例将etcd数据目录移动到其他位置:

      $ sudo mv -v /var/lib/etcd/ /tmp
    11. 如果存在/etc/kubernetes/manifests/keepalived.yaml文件并且节点已被删除,请按照以下步骤操作:

      1. /etc/kubernetes/manifests/keepalived.yaml文件移出 kubelet 清单目录:

        $ sudo mv -v /etc/kubernetes/manifests/keepalived.yaml /tmp
      2. 验证由keepalived守护程序管理的任何容器是否已停止:

        $ sudo crictl ps --name keepalived

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

      3. 检查控制平面是否分配了任何虚拟 IP (VIP)。

        $ ip -o address | egrep '<api_vip>|<ingress_vip>'
      4. 对于每个报告的 VIP,运行以下命令将其删除:

        $ sudo ip address del <reported_vip> dev <reported_vip_device>
    12. 在其他非恢复主机的控制平面主机上重复此步骤。

  5. 访问恢复控制平面主机。

  6. 如果正在使用keepalived守护程序,请验证恢复控制平面节点是否拥有 VIP。

    $ ip -o address | grep <api_vip>

    如果存在,VIP 的地址将在输出中突出显示。如果 VIP 未设置或配置不正确,则此命令返回空字符串。

  7. 如果启用了集群范围的代理,请确保您已导出NO_PROXYHTTP_PROXYHTTPS_PROXY环境变量。

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

  8. 在恢复控制平面主机上运行恢复脚本,并传入etcd备份目录的路径:

    $ sudo -E /usr/local/bin/cluster-restore.sh /home/core/assets/backup
    示例脚本输出
    ...stopping kube-scheduler-pod.yaml
    ...stopping kube-controller-manager-pod.yaml
    ...stopping etcd-pod.yaml
    ...stopping kube-apiserver-pod.yaml
    Waiting for container etcd to stop
    .complete
    Waiting for container etcdctl to stop
    .............................complete
    Waiting for container etcd-metrics to stop
    complete
    Waiting for container kube-controller-manager to stop
    complete
    Waiting for container kube-apiserver to stop
    ..........................................................................................complete
    Waiting for container kube-scheduler to stop
    complete
    Moving etcd data-dir /var/lib/etcd/member to /var/lib/etcd-backup
    starting restore-etcd static pod
    starting kube-apiserver-pod.yaml
    static-pod-resources/kube-apiserver-pod-7/kube-apiserver-pod.yaml
    starting kube-controller-manager-pod.yaml
    static-pod-resources/kube-controller-manager-pod-7/kube-controller-manager-pod.yaml
    starting kube-scheduler-pod.yaml
    static-pod-resources/kube-scheduler-pod-8/kube-scheduler-pod.yaml

    cluster-restore.sh脚本必须显示etcdkube-apiserverkube-controller-managerkube-scheduler Pod 在恢复过程结束时已停止然后启动。

    如果在上次etcd备份后更新了节点证书,则恢复过程可能导致节点进入NotReady状态。

  9. 检查节点以确保它们处于Ready状态。

    1. 运行以下命令:

      $ oc get nodes -w
      示例输出
      NAME                STATUS  ROLES          AGE     VERSION
      host-172-25-75-28   Ready   master         3d20h   v1.30.3
      host-172-25-75-38   Ready   infra,worker   3d20h   v1.30.3
      host-172-25-75-40   Ready   master         3d20h   v1.30.3
      host-172-25-75-65   Ready   master         3d20h   v1.30.3
      host-172-25-75-74   Ready   infra,worker   3d20h   v1.30.3
      host-172-25-75-79   Ready   worker         3d20h   v1.30.3
      host-172-25-75-86   Ready   worker         3d20h   v1.30.3
      host-172-25-75-98   Ready   infra,worker   3d20h   v1.30.3

      所有节点报告其状态可能需要几分钟时间。

    2. 如果任何节点处于NotReady状态,请登录到节点并从每个节点的/var/lib/kubelet/pki目录中删除所有 PEM 文件。您可以通过 SSH 登录到节点或使用 Web 控制台中的终端窗口。

      $  ssh -i <ssh-key-path> core@<master-hostname>
      pki目录示例:
      sh-4.4# pwd
      /var/lib/kubelet/pki
      sh-4.4# ls
      kubelet-client-2022-04-28-11-24-09.pem  kubelet-server-2022-04-28-11-24-15.pem
      kubelet-client-current.pem              kubelet-server-current.pem
  10. 重新启动所有控制平面主机上的 kubelet 服务。

    1. 从恢复主机运行:

      $ sudo systemctl restart kubelet.service
    2. 在所有其他控制平面主机上重复此步骤。

  11. 批准挂起的证书签名请求 (CSR)。

    没有工作节点的集群(例如单节点集群或由三个可调度控制平面节点组成的集群)将没有任何待批准的 CSR。您可以跳过此步骤中列出的所有命令。

    1. 通过运行以下命令获取当前 CSR 的列表:

      $ oc get csr
      示例输出
      NAME        AGE    SIGNERNAME                                    REQUESTOR                                                                   CONDITION
      csr-2s94x   8m3s   kubernetes.io/kubelet-serving                 system:node:<node_name>                                                     Pending (1)
      csr-4bd6t   8m3s   kubernetes.io/kubelet-serving                 system:node:<node_name>                                                     Pending (1)
      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 (2)
      ...
      1 节点为 kubelet 服务端点请求的待处理 kubelet 服务 CSR。
      2 使用node-bootstrapper节点引导凭据请求的待处理 kubelet 客户端 CSR。
    2. 通过运行以下命令查看 CSR 的详细信息以验证其有效性:

      $ oc describe csr <csr_name> (1)
      1 <csr_name>是当前 CSR 列表中的 CSR 名称。
    3. 通过运行以下命令批准每个有效的node-bootstrapper CSR:

      $ oc adm certificate approve <csr_name>
    4. 对于用户配置的安装,通过运行以下命令批准每个有效的 kubelet 服务 CSR:

      $ oc adm certificate approve <csr_name>
  12. 验证单成员控制平面是否已成功启动。

    1. 从恢复主机使用以下命令验证etcd容器是否正在运行:

      $ sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
      示例输出
      3ad41b7908e32       36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009                                                         About a minute ago   Running             etcd                                          0                   7c05f8af362f0
    2. 从恢复主机使用以下命令验证etcd Pod 是否正在运行:

      $ oc -n openshift-etcd get pods -l k8s-app=etcd
      示例输出
      NAME                                             READY   STATUS      RESTARTS   AGE
      etcd-ip-10-0-143-125.ec2.internal                1/1     Running     1          2m47s

      如果状态为Pending,或者输出列出了多个正在运行的etcd Pod,请等待几分钟然后再次检查。

  13. 如果您使用的是OVNKubernetes网络插件,则必须重新启动ovnkube-controlplane Pod。

    1. 通过运行以下命令删除所有ovnkube-controlplane Pod:

      $ oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-control-plane
    2. 使用以下命令验证所有ovnkube-controlplane Pod 是否已重新部署:

      $ oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-control-plane
  14. 如果您使用的是 OVN-Kubernetes 网络插件,请逐个重新启动所有节点上的 Open Virtual Network (OVN) Kubernetes Pod。使用以下步骤重新启动每个节点上的 OVN-Kubernetes Pod:

    按以下顺序重新启动 OVN-Kubernetes Pod:
    1. 恢复控制平面主机

    2. 其他控制平面主机(如果可用)

    3. 其他节点

    验证和变异准入 Webhook 可能会拒绝 Pod。如果您添加任何其他将failurePolicy设置为Fail的 Webhook,则它们可能会拒绝 Pod,并且恢复过程可能会失败。您可以通过在恢复集群状态时保存和删除 Webhook 来避免这种情况。成功恢复集群状态后,您可以再次启用 Webhook。

    或者,您可以在恢复集群状态时暂时将failurePolicy设置为Ignore。成功恢复集群状态后,您可以将failurePolicy设置为Fail

    1. 删除北向数据库 (nbdb) 和南向数据库 (sbdb)。使用安全 shell (SSH) 访问恢复主机和其余控制平面节点并运行:

      $ sudo rm -f /var/lib/ovn-ic/etc/*.db
    2. 重新启动 OpenVSwitch 服务。使用安全 shell (SSH) 访问节点并运行以下命令:

      $ sudo systemctl restart ovs-vswitchd ovsdb-server
    3. 通过运行以下命令删除节点上的ovnkube-node Pod,将<node>替换为您要重新启动的节点的名称:

      $ oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>
    4. 使用以下命令验证ovnkube-node Pod 是否再次运行:

      $ oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>

      Pod 重启可能需要几分钟。

  15. 依次删除并重新创建其他非恢复控制平面机器。机器重新创建后,将强制执行新的修订版本,并且etcd会自动扩展。

    • 如果您使用用户预配的裸机安装,您可以使用最初创建它的相同方法重新创建控制平面机器。有关更多信息,请参阅“在裸机上安装用户预配的集群”。

      不要删除和重新创建恢复主机的机器。

    • 如果您正在运行安装程序预配的基础架构,或者您使用 Machine API 创建了您的机器,请按照以下步骤操作

      不要删除和重新创建恢复主机的机器。

      对于安装程序预配的基础架构上的裸机安装,不会重新创建控制平面机器。有关更多信息,请参阅“更换裸机控制平面节点”。

      1. 获取丢失的控制平面主机之一的机器。

        在具有集群管理员用户权限的终端中,运行以下命令

        $ oc get machines -n openshift-machine-api -o wide

        示例输出

        NAME                                        PHASE     TYPE        REGION      ZONE         AGE     NODE                           PROVIDERID                              STATE
        clustername-8qw5l-master-0                  Running   m4.xlarge   us-east-1   us-east-1a   3h37m   ip-10-0-131-183.ec2.internal   aws:///us-east-1a/i-0ec2782f8287dfb7e   stopped (1)
        clustername-8qw5l-master-1                  Running   m4.xlarge   us-east-1   us-east-1b   3h37m   ip-10-0-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
        1 这是丢失的控制平面主机ip-10-0-131-183.ec2.internal的控制平面机器。
      2. 通过运行以下命令删除丢失的控制平面主机的机器

        $ oc delete machine -n openshift-machine-api clustername-8qw5l-master-0 (1)
        1 指定丢失的控制平面主机的控制平面机器的名称。

        删除丢失的控制平面主机的机器后,将自动预配一台新机器。

      3. 通过运行以下命令验证是否已创建新机器

        $ oc get machines -n openshift-machine-api -o wide

        示例输出

        NAME                                        PHASE          TYPE        REGION      ZONE         AGE     NODE                           PROVIDERID                              STATE
        clustername-8qw5l-master-1                  Running        m4.xlarge   us-east-1   us-east-1b   3h37m   ip-10-0-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
        1 新的机器clustername-8qw5l-master-3正在创建中,并在阶段从Provisioning变为Running后准备就绪。

        创建新机器可能需要几分钟。当机器或节点恢复到健康状态时,etcd集群操作符将自动同步。

      4. 对每个丢失的控制平面主机(恢复主机除外)重复这些步骤。

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

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'

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

  17. 在恢复主机中的单独终端窗口中,通过运行以下命令导出恢复kubeconfig文件:

    $ export KUBECONFIG=/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost-recovery.kubeconfig
  18. 强制etcd重新部署。

    在您导出恢复kubeconfig文件的同一终端窗口中,运行:

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

    etcd重新部署开始。

    etcd集群操作符执行重新部署时,现有节点将使用与初始引导启动类似的新 Pod 启动。

  19. 输入以下命令重新启用仲裁保护:

    $ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
  20. 您可以通过运行以下命令验证对象中是否已删除unsupportedConfigOverrides部分:

    $ oc get etcd/cluster -oyaml
  21. 验证所有节点都已更新到最新版本。

    在具有集群管理员用户权限的终端中,运行:

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

    查看etcdNodeInstallerProgressing状态条件,以验证所有节点是否都处于最新版本。成功更新后,输出将显示AllNodesAtLatestRevision

    AllNodesAtLatestRevision
    3 nodes are at revision 7 (1)
    
    1 在此示例中,最新的修订版本号为7

    如果输出包含多个修订版本号,例如2 nodes are at revision 6; 1 nodes are at revision 7,则表示更新仍在进行中。请等待几分钟,然后重试。

  22. etcd重新部署后,强制对控制平面进行新的 rollout。由于 kubelet 使用内部负载均衡器连接到 API 服务器,kube-apiserver 将自行在其他节点上重新安装。

    在具有集群管理员用户权限的终端中,运行:

    1. 强制kube-apiserver进行新的 rollout:

      $ oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge

      验证所有节点都已更新到最新版本。

      $ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'

      查看NodeInstallerProgressing状态条件,以验证所有节点是否都处于最新版本。成功更新后,输出将显示AllNodesAtLatestRevision

      AllNodesAtLatestRevision
      3 nodes are at revision 7 (1)
      
      1 在此示例中,最新的修订版本号为7

      如果输出包含多个修订版本号,例如2 nodes are at revision 6; 1 nodes are at revision 7,则表示更新仍在进行中。请等待几分钟,然后重试。

    2. 通过运行以下命令强制对 Kubernetes 控制器管理器进行新的 rollout:

      $ oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge

      通过运行以下命令验证所有节点是否都已更新到最新版本:

      $ oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'

      查看NodeInstallerProgressing状态条件,以验证所有节点是否都处于最新版本。成功更新后,输出将显示AllNodesAtLatestRevision

      AllNodesAtLatestRevision
      3 nodes are at revision 7 (1)
      
      1 在此示例中,最新的修订版本号为7

      如果输出包含多个修订版本号,例如2 nodes are at revision 6; 1 nodes are at revision 7,则表示更新仍在进行中。请等待几分钟,然后重试。

    3. 通过运行以下命令强制对kube-scheduler进行新的 rollout:

      $ oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge

      使用以下命令验证所有节点是否都已更新到最新版本:

      $ oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'

      查看NodeInstallerProgressing状态条件,以验证所有节点是否都处于最新版本。成功更新后,输出将显示AllNodesAtLatestRevision

      AllNodesAtLatestRevision
      3 nodes are at revision 7 (1)
      
      1 在此示例中,最新的修订版本号为7

      如果输出包含多个修订版本号,例如2 nodes are at revision 6; 1 nodes are at revision 7,则表示更新仍在进行中。请等待几分钟,然后重试。

  23. 通过运行以下命令监控平台操作符:

    $ oc adm wait-for-stable-cluster

    此过程可能需要最多 15 分钟。

  24. 验证所有控制平面主机是否已启动并加入集群。

    在具有集群管理员用户权限的终端中,运行以下命令:

    $ oc -n openshift-etcd get pods -l k8s-app=etcd
    示例输出
    etcd-ip-10-0-143-125.ec2.internal                2/2     Running     0          9h
    etcd-ip-10-0-154-194.ec2.internal                2/2     Running     0          9h
    etcd-ip-10-0-173-171.ec2.internal                2/2     Running     0          9h

为了确保所有工作负载在恢复过程后恢复正常运行,请重新启动所有控制平面节点。

完成之前的步骤后,您可能需要等待几分钟才能使所有服务恢复到其恢复状态。例如,使用oc login进行身份验证可能不会立即生效,直到 OAuth 服务器 Pod 重新启动。

考虑使用system:admin kubeconfig文件进行立即身份验证。此方法基于 SSL/TLS 客户端证书进行身份验证,而不是 OAuth 令牌。您可以通过发出以下命令来使用此文件进行身份验证:

$ export KUBECONFIG=<installation_directory>/auth/kubeconfig

发出以下命令以显示您的已认证用户名:

$ oc whoami

恢复持久存储状态的问题和解决方法

如果您的 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 快照,则执行 etcd 恢复时,由于卷仍附加到节点 Y,Pod P1 可能无法正确启动。OpenShift Container Platform 不知道此附加,也不会自动分离它。发生这种情况时,必须从节点 Y 手动分离卷,以便卷可以附加到节点 X,然后 Pod P1 才能启动。

  • 在拍摄 etcd 快照后更新了云提供商或存储提供商凭据。这会导致依赖于这些凭据的任何 CSI 驱动程序或操作符无法工作。您可能必须手动更新这些驱动程序或操作符所需的凭据。

  • 在拍摄 etcd 快照后,从 OpenShift Container Platform 节点中删除或重命名设备。本地存储操作符为其从/dev/disk/by-id/dev目录管理的每个 PV 创建符号链接。这种情况可能导致本地 PV 引用不再存在的设备。

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

    1. 手动删除具有无效设备的 PV。

    2. 从各个节点中删除符号链接。

    3. 删除LocalVolumeLocalVolumeSet对象(参见存储配置持久化存储使用本地卷的持久化存储删除本地存储操作符资源)。

Pod 扰动预算

了解并配置 Pod 扰动预算。

了解如何使用 Pod 扰动预算指定必须保持运行的 Pod 数量

Pod 扰动预算允许在操作期间(例如,为维护而驱逐节点)对 Pod 指定安全约束。

PodDisruptionBudget是一个 API 对象,它指定了必须同时保持运行的副本的最小数量或百分比。在项目中设置这些预算在节点维护期间(例如缩减集群规模或集群升级)非常有用,并且仅在自愿驱逐(而非节点故障)时生效。

PodDisruptionBudget对象的配置包含以下关键部分:

  • 标签选择器,这是一个对一组 Pod 的标签查询。

  • 可用性级别,它指定了必须同时可用的 Pod 的最小数量,可以是:

    • minAvailable是在扰动期间始终必须可用的 Pod 数量。

    • maxUnavailable是在扰动期间允许不可用的 Pod 数量。

Available指的是状态为Ready=True的 Pod 数量。Ready=True指的是能够处理请求并应添加到所有匹配服务的负载均衡池中的 Pod。

maxUnavailable0%0,或者minAvailable100%或等于副本数量是被允许的,但是这可能会阻止节点被驱逐。

OpenShift Container Platform 中所有机器配置池的maxUnavailable默认设置为1。建议不要更改此值,并一次更新一个控制平面节点。不要将控制平面池的此值更改为3

您可以使用以下命令检查所有项目中的 Pod 扰动预算:

$ oc get poddisruptionbudget --all-namespaces

以下示例包含一些特定于 AWS 上 OpenShift Container Platform 的值。

示例输出
NAMESPACE                              NAME                                    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
openshift-apiserver                    openshift-apiserver-pdb                 N/A             1                 1                     121m
openshift-cloud-controller-manager     aws-cloud-controller-manager            1               N/A               1                     125m
openshift-cloud-credential-operator    pod-identity-webhook                    1               N/A               1                     117m
openshift-cluster-csi-drivers          aws-ebs-csi-driver-controller-pdb       N/A             1                 1                     121m
openshift-cluster-storage-operator     csi-snapshot-controller-pdb             N/A             1                 1                     122m
openshift-cluster-storage-operator     csi-snapshot-webhook-pdb                N/A             1                 1                     122m
openshift-console                      console                                 N/A             1                 1                     116m
#...

当系统中至少运行minAvailable个 Pod 时,PodDisruptionBudget被认为是健康的。超过此限制的每个 Pod 都可以被驱逐。

根据您的 Pod 优先级和抢占设置,即使满足 Pod 扰动预算要求,低优先级 Pod 也可能被移除。

使用 Pod 扰动预算指定必须保持运行的 Pod 数量

您可以使用PodDisruptionBudget对象指定必须同时保持运行的副本的最小数量或百分比。

步骤

要配置 Pod 扰动预算:

  1. 创建一个包含类似于以下对象的 YAML 文件:

    apiVersion: policy/v1 (1)
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      minAvailable: 2  (2)
      selector:  (3)
        matchLabels:
          name: my-pod
    1 PodDisruptionBudget属于policy/v1 API 组。
    2 必须同时可用的 Pod 的最小数量。这可以是整数,也可以是指定百分比的字符串,例如20%
    3 对一组资源的标签查询。matchLabelsmatchExpressions的结果是逻辑上连接的。将此参数留空,例如selector {},以选择项目中的所有 Pod。

    或者

    apiVersion: policy/v1 (1)
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      maxUnavailable: 25% (2)
      selector: (3)
        matchLabels:
          name: my-pod
    1 PodDisruptionBudget属于policy/v1 API 组。
    2 可以同时不可用的 Pod 的最大数量。这可以是整数,也可以是指定百分比的字符串,例如20%
    3 对一组资源的标签查询。matchLabelsmatchExpressions的结果是逻辑上连接的。将此参数留空,例如selector {},以选择项目中的所有 Pod。
  2. 运行以下命令将对象添加到项目:

    $ oc create -f </path/to/file> -n <project_name>

指定不健康 Pod 的驱逐策略

当您使用 Pod 扰动预算 (PDB) 指定必须同时可用的 Pod 数量时,您还可以定义如何考虑不健康 Pod 是否应被驱逐的标准。

您可以选择以下策略之一:

IfHealthyBudget

仅当受保护的应用程序不会中断时,才能驱逐尚未健康的正在运行的 Pod。

AlwaysAllow

无论是否满足 Pod 扰动预算中的标准,都可以驱逐尚未健康的正在运行的 Pod。此策略可以帮助驱逐故障应用程序,例如处于CrashLoopBackOff状态或无法报告Ready状态的 Pod。

建议在PodDisruptionBudget对象中将unhealthyPodEvictionPolicy字段设置为AlwaysAllow,以支持在节点驱逐期间驱逐行为异常的应用程序。默认行为是等待应用程序 Pod 变为健康状态,然后才能进行驱逐。

步骤
  1. 创建一个定义PodDisruptionBudget对象的 YAML 文件,并指定不健康 Pod 的驱逐策略。

    示例pod-disruption-budget.yaml文件:
    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      minAvailable: 2
      selector:
        matchLabels:
          name: my-pod
      unhealthyPodEvictionPolicy: AlwaysAllow (1)
    1 选择IfHealthyBudgetAlwaysAllow作为不健康 Pod 的驱逐策略。当unhealthyPodEvictionPolicy字段为空时,默认为IfHealthyBudget
  2. 运行以下命令创建PodDisruptionBudget对象:

    $ oc create -f pod-disruption-budget.yaml

使用设置了AlwaysAllow不健康 Pod 驱逐策略的 PDB,您现在可以驱逐节点并驱逐受此 PDB 保护的故障应用程序的 Pod。