第 9 章 网络边缘上的远程 worker 节点

9.1. 在网络边缘使用远程 worker 节点

您可以使用位于网络边缘的节点来配置 OpenShift Container Platform 集群。在本主题中,它们称为远程 worker 节点。带有远程 worker 节点的典型集群合并了内部 master 和 worker 节点,其他位置的 worker 节点会连接到集群。本主题旨在提供使用远程 worker 节点的最佳实践指导,且不包含特定配置详情。

在使用具有远程 worker 节点的部署模式时,不同行业有不同的用例,如电信、零售、制造企业和政府。例如,您可以通过将远程 worker 节点合并到 Kubernetes 区域来隔离项目和工作负载。

但是,具有远程 worker 节点可能会带来更高的延迟,以及网络连接间丢失的问题。使用带有远程 worker 节点的集群会有一些挑战,包括:

  • 网络隔离:OpenShift Container Platform control plane 和远程 worker 节点必须可以相互通信。由于 control plane 和远程 worker 节点之间很远,网络问题可能会阻止这种通信。如需有关 OpenShift Container Platform 如何响应网络分离以及减少对集群的影响的信息,请参阅使用远程 worker 节点进行网络隔离。
  • 电源中断:因为 control plane 和远程 worker 节点位于不同的位置,因此在远程位置或在两个位置之间的任意点出现停机会给集群造成负面影响。如需了解 OpenShift Container Platform 如何响应节点丢失以及减少对集群的影响的信息,请参阅远程 worker 节点的电源丢失
  • 延迟或临时减少吞吐量:与任何网络一样,集群和远程 worker 节点之间的网络状况改变都会对集群有负面影响。OpenShift Container Platform 提供多个 worker 延迟配置集,供您控制集群的反应延迟问题。

在规划使用远程 worker 节点的集群时,请注意以下限制:

  • OpenShift Container Platform 不支持使用与内部集群所使用的不同云供应商的远程 worker 节点。
  • 因为系统和环境中的问题(如特定类型的内存不在另一区中可用),将工作负载从一个 Kubernetes 区域移动到不同的 Kubernetes 区可能会有问题。
  • 使用代理和防火墙可能会遇到本文档所涉及到的范围以外的限制。有关如何解决这些限制,如配置防火墙,请参阅相关的 OpenShift Container Platform 文档。
  • 您需要配置和维护 control plane 和网络边缘节点之间的 L2/L3 级别网络连接。

9.1.1. 添加远程 worker 节点

在集群中添加远程 worker 节点涉及一些额外的注意事项。

  • 您必须确保路由或默认网关被放置,以便在 control plane 和每个远程 worker 节点之间路由流量。
  • 您必须将 Ingress VIP 放在 control plane 上。
  • 使用用户置备的基础架构添加远程 worker 节点与添加其他 worker 节点相同。
  • 要在安装时将远程 worker 节点添加到安装程序置备的集群中,请在安装前在 install-config.yaml 文件中指定每个 worker 节点的子网。DHCP 服务器不需要额外的设置。您必须使用虚拟介质,因为远程 worker 节点无法访问本地置备网络。
  • 要将远程 worker 节点添加到使用 provisioning 网络部署的安装程序置备的集群中,请确保在 install-config.yaml 文件中将 virtualMediaViaExternalNetwork 标志设置为 true,以便它将使用虚拟介质添加节点。远程 worker 节点无法访问本地置备网络。它们必须使用虚拟介质而不是 PXE 部署。另外,为每个远程 worker 节点组和 DHCP 服务器中的 control plane 节点指定每个子网。

9.1.2. 使用远程 worker 节点进行网络隔离

所有节点每 10 秒向 OpenShift Container Platform 集群中的 Kubernetes Controller Manager Operator(kube 控制器)发送 heartbeat。如果集群没有从节点获得 heartbeat,OpenShift Container Platform 会使用几个默认机制进行响应。

OpenShift Container Platform 旨在可以正确处理网络分区和其他中断问题的出现。您可以缓解一些常见中断的影响,如软件升级中断、网络分割和路由问题。缓解策略包括确保远程 worker 节点上的 pod 请求正确的 CPU 和内存资源量、配置适当的复制策略、使用跨区冗余以及在工作负载中使用 Pod Disruption Tables。

如果 kube 控制器在经过了配置的时间后无法访问节点,则 control plane 上的节点控制器会将节点健康状况更新为 Unhealthy,并将节点 Ready 条件标记为 Unknown。因此,调度程序会停止将 pod 调度到该节点。内部节点控制器添加了 node.kubernetes.io/unreachable 污点,对节点具有 NoExecute 效果,默认情况下,在五分钟后调度节点上的 pod 进行驱除。

如果工作负载控制器(如 Deployment 对象或 StatefulSet 对象)将流量定向到不健康节点上的 pod,而其他节点也可以访问集群,OpenShift Container Platform 会从节点上的 pod 路由流量。无法访问集群的节点不会使用新的流量路由进行更新。因此,这些节点上的工作负载可能会继续尝试访问不健康的节点。

您可以通过以下方法降低连接丢失的影响:

  • 使用守护进程集创建容许污点的 pod
  • 使用在节点停机时自动重启的静态 pod
  • 使用 Kubernetes 区域来控制 pod 驱除
  • 配置 pod 容限来延迟或避免 pod 驱除
  • 配置 kubelet 以控制它在将节点标记为不健康的时间。

有关在带有远程 worker 节点的集群中使用这些对象的更多信息,请参阅关于远程 worker 节点策略

9.1.3. 远程 worker 节点上的电源丢失

如果远程 worker 节点断电或重启不可用,OpenShift Container Platform 会使用几个默认机制进行响应。

如果 Kubernetes Controller Manager Operator(kube controller)在配置的时间后无法访问节点,control plane 会将节点健康状况更新为 Unhealthy,并将节点 Ready 条件标记为 Unknown。因此,调度程序会停止将 pod 调度到该节点。内部节点控制器添加了 node.kubernetes.io/unreachable 污点,对节点具有 NoExecute 效果,默认情况下,在五分钟后调度节点上的 pod 进行驱除。

在节点上当节点恢复电源并与 control plane 重新连接时, pod 必须重启。

注意

如果您希望 pod 重启后立即重启,请使用静态 pod。

节点重启后,kubelet 还会重启并尝试重启节点上调度的 pod。如果到 control plane 的连接时间超过默认的五分钟,则 control plane 无法更新节点健康状况并移除 node.kubernetes.io/unreachable 污点。在节点上,kubelet 会终止任何正在运行的 pod。当这些条件被清除后,调度程序就可以开始将 pod 调度到该节点。

您可以通过以下方法减轻电源损失的影响:

  • 使用守护进程集创建容许污点的 pod
  • 使用与节点自动重启的静态 pod
  • 配置 pod 容限以延迟或避免 pod 驱除
  • 配置 kubelet 以控制节点控制器何时将节点标记为不健康的时间。

有关在带有远程 worker 节点的集群中使用这些对象的更多信息,请参阅关于远程 worker 节点策略

9.1.4. 远程 worker 吞吐量延迟或临时减少

如果集群管理员为平台验证执行了延迟测试,他们可以发现需要调整集群的操作,以确保高延迟的情况的稳定性。集群管理员只需要更改一个参数,该参数记录在一个文件中,它控制了 Supervisory 进程读取状态并解释集群的运行状况的四个参数。仅更改一个参数可以以方便、可支持的方式提供集群调整。

Kubelet 进程提供监控集群运行状况的起点。Kubelet 为 OpenShift Container Platform 集群中的所有节点设置状态值。Kubernetes Controller Manager (kube controller) 默认每 10 秒读取状态值。如果 kube 控制器无法读取节点状态值,它会在配置的时间后丢失与该节点联系。默认行为是:

  1. control plane 上的节点控制器将节点健康状况更新为 Unhealthy,并奖节点 Ready 的条件标记为 'Unknown'。
  2. 因此,调度程序会停止将 pod 调度到该节点。
  3. Node Lifecycle Controller 添加了一个 node.kubernetes.io/unreachable 污点,对节点具有 NoExecute 效果,默认在五分钟后调度节点上的任何 pod 进行驱除。

如果您的网络容易出现延迟问题,尤其是在网络边缘中有节点时,此行为可能会造成问题。在某些情况下,Kubernetes Controller Manager 可能会因为网络延迟而从健康的节点接收更新。Kubelet 会从节点中驱除 pod,即使节点处于健康状态。

要避免这个问题,您可以使用 worker 延迟配置集调整 kubelet 和 Kubernetes Controller Manager 在执行操作前等待状态更新的频率。如果在控制平面和 worker 节点间存在网络延迟,worker 节点没有处于最近状态,这个调整有助于集群可以正常工作。

这些 worker 延迟配置集包含预定义的三组参数,它们带有经过仔细调优的值,以控制集群对增加的延迟进行适当地响应。用户不需要手动进行实验以查找最佳值。

您可在安装集群时配置 worker 延迟配置集,或当您发现集群网络中的延迟增加时。

9.1.5. 远程 worker 节点策略

如果您使用远程 worker 节点,请考虑使用哪个对象来运行应用程序。

建议根据所计划的在出现网络问题或电源丢失时需要进行的行为,使用守护进程集或静态 pod。另外,如果 control plane 无法访问远程 worker 节点,您可以使用 Kubernetes 区和容限来控制或避免 pod 驱除。

守护进程集
守护进程集是管理远程 worker 节点上的 pod 的最佳方法,理由如下:
  • 守护进程集通常不需要重新调度。如果节点断开与集群的连接,节点上的 pod 将继续运行。OpenShift Container Platform 不更改守护进程设置 pod 的状态,并使 pod 保留为最新报告的状态。例如,如果守护进程集 pod 处于 Running 状态,当节点停止通信时,pod 会继续运行,并假定 OpenShift Container Platform 正在运行。
  • 在默认情况下,守护进程集会被创建为带有对没有 tolerationSeconds 值的 node.kubernetes.io/unreachablenode.kubernetes.io/not-ready 污点的 NoExecute 容限。如果 control plane 无法访问节点,则守护进程集 pod 不会被驱除。例如:

    容限默认添加到守护进程集 pod

      tolerations:
        - key: node.kubernetes.io/not-ready
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/unreachable
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/memory-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/pid-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/unschedulable
          operator: Exists
          effect: NoSchedule

  • 守护进程集可以使用标签来确保工作负载在匹配的 worker 节点上运行。
  • 您可以使用 OpenShift Container Platform 服务端点来加载均衡守护进程设置 pod。
注意

如果 OpenShift Container Platform 无法访问该节点,守护进程集不会在节点重新引导后调度 pod。

静态 pod
如果您希望在一个节点重启后(例如发生了电源中断的情况)重启 pod,考虑使用静态 pod。节点上的 kubelet 会在节点重启时自动重启静态 pod。
注意

静态 pod 无法使用 secret 和配置映射。

Kubernetes 区域
Kubernetes 区域 可能会降低速率,或在某些情况下完全停止 pod 驱除。

当 control plane 无法访问节点时,节点控制器默认应用 node.kubernetes.io/unreachable 污点并驱除 pod,驱除率为每秒 0.1 个节点。但是,在使用 Kubernetes 区的集群中,pod 驱除行为会被改变。

如果区被完全破坏,区中的所有节点都具有 FalseUnknownReady 条件,control plane 不会将 node.kubernetes.io/unreachable 污点应用到那个区的节点。

对于部分受破坏的区,超过 55% 的节点具有 FalseUnknown 条件,pod 驱除率会降低为每秒 0.01 个节点。在较小集群(小于 50 个节点)中的节点不具有污点。您的集群必须具有超过三个区域才能使行为生效。

您可以通过应用节点规格中的 topology.kubernetes.io/region 标签将节点分配给特定区。

Kubernetes 区节点标签示例

kind: Node
apiVersion: v1
metadata:
  labels:
    topology.kubernetes.io/region=east

KubeletConfig 对象

您可以调整 kubelet 检查每个节点状态的时间长度。

要设置影响内部节点控制器何时标记具有 UnhealthyUnreachable 状况的节点的时间间隔,创建一个包含 node-status-update-frequency 参数的 KubeletConfig 对象,以及 node-status-report-frequency 参数。

每个节点上的 kubelet 决定 node-status-update-frequency 设置定义的节点状态,并根据 node-status-report-frequency 设置向集群报告这个状态。默认情况下,kubelet 每 10 秒决定 pod 状态,并每分钟报告状态。但是,如果节点状态更改,kubelet 会立即报告到集群的更改。只有在启用了 Node Lease 功能门时,OpenShift Container Platform 才会使用 node-status-report-frequency 设置,这是 OpenShift Container Platform 集群的默认设置。如果禁用了 Node Lease 功能门,节点会根据 node-status-update-frequency 设置报告其状态。

kubelet 配置示例

apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  name: disable-cpu-units
spec:
  machineConfigPoolSelector:
    matchLabels:
      machineconfiguration.openshift.io/role: worker 1
  kubeletConfig:
    node-status-update-frequency: 2
      - "10s"
    node-status-report-frequency: 3
      - "1m"

1
使用 MachineConfig 对象中的标签指定此 KubeletConfig 对象应用到的节点类型。
2
指定 kubelet 检查与此 MachineConfig 对象关联的节点状态的频率。默认值为 10s。如果更改此默认值,则 node-status-report-frequency 值将更改为相同的值。
3
指定 kubelet 报告与此 MachineConfig 对象关联的节点状态的频率。默认值为 1m

node-status-update-frequency 参数与 node-monitor-grace-periodpod-eviction-timeout 参数一起工作。

  • node-monitor-grace-period 参数指定,如果控制器管理器未接收节点 heartbeat,OpenShift Container Platform 会在与 MachineConfig 对象关联的节点标记为 Unhealthy 后等待多久。该节点上的工作负载在此时间之后将继续运行。如果在 node-monitor-grace-period 过期后远程 worker 节点重新加入集群,pod 会继续运行。新的 pod 可以调度到该节点。node-monitor-grace-period 间隔为 40snode-status-update-frequency 值必须小于 node-monitor-grace-period 值。
  • pod-eviction-timeout 参数指定 OpenShift Container Platform 在将与 MachineConfig 对象关联的节点标记为 Unreachable 后等待的时间,以开始标记 pod 进行驱除。被驱除的 pod 会被在其他节点上重新调度。如果在 pod-eviction-timeout 过期后远程 worker 节点重新加入集群,则在远程 worker 节点上运行的 pod 将会被终止,因为节点控制器已逐出 pod。然后可将 Pod 重新调度到该节点。pod-eviction-timeout 间隔为 5m0s
注意

不支持修改 node-monitor-grace-periodpod-eviction-timeout 参数。

容限(Tolerations)
如果内部节点控制器添加了一个 node.kubernetes.io/unreachable 污点,它在无法访问时对节点有一个 NoExecute 的效果,则可以使用 pod 容限来减轻影响。

具有 NoExecute 效果的污点会影响节点上运行的 pod:

  • 不容许污点的 Pod 会被放入队列进行驱除。
  • 如果 Pod 容许污点,且没有在容限规格中指定 tolerationSeconds 值,则会永久保持绑定。
  • 如果 Pod 容许污点,且指定了 tolerationSeconds 值,则会在指定的时间里保持绑定。在这个时间过后, pod 会被放入队列以驱除。

您可以通过把 pod 配置为使 node.kubernetes.io/unreachablenode.kubernetes.io/not-ready 污点有 NoExecute 的效果来延迟或避免 pod 驱除。

pod 规格中的容限示例

...
tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute" 1
- key: "node.kubernetes.io/not-ready"
  operator: "Exists"
  effect: "NoExecute" 2
  tolerationSeconds: 600
...

1
没有 tolerationSecondsNoExecute 效果可在 control plane 无法访问节点时永久保留 pod。
2
带有 tolerationSeconds: 600 的 NoExecute 效果允许在 control plane 将节点标记为 Unhealthy 时让 pod 再保持 10 分钟。

OpenShift Container Platform 在 pod-eviction-timeout 值到期后使用 tolerationSeconds 值。

其他类型的 OpenShift Container Platform 对象
您可以使用副本集、部署和复制控制器。当节点断开连接五分钟后,调度程序可将这些 pod 重新调度到其他节点上。重新调度到其他节点对于某些工作负载(如 REST API)来说是很有帮助的,管理员可以保证特定数量的 pod 正在运行并可以被访问。
注意

在使用远程 worker 节点时,如果远程 worker 节点旨在保留给特定功能,则不同节点上重新调度 pod 可能会是无法接受的。

有状态集不会在停机时重启。pod 处于 terminating 状态,直到 control plane 可以确认 pod 已被终止。

为了避免调度到一个无法访问同一类型的持久性存储的节点,OpenShift Container Platform 不允许在网络分离时将需要持久性卷的 pod 迁移到其他区。

其他资源