4.8. 为 OpenShift Container Platform 集群中的节点分配资源

为提供更加可靠的调度并且最大程度减少资源过量使用,每个节点都可保留一部分资源供主机上的所有底层节点组件(如 kubelet 和 kube-proxy)和其余系统组件(如 sshdNetworkManager)使用。指定之后,调度程序就能获得更多关于节点为 pod 分配的资源(如内存和 CPU)的信息。

4.8.1. 了解如何为节点分配资源

OpenShift Container Platform 中为节点组件保留的 CPU 和内存资源基于两个节点设置:

设置描述

kube-reserved

为节点组件保留的资源。默认为 none。

system-reserved

为其余系统组件保留的资源。默认为 none。

如果未设置标记,则默认为 0。如果未设置任何标记,则分配的资源设置为引入可分配资源前的节点容量。

4.8.1.1. OpenShift Container Platform 如何计算分配的资源

分配的资源数量根据以下公式来计算:

[Allocatable] = [Node Capacity] - [kube-reserved] - [system-reserved] - [Hard-Eviction-Thresholds]
注意

其中,可分配量中扣除了 Hard-Eviction-Thresholds 是一个新的改变,旨在提高系统可靠性。现在,对最终用户 pod 的可分配量在节点一级被强制实施。用户可使用 experimental-allocatable-ignore-eviction 设置来保留传统的行为,但这个设置会在未来发行版中弃用。

如果 [Allocatable] 为负,它会被设为 0

每个节点报告由容器运行时和 kubelet 使用的系统资源。为更方便地配置 --system-reserved--kube-reserved,您可以使用节点概述 API 内省相应节点的资源使用情况,该 API 可通过 /api/v1/nodes/<node>/proxy/stats/summary 访问。

4.8.1.2. 节点如何强制实施资源限制

节点可以根据配置的可分配值限制 pod 可消耗的资源总量。此功能可以防止 pod 造成系统服务(如容器运行时和节点代理等等)缺少资源,因而能显著提高节点可靠性。强烈建议管理员根据所需的节点使用率目标保留资源,以便提高节点可靠性。

节点使用一个新的 cgroup 分级结构来强制实施对资源的约束。它可以强制实现对服务质量的要求。所有 pod 都在专用的 cgroup 层次结构中启动,与系统守护进程隔离。

也可以选择在 enforcing-node-allocatable 标记中指定相应令牌来强制节点实施 kube-reserved 和 system-reserved。如果指定,则需要提供对应的 --kube-reserved-cgroup--system-reserved-cgroup。在未来的发行版中,节点和容器运行时将会被打包在一个与 system.slice 分开的通用 cgroup 中。在此之前,建议用户不要更改 enforcing-node-allocatable 标记的默认值。

管理员应该如对待有保障 pod 一般对待系统守护进程。系统守护进程可能会在其限定控制组中爆发,此行为需要作为集群部署的一个部分进行管理。强制实施 system-reserved 限制可导致节点上关键系统服务缺少 CPU 资源或面临 OOM 终止。我们的建议是,只在操作员为其节点进行了详尽性能测试,确定了精确的估计值并且有信心能够在该组中任何进程发生 OOM 终止时都能复原,才可强制实施 system-reserved。

因此,强烈建议用户默认只为 pod 强制实施节点可分配量,并为系统守护进程设置适当的保留量,以便保持整个节点的可靠性。

4.8.1.3. 了解驱除阈值

如果某个节点面临内存压力,这可能会影响整个节点以及该节点上运行的所有 pod。如果系统守护进程使用的内存超过为其保留的内存量,可能会发生 OOM 事件,影响整个节点以及该节点上运行的所有 pod。为避免系统 OOM(或降低其发生概率),节点会提供资源不足处理。

您可以使用 --eviction-hard 标记保留一些内存。每当节点上的内存可用量低于该绝对值或百分比时,节点会尝试驱除 pod。如果节点上没有系统守护进程,pod 的内存会被限制在 capacity - eviction-hard 内。因此,pod 不能使用作为达到内存不足状态前驱除缓冲量而预留的资源。

下例演示了节点内存可分配量的影响:

  • 节点容量为 32Gi
  • --kube-reserved 为 2Gi
  • --system-reserved 为 1Gi
  • --eviction-hard 设置为 100Mi

对于这个节点,有效节点可分配量的值是 28.9Gi。如果节点和系统组件用尽其所有保留量,则 pod 的可用内存为 28.9Gi,并且 kubelet 会在超过此用量时驱除 pod。

如果您通过顶级 cgroup 强制实施节点可分配量 (28.9Gi),那么 pod 永不会超过 28.9Gi。除非系统守护进程消耗的内存超过 3.1Gi,否则不会执行驱除。

如果系统守护进程没有用尽其所有保留量,那么在上例中,pod 会在节点开始驱除前面临被其限定 cgroup 执行 memcg OOM 终止的问题。为了在这种情况下更好地强制实施 QoS,节点会对所有 pod 的顶级 cgroup 应用硬驱除阈值,即 Node Allocatable + Eviction Hard Thresholds

如果系统守护进程没有用尽所有保留量,每当 pod 消耗的内存超过 28.9Gi 时,节点就会驱除 pod。如果不及时驱除,消耗的内存超过 29Gi 时就会对 pod 执行 OOM 终止。

4.8.1.4. 调度程序如何确定资源可用性

调度程序使用 node.Status.Allocatable(而非 node.Status.Capacity)的值来决定节点是否成为 pod 调度的候选者。

在默认情况下,节点会将其机器容量报告为可完全被集群调度。

4.8.2. 为节点配置分配的资源

OpenShift Container Platform 支持对 CPU 和内存资源类型执行分配。如果管理员启用了临时存储技术预览功能,则也支持 ephemeral-resource 资源类型。对于 cpu 类型,资源数量以内核数为单位来指定,例如 200m0.51。对于 memoryephemeral-storage,则以字节数为单位来指定,例如 200Ki50Mi5Gi

作为管理员,您可以通过一组 <resource_type>=<resource_quantity> 对(如 cpu=200m,memory=512Mi)来利用自定义资源 (CR) 进行设置。

先决条件

  1. 若要帮助自己确定 --system-reserved--kube-reserved 的设置,您可以使用节点概述 API 内省相应节点的资源使用情况,该 API 可通过 /api/v1/nodes/<node>/proxy/stats/summary 访问。对节点运行以下命令:

    $ oc get --raw /api/v1/nodes/<node>/proxy/stats/summary

    例如,若要访问 cluster.node22 节点的资源,您可以运行:

    $ oc get --raw /api/v1/nodes/cluster.node22/proxy/stats/summary
    {
        "node": {
            "nodeName": "cluster.node22",
            "systemContainers": [
                {
                    "cpu": {
                        "usageCoreNanoSeconds": 929684480915,
                        "usageNanoCores": 190998084
                    },
                    "memory": {
                        "rssBytes": 176726016,
                        "usageBytes": 1397895168,
                        "workingSetBytes": 1050509312
                    },
                    "name": "kubelet"
                },
                {
                    "cpu": {
                        "usageCoreNanoSeconds": 128521955903,
                        "usageNanoCores": 5928600
                    },
                    "memory": {
                        "rssBytes": 35958784,
                        "usageBytes": 129671168,
                        "workingSetBytes": 102416384
                    },
                    "name": "runtime"
                }
            ]
        }
    }
  2. 为您要配置的节点类型获取与静态机器配置池 CRD 关联的标签。执行以下步骤之一:

    1. 查看 Machine Config Pool:

      $ oc describe machineconfigpool <name>

      例如:

      $ oc describe machineconfigpool worker
      
      apiVersion: machineconfiguration.openshift.io/v1
      kind: MachineConfigPool
      metadata:
        creationTimestamp: 2019-02-08T14:52:39Z
        generation: 1
        labels:
          custom-kubelet: small-pods 1
      1
      如果添加了标签,它会出现在 labels 下。
    2. 如果标签不存在,则添加一个键/值对:

      $ oc label machineconfigpool worker custom-kubelet=small-pods

流程

  1. 为配置更改创建自定义资源 (CR)。

    资源分配 CR 的示例配置

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: set-allocatable 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: small-pods 2
      kubeletConfig:
        systemReserved:
          cpu: 500m
          memory: 512Mi
        kubeReserved:
          cpu: 500m
          memory: 512Mi


为了尽快向用户提供最新的信息,本文档可能会包括由机器自动从英文原文翻译的内容。如需更多信息,请参阅此说明。