×

关于 NUMA 感知调度

NUMA 简介

非一致性内存访问 (NUMA) 是一种计算平台架构,允许不同的 CPU 以不同的速度访问不同的内存区域。NUMA 资源拓扑是指 CPU、内存和 PCI 设备在计算节点中彼此相对的位置。位于同一位置的资源被称为位于相同的 *NUMA 区域*。对于高性能应用程序,集群需要在一个 NUMA 区域中处理 Pod 工作负载。

性能注意事项

NUMA 架构允许具有多个内存控制器的 CPU 使用 CPU 复杂体中任何可用的内存,而不管内存位于何处。这增加了灵活性,但以牺牲性能为代价。使用位于其 NUMA 区域之外的内存处理工作负载的 CPU 比在一个 NUMA 区域中处理的工作负载慢。此外,对于 I/O 受限的工作负载,位于远处 NUMA 区域的网络接口会降低信息到达应用程序的速度。高性能工作负载(例如电信工作负载)在这种情况下无法达到规格要求。

NUMA 感知调度

NUMA 感知调度将请求的集群计算资源(CPU、内存、设备)对齐到同一 NUMA 区域,以高效处理对延迟敏感或高性能的工作负载。NUMA 感知调度还可以提高每个计算节点的 Pod 密度,从而提高资源效率。

与节点调优操作符集成

通过将节点调优操作符的性能配置文件与 NUMA 感知调度集成,您可以进一步配置 CPU 亲和性以优化对延迟敏感型工作负载的性能。

默认调度逻辑

默认的 OpenShift Container Platform Pod 调度器调度逻辑会考虑整个计算节点的可用资源,而不是单个 NUMA 区域。如果在 kubelet topology manager 中请求最严格的资源对齐,则在将 Pod 接纳到节点时可能会发生错误情况。相反,如果未请求最严格的资源对齐,则可以将 Pod 接纳到节点而无需正确的资源对齐,从而导致性能下降或不可预测。例如,当 Pod 调度器针对保证型 Pod 工作负载做出次优调度决策时,在不知道 Pod 请求的资源是否可用时,可能会出现带有Topology Affinity Error状态的失控 Pod 创建。调度不匹配决策可能会导致 Pod 启动延迟无限期延长。此外,根据集群状态和资源分配,糟糕的 Pod 调度决策可能会由于启动尝试失败而导致集群额外负载。

NUMA 感知 Pod 调度图

NUMA 资源操作符部署自定义的 NUMA 资源辅助调度器和其他资源,以减轻默认 OpenShift Container Platform Pod 调度器的缺点。下图提供了 NUMA 感知 Pod 调度的概述。

Diagram of NUMA-aware scheduling that shows how the various components interact with each other in the cluster
图 1. NUMA 感知调度概述
NodeResourceTopology API

NodeResourceTopology API 描述每个计算节点中可用的 NUMA 区域资源。

NUMA 感知调度器

NUMA 感知辅助调度器从NodeResourceTopology API 接收有关可用 NUMA 区域的信息,并在可以最佳处理的节点上调度高性能工作负载。

节点拓扑导出器

节点拓扑导出器将每个计算节点的可用 NUMA 区域资源暴露给NodeResourceTopology API。节点拓扑导出器守护进程使用PodResources API 跟踪 kubelet 的资源分配。

PodResources API

PodResources API 位于每个节点本地,并将资源拓扑和可用资源暴露给 kubelet。

PodResources API 的List端点会暴露分配给特定容器的独占 CPU。该 API 不会暴露属于共享池的 CPU。

GetAllocatableResources端点暴露节点上可用的可分配资源。

其他资源
  • 有关在集群中运行辅助 Pod 调度器以及如何使用辅助 Pod 调度器部署 Pod 的更多信息,请参阅使用辅助调度器调度 Pod

安装 NUMA 资源操作符

NUMA 资源操作符部署允许您调度 NUMA 感知工作负载和部署的资源。您可以使用 OpenShift Container Platform CLI 或 Web 控制台安装 NUMA 资源操作符。

使用 CLI 安装 NUMA 资源操作符

作为集群管理员,您可以使用 CLI 安装操作符。

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

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

步骤
  1. 为 NUMA 资源操作符创建一个命名空间

    1. 将以下 YAML 保存到nro-namespace.yaml文件中

      apiVersion: v1
      kind: Namespace
      metadata:
        name: openshift-numaresources
    2. 通过运行以下命令创建Namespace CR

      $ oc create -f nro-namespace.yaml
  2. 为 NUMA 资源操作符创建操作符组

    1. 将以下 YAML 保存到nro-operatorgroup.yaml文件中

      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: numaresources-operator
        namespace: openshift-numaresources
      spec:
        targetNamespaces:
        - openshift-numaresources
    2. 通过运行以下命令创建OperatorGroup CR

      $ oc create -f nro-operatorgroup.yaml
  3. 为 NUMA 资源操作符创建订阅

    1. 将以下 YAML 保存到nro-sub.yaml文件中

      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: numaresources-operator
        namespace: openshift-numaresources
      spec:
        channel: "4.17"
        name: numaresources-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace
    2. 通过运行以下命令创建Subscription CR

      $ oc create -f nro-sub.yaml
验证
  1. 通过检查openshift-numaresources命名空间中的 CSV 资源来验证安装是否成功。运行以下命令

    $ oc get csv -n openshift-numaresources
    示例输出
    NAME                             DISPLAY                  VERSION   REPLACES   PHASE
    numaresources-operator.v4.17.2   numaresources-operator   4.17.2               Succeeded

使用 Web 控制台安装 NUMA 资源操作符

作为集群管理员,您可以使用 Web 控制台安装 NUMA 资源操作符。

步骤
  1. 为 NUMA 资源操作符创建一个命名空间

    1. 在 OpenShift Container Platform Web 控制台中,单击**管理**→**命名空间**。

    2. 单击**创建命名空间**,在**名称**字段中输入openshift-numaresources,然后单击**创建**。

  2. 安装 NUMA 资源操作符

    1. 在 OpenShift Container Platform Web 控制台中,单击**操作符**→**OperatorHub**。

    2. 从可用操作符列表中选择**numaresources-operator**,然后单击**安装**。

    3. 在**已安装的命名空间**字段中,选择openshift-numaresources命名空间,然后单击**安装**。

  3. 可选:验证 NUMA 资源操作符是否已成功安装

    1. 切换到**操作符**→**已安装的操作符**页面。

    2. 确保**NUMA 资源操作符**列在openshift-numaresources命名空间中,且**状态**为**InstallSucceeded**。

      在安装过程中,操作符可能会显示**失败**状态。如果安装稍后成功并显示**InstallSucceeded**消息,则可以忽略**失败**消息。

      如果操作符未显示为已安装,则需要进一步排查

      • 转到**操作符**→**已安装的操作符**页面,并检查**操作符订阅**和**安装计划**选项卡中**状态**下的任何失败或错误。

      • 转到**工作负载**→**Pod**页面,并检查default项目中 Pod 的日志。

调度 NUMA 感知工作负载

运行对延迟敏感型工作负载的集群通常具有有助于最大限度地减少工作负载延迟和优化性能的性能配置文件。NUMA 感知调度器会根据可用的节点 NUMA 资源以及应用于节点的任何性能配置文件设置来部署工作负载。NUMA 感知部署和工作负载的性能配置文件相结合,确保以最大限度地提高性能的方式调度工作负载。

要使 NUMA 资源操作符完全运行,必须部署NUMAResourcesOperator自定义资源和 NUMA 感知辅助 Pod 调度器。

创建 NUMAResourcesOperator 自定义资源

安装 NUMA 资源操作符后,创建NUMAResourcesOperator自定义资源 (CR),该资源指示 NUMA 资源操作符安装支持 NUMA 感知调度器所需的所有集群基础设施,包括守护程序集和 API。

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

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

  • 安装 NUMA 资源操作符。

步骤
  1. 创建NUMAResourcesOperator自定义资源

    1. 将以下最小必需的 YAML 文件示例保存为nrop.yaml

      apiVersion: nodetopology.openshift.io/v1
      kind: NUMAResourcesOperator
      metadata:
        name: numaresourcesoperator
      spec:
        nodeGroups:
        - machineConfigPoolSelector:
            matchLabels:
              pools.operator.machineconfiguration.openshift.io/worker: "" (1)
      1 这应与您要配置 NUMA 资源操作符的MachineConfigPool匹配。例如,您可能已创建名为worker-cnfMachineConfigPool,该池指定一组预期运行电信工作负载的节点。
    2. 通过运行以下命令创建NUMAResourcesOperator CR

      $ oc create -f nrop.yaml

      创建NUMAResourcesOperator会在相应的机器配置池以及受影响的节点上触发重新引导。

验证
  1. 通过运行以下命令验证 NUMA 资源操作符是否已成功部署

    $ oc get numaresourcesoperators.nodetopology.openshift.io
    示例输出
    NAME                    AGE
    numaresourcesoperator   27s
  2. 几分钟后,运行以下命令以验证所需资源是否已成功部署

    $ oc get all -n openshift-numaresources
    示例输出
    NAME                                                    READY   STATUS    RESTARTS   AGE
    pod/numaresources-controller-manager-7d9d84c58d-qk2mr   1/1     Running   0          12m
    pod/numaresourcesoperator-worker-7d96r                  2/2     Running   0          97s
    pod/numaresourcesoperator-worker-crsht                  2/2     Running   0          97s
    pod/numaresourcesoperator-worker-jp9mw                  2/2     Running   0          97s

部署 NUMA 感知辅助 Pod 调度器

安装 NUMA 资源操作符后,请按照以下步骤部署 NUMA 感知型辅助 Pod 调度器。

步骤
  1. 创建NUMAResourcesScheduler自定义资源,用于部署 NUMA 感知型自定义 Pod 调度器。

    1. 将以下最小必需的 YAML 保存到nro-scheduler.yaml文件中。

      apiVersion: nodetopology.openshift.io/v1
      kind: NUMAResourcesScheduler
      metadata:
        name: numaresourcesscheduler
      spec:
        imageSpec: "registry.redhat.io/openshift4/noderesourcetopology-scheduler-rhel9:v4.17" (1)
      1 在断开连接的环境中,请确保通过以下任一方法配置此镜像的分辨率:
      • 创建ImageTagMirrorSet自定义资源 (CR)。更多信息,请参见“附加资源”部分中的“配置镜像注册表仓库镜像”。

      • 将 URL 设置为断开连接的注册表。

    2. 运行以下命令创建NUMAResourcesScheduler CR。

      $ oc create -f nro-scheduler.yaml
  2. 几秒钟后,运行以下命令确认所需资源已成功部署。

    $ oc get all -n openshift-numaresources
    示例输出
    NAME                                                    READY   STATUS    RESTARTS   AGE
    pod/numaresources-controller-manager-7d9d84c58d-qk2mr   1/1     Running   0          12m
    pod/numaresourcesoperator-worker-7d96r                  2/2     Running   0          97s
    pod/numaresourcesoperator-worker-crsht                  2/2     Running   0          97s
    pod/numaresourcesoperator-worker-jp9mw                  2/2     Running   0          97s
    pod/secondary-scheduler-847cb74f84-9whlm                1/1     Running   0          10m
    
    NAME                                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                     AGE
    daemonset.apps/numaresourcesoperator-worker   3         3         3       3            3           node-role.kubernetes.io/worker=   98s
    
    NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/numaresources-controller-manager   1/1     1            1           12m
    deployment.apps/secondary-scheduler                1/1     1            1           10m
    
    NAME                                                          DESIRED   CURRENT   READY   AGE
    replicaset.apps/numaresources-controller-manager-7d9d84c58d   1         1         1       12m
    replicaset.apps/secondary-scheduler-847cb74f84                1         1         1       10m

配置单个 NUMA 节点策略

NUMA 资源操作符要求在集群上配置单个 NUMA 节点策略。这可以通过两种方式实现:创建和应用性能配置文件,或配置 KubeletConfig。

配置单个 NUMA 节点策略的首选方法是应用性能配置文件。您可以使用性能配置文件创建器 (PPC) 工具创建性能配置文件。如果在集群上创建了性能配置文件,它会自动创建其他调整组件,例如KubeletConfigtuned配置文件。

有关创建性能配置文件的更多信息,请参见“附加资源”部分中的“关于性能配置文件创建器”。

示例性能配置文件

此示例 YAML 显示了使用性能配置文件创建器 (PPC) 工具创建的性能配置文件。

apiVersion: performance.openshift.io/v2
kind: PerformanceProfile
metadata:
  name: performance
spec:
  cpu:
    isolated: "3"
    reserved: 0-2
  machineConfigPoolSelector:
    pools.operator.machineconfiguration.openshift.io/worker: "" (1)
  nodeSelector:
    node-role.kubernetes.io/worker: ""
  numa:
    topologyPolicy: single-numa-node (2)
  realTimeKernel:
    enabled: true
  workloadHints:
    highPowerConsumption: true
    perPodPowerManagement: false
    realTime: true
1 这应该与您想要在其上配置 NUMA 资源操作符的MachineConfigPool匹配。例如,您可能已创建了一个名为worker-cnfMachineConfigPool,它指定了一组运行电信工作负载的节点。
2 必须将topologyPolicy设置为single-numa-node。运行 PPC 工具时,请将topology-manager-policy参数设置为single-numa-node,以确保这一点。

创建 KubeletConfig CRD

配置单个 NUMA 节点策略的推荐方法是应用性能配置文件。另一种方法是创建和应用KubeletConfig自定义资源 (CR),如下所示。

步骤
  1. 创建KubeletConfig自定义资源 (CR),用于配置机器配置文件的 Pod 准入策略。

    1. 将以下 YAML 保存到nro-kubeletconfig.yaml文件中。

      apiVersion: machineconfiguration.openshift.io/v1
      kind: KubeletConfig
      metadata:
        name: worker-tuning
      spec:
        machineConfigPoolSelector:
          matchLabels:
            pools.operator.machineconfiguration.openshift.io/worker: "" (1)
        kubeletConfig:
          cpuManagerPolicy: "static" (2)
          cpuManagerReconcilePeriod: "5s"
          reservedSystemCPUs: "0,1" (3)
          memoryManagerPolicy: "Static" (4)
          evictionHard:
            memory.available: "100Mi"
          kubeReserved:
            memory: "512Mi"
          reservedMemory:
            - numaNode: 0
              limits:
                memory: "1124Mi"
          systemReserved:
            memory: "512Mi"
          topologyManagerPolicy: "single-numa-node" (5)
      1 调整此标签以匹配NUMAResourcesOperator CR 中的machineConfigPoolSelector
      2 对于cpuManagerPolicystatic必须使用小写s
      3 根据节点上的 CPU 进行调整。
      4 对于memoryManagerPolicyStatic必须使用大写S
      5 topologyManagerPolicy必须设置为single-numa-node
    2. 运行以下命令创建KubeletConfig CR。

      $ oc create -f nro-kubeletconfig.yaml

      应用性能配置文件或KubeletConfig会自动触发节点重启。如果未触发重启,您可以查看KubeletConfig中处理节点组的标签来排除问题。

使用 NUMA 感知型调度器调度工作负载

现在topo-aware-scheduler已安装,NUMAResourcesOperatorNUMAResourcesScheduler CR 已应用,并且您的集群具有匹配的性能配置文件或kubeletconfig,您可以使用指定处理工作负载所需最小资源的部署 CR 来使用 NUMA 感知型调度器调度工作负载。

以下示例部署使用 NUMA 感知型调度来处理示例工作负载。

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

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

步骤
  1. 运行以下命令获取在集群中部署的 NUMA 感知型调度器的名称。

    $ oc get numaresourcesschedulers.nodetopology.openshift.io numaresourcesscheduler -o json | jq '.status.schedulerName'
    示例输出
    "topo-aware-scheduler"
  2. 创建一个使用名为topo-aware-scheduler的调度器的Deployment CR,例如

    1. 将以下 YAML 保存到nro-deployment.yaml文件中。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: numa-deployment-1
        namespace: openshift-numaresources
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: test
        template:
          metadata:
            labels:
              app: test
          spec:
            schedulerName: topo-aware-scheduler (1)
            containers:
            - name: ctnr
              image: quay.io/openshifttest/hello-openshift:openshift
              imagePullPolicy: IfNotPresent
              resources:
                limits:
                  memory: "100Mi"
                  cpu: "10"
                requests:
                  memory: "100Mi"
                  cpu: "10"
            - name: ctnr2
              image: registry.access.redhat.com/rhel:latest
              imagePullPolicy: IfNotPresent
              command: ["/bin/sh", "-c"]
              args: [ "while true; do sleep 1h; done;" ]
              resources:
                limits:
                  memory: "100Mi"
                  cpu: "8"
                requests:
                  memory: "100Mi"
                  cpu: "8"
      1 schedulerName必须与在您的集群中部署的 NUMA 感知型调度器的名称匹配,例如topo-aware-scheduler
    2. 运行以下命令创建Deployment CR。

      $ oc create -f nro-deployment.yaml
验证
  1. 验证部署是否成功。

    $ oc get pods -n openshift-numaresources
    示例输出
    NAME                                                READY   STATUS    RESTARTS   AGE
    numa-deployment-1-6c4f5bdb84-wgn6g                  2/2     Running   0          5m2s
    numaresources-controller-manager-7d9d84c58d-4v65j   1/1     Running   0          18m
    numaresourcesoperator-worker-7d96r                  2/2     Running   4          43m
    numaresourcesoperator-worker-crsht                  2/2     Running   2          43m
    numaresourcesoperator-worker-jp9mw                  2/2     Running   2          43m
    secondary-scheduler-847cb74f84-fpncj                1/1     Running   0          18m
  2. 运行以下命令验证topo-aware-scheduler是否正在调度已部署的 Pod。

    $ oc describe pod numa-deployment-1-6c4f5bdb84-wgn6g -n openshift-numaresources
    示例输出
    Events:
      Type    Reason          Age    From                  Message
      ----    ------          ----   ----                  -------
      Normal  Scheduled       4m45s  topo-aware-scheduler  Successfully assigned openshift-numaresources/numa-deployment-1-6c4f5bdb84-wgn6g to worker-1

    请求的资源超过可调度资源的部署将失败,并出现MinimumReplicasUnavailable错误。当所需资源可用时,部署成功。在所需资源可用之前,Pod 保持Pending状态。

  3. 验证节点是否列出了预期的已分配资源。

    1. 运行以下命令确定正在运行部署 Pod 的节点。

      $ oc get pods -n openshift-numaresources -o wide
      示例输出
      NAME                                 READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
      numa-deployment-1-6c4f5bdb84-wgn6g   0/2     Running   0          82m   10.128.2.50   worker-1   <none>  <none>
    2. 使用正在运行部署 Pod 的节点名称运行以下命令。

      $ oc describe noderesourcetopologies.topology.node.k8s.io worker-1
      示例输出
      ...
      
      Zones:
        Costs:
          Name:   node-0
          Value:  10
          Name:   node-1
          Value:  21
        Name:     node-0
        Resources:
          Allocatable:  39
          Available:    21 (1)
          Capacity:     40
          Name:         cpu
          Allocatable:  6442450944
          Available:    6442450944
          Capacity:     6442450944
          Name:         hugepages-1Gi
          Allocatable:  134217728
          Available:    134217728
          Capacity:     134217728
          Name:         hugepages-2Mi
          Allocatable:  262415904768
          Available:    262206189568
          Capacity:     270146007040
          Name:         memory
        Type:           Node
      1 由于已分配给保证型 Pod 的资源,Available容量已减少。

      保证型 Pod 消耗的资源会从noderesourcetopologies.topology.node.k8s.io下列出的可用节点资源中减去。

  4. 具有Best-effortBurstable服务质量 (qosClass) 的 Pod 的资源分配不会反映在noderesourcetopologies.topology.node.k8s.io下的 NUMA 节点资源中。如果 Pod 的消耗资源未反映在节点资源计算中,请验证 Pod 是否具有GuaranteedqosClass,并且 CPU 请求是整数而不是小数。您可以通过运行以下命令来验证 Pod 是否具有GuaranteedqosClass

    $ oc get pod numa-deployment-1-6c4f5bdb84-wgn6g -n openshift-numaresources -o jsonpath="{ .status.qosClass }"
    示例输出
    Guaranteed

可选:配置 NUMA 资源更新的轮询操作

NUMA 资源操作符控制的守护进程在其nodeGroup中轮询资源以检索有关可用 NUMA 资源的更新。您可以通过配置NUMAResourcesOperator自定义资源 (CR) 中的spec.nodeGroups规范来微调这些守护进程的轮询操作。这提供了对轮询操作的高级控制。配置这些规范以改进调度行为并排除次优调度决策的故障。

配置选项如下:

  • infoRefreshMode:确定轮询 kubelet 的触发条件。NUMA 资源操作符会将结果信息报告给 API 服务器。

  • infoRefreshPeriod:确定轮询更新之间的持续时间。

  • podsFingerprinting:确定是否在轮询更新中公开当前在节点上运行的 Pod 集的某个时间点信息。

    podsFingerprinting 的默认值为 EnabledExclusiveResources。为了优化调度程序性能,请将 podsFingerprinting 设置为 EnabledExclusiveResourcesEnabled。此外,请在 NUMAResourcesScheduler 自定义资源 (CR) 中将 cacheResyncPeriod 配置为大于 0 的值。cacheResyncPeriod 规范有助于通过监控节点上的待处理资源来报告更精确的资源可用性。

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

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

  • 安装 NUMA 资源操作符。

步骤
  • 在您的 NUMAResourcesOperator CR 中配置 spec.nodeGroups 规范

    apiVersion: nodetopology.openshift.io/v1
    kind: NUMAResourcesOperator
    metadata:
      name: numaresourcesoperator
    spec:
      nodeGroups:
      - config:
          infoRefreshMode: Periodic (1)
          infoRefreshPeriod: 10s (2)
          podsFingerprinting: Enabled (3)
        name: worker
    1 有效值为 PeriodicEventsPeriodicAndEvents。使用 Periodic 以您在 infoRefreshPeriod 中定义的间隔轮询 kubelet。使用 Events 在每个 Pod 生命周期事件时轮询 kubelet。使用 PeriodicAndEvents 启用这两种方法。
    2 定义 PeriodicPeriodicAndEvents 刷新模式的轮询间隔。如果刷新模式为 Events,则忽略此字段。
    3 有效值为 EnabledDisabledEnabledExclusiveResources。对于 NUMAResourcesScheduler 中的 cacheResyncPeriod 规范,必须设置为 EnabledEnabledExclusiveResources
验证
  1. 部署 NUMA 资源操作符后,请运行以下命令验证节点组配置是否已应用

    $ oc get numaresop numaresourcesoperator -o json | jq '.status'
    示例输出
          ...
    
            "config": {
            "infoRefreshMode": "Periodic",
            "infoRefreshPeriod": "10s",
            "podsFingerprinting": "Enabled"
          },
          "name": "worker"
    
          ...

NUMA 感知调度的故障排除

要对 NUMA 感知 Pod 调度的常见问题进行故障排除,请执行以下步骤。

先决条件
  • 安装 OpenShift Container Platform 命令行界面 (oc)。

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

  • 安装 NUMA 资源操作符并部署 NUMA 感知辅助调度程序。

步骤
  1. 通过运行以下命令验证 noderesourcetopologies CRD 是否已部署到集群中

    $ oc get crd | grep noderesourcetopologies
    示例输出
    NAME                                                              CREATED AT
    noderesourcetopologies.topology.node.k8s.io                       2022-01-18T08:28:06Z
  2. 检查 NUMA 感知调度程序名称是否与 NUMA 感知工作负载中指定的名称匹配,方法是运行以下命令

    $ oc get numaresourcesschedulers.nodetopology.openshift.io numaresourcesscheduler -o json | jq '.status.schedulerName'
    示例输出
    topo-aware-scheduler
  3. 验证 NUMA 感知可调度节点是否已应用 noderesourcetopologies CR。运行以下命令

    $ oc get noderesourcetopologies.topology.node.k8s.io
    示例输出
    NAME                    AGE
    compute-0.example.com   17h
    compute-1.example.com   17h

    节点数应等于机器配置池 (mcp) 工作程序定义配置的工作程序节点数。

  4. 通过运行以下命令验证所有可调度节点的 NUMA 区域粒度

    $ oc get noderesourcetopologies.topology.node.k8s.io -o yaml
    示例输出
    apiVersion: v1
    items:
    - apiVersion: topology.node.k8s.io/v1
      kind: NodeResourceTopology
      metadata:
        annotations:
          k8stopoawareschedwg/rte-update: periodic
        creationTimestamp: "2022-06-16T08:55:38Z"
        generation: 63760
        name: worker-0
        resourceVersion: "8450223"
        uid: 8b77be46-08c0-4074-927b-d49361471590
      topologyPolicies:
      - SingleNUMANodeContainerLevel
      zones:
      - costs:
        - name: node-0
          value: 10
        - name: node-1
          value: 21
        name: node-0
        resources:
        - allocatable: "38"
          available: "38"
          capacity: "40"
          name: cpu
        - allocatable: "134217728"
          available: "134217728"
          capacity: "134217728"
          name: hugepages-2Mi
        - allocatable: "262352048128"
          available: "262352048128"
          capacity: "270107316224"
          name: memory
        - allocatable: "6442450944"
          available: "6442450944"
          capacity: "6442450944"
          name: hugepages-1Gi
        type: Node
      - costs:
        - name: node-0
          value: 21
        - name: node-1
          value: 10
        name: node-1
        resources:
        - allocatable: "268435456"
          available: "268435456"
          capacity: "268435456"
          name: hugepages-2Mi
        - allocatable: "269231067136"
          available: "269231067136"
          capacity: "270573244416"
          name: memory
        - allocatable: "40"
          available: "40"
          capacity: "40"
          name: cpu
        - allocatable: "1073741824"
          available: "1073741824"
          capacity: "1073741824"
          name: hugepages-1Gi
        type: Node
    - apiVersion: topology.node.k8s.io/v1
      kind: NodeResourceTopology
      metadata:
        annotations:
          k8stopoawareschedwg/rte-update: periodic
        creationTimestamp: "2022-06-16T08:55:37Z"
        generation: 62061
        name: worker-1
        resourceVersion: "8450129"
        uid: e8659390-6f8d-4e67-9a51-1ea34bba1cc3
      topologyPolicies:
      - SingleNUMANodeContainerLevel
      zones: (1)
      - costs:
        - name: node-0
          value: 10
        - name: node-1
          value: 21
        name: node-0
        resources: (2)
        - allocatable: "38"
          available: "38"
          capacity: "40"
          name: cpu
        - allocatable: "6442450944"
          available: "6442450944"
          capacity: "6442450944"
          name: hugepages-1Gi
        - allocatable: "134217728"
          available: "134217728"
          capacity: "134217728"
          name: hugepages-2Mi
        - allocatable: "262391033856"
          available: "262391033856"
          capacity: "270146301952"
          name: memory
        type: Node
      - costs:
        - name: node-0
          value: 21
        - name: node-1
          value: 10
        name: node-1
        resources:
        - allocatable: "40"
          available: "40"
          capacity: "40"
          name: cpu
        - allocatable: "1073741824"
          available: "1073741824"
          capacity: "1073741824"
          name: hugepages-1Gi
        - allocatable: "268435456"
          available: "268435456"
          capacity: "268435456"
          name: hugepages-2Mi
        - allocatable: "269192085504"
          available: "269192085504"
          capacity: "270534262784"
          name: memory
        type: Node
    kind: List
    metadata:
      resourceVersion: ""
      selfLink: ""
    1 zones 下的每个部分描述单个 NUMA 区域的资源。
    2 resources 描述 NUMA 区域资源的当前状态。检查 items.zones.resources.available 下列出的资源是否与分配给每个保证型 Pod 的独占 NUMA 区域资源相对应。

报告更精确的资源可用性

启用 cacheResyncPeriod 规范,以帮助 NUMA 资源操作符通过监控节点上的待处理资源并在定义的间隔内将此信息同步到调度程序缓存中来报告更精确的资源可用性。这也有助于最大限度地减少由于次优调度决策而导致的拓扑亲和性错误。间隔越短,网络负载越大。cacheResyncPeriod 规范默认情况下处于禁用状态。

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

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

步骤
  1. 删除当前正在运行的 NUMAResourcesScheduler 资源

    1. 通过运行以下命令获取活动的 NUMAResourcesScheduler

      $ oc get NUMAResourcesScheduler
      示例输出
      NAME                     AGE
      numaresourcesscheduler   92m
    2. 通过运行以下命令删除辅助调度程序资源

      $ oc delete NUMAResourcesScheduler numaresourcesscheduler
      示例输出
      numaresourcesscheduler.nodetopology.openshift.io "numaresourcesscheduler" deleted
  2. 将以下 YAML 保存到文件 nro-scheduler-cacheresync.yaml 中。此示例将日志级别更改为 Debug

    apiVersion: nodetopology.openshift.io/v1
    kind: NUMAResourcesScheduler
    metadata:
      name: numaresourcesscheduler
    spec:
      imageSpec: "registry.redhat.io/openshift4/noderesourcetopology-scheduler-container-rhel8:v4.17"
      cacheResyncPeriod: "5s" (1)
    1 输入以秒为单位的调度程序缓存同步间隔值。对于大多数实现,5s 是一个典型值。
  3. 通过运行以下命令创建更新后的 NUMAResourcesScheduler 资源

    $ oc create -f nro-scheduler-cacheresync.yaml
    示例输出
    numaresourcesscheduler.nodetopology.openshift.io/numaresourcesscheduler created
验证步骤
  1. 检查 NUMA 感知调度程序是否已成功部署

    1. 运行以下命令检查 CRD 是否已成功创建

      $ oc get crd | grep numaresourcesschedulers
      示例输出
      NAME                                                              CREATED AT
      numaresourcesschedulers.nodetopology.openshift.io                 2022-02-25T11:57:03Z
    2. 通过运行以下命令检查新的自定义调度程序是否可用

      $ oc get numaresourcesschedulers.nodetopology.openshift.io
      示例输出
      NAME                     AGE
      numaresourcesscheduler   3h26m
  2. 检查调度程序的日志是否显示提高的日志级别

    1. 通过运行以下命令获取在 openshift-numaresources 命名空间中运行的 Pod 列表

      $ oc get pods -n openshift-numaresources
      示例输出
      NAME                                               READY   STATUS    RESTARTS   AGE
      numaresources-controller-manager-d87d79587-76mrm   1/1     Running   0          46h
      numaresourcesoperator-worker-5wm2k                 2/2     Running   0          45h
      numaresourcesoperator-worker-pb75c                 2/2     Running   0          45h
      secondary-scheduler-7976c4d466-qm4sc               1/1     Running   0          21m
    2. 通过运行以下命令获取辅助调度程序 Pod 的日志

      $ oc logs secondary-scheduler-7976c4d466-qm4sc -n openshift-numaresources
      示例输出
      ...
      I0223 11:04:55.614788       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.Namespace total 11 items received
      I0223 11:04:56.609114       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.ReplicationController total 10 items received
      I0223 11:05:22.626818       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.StorageClass total 7 items received
      I0223 11:05:31.610356       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.PodDisruptionBudget total 7 items received
      I0223 11:05:31.713032       1 eventhandlers.go:186] "Add event for scheduled pod" pod="openshift-marketplace/certified-operators-thtvq"
      I0223 11:05:53.461016       1 eventhandlers.go:244] "Delete event for scheduled pod" pod="openshift-marketplace/certified-operators-thtvq"

检查 NUMA 感知调度程序日志

通过查看日志来对 NUMA 感知调度程序的问题进行故障排除。如果需要,您可以通过修改 NUMAResourcesScheduler 资源的 spec.logLevel 字段来提高调度程序日志级别。可接受的值为 NormalDebugTrace,其中 Trace 是最详细的选项。

要更改辅助调度程序的日志级别,请删除正在运行的调度程序资源,并使用更改后的日志级别重新部署它。在此停机期间,调度程序无法调度新的工作负载。

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

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

步骤
  1. 删除当前正在运行的 NUMAResourcesScheduler 资源

    1. 通过运行以下命令获取活动的 NUMAResourcesScheduler

      $ oc get NUMAResourcesScheduler
      示例输出
      NAME                     AGE
      numaresourcesscheduler   90m
    2. 通过运行以下命令删除辅助调度程序资源

      $ oc delete NUMAResourcesScheduler numaresourcesscheduler
      示例输出
      numaresourcesscheduler.nodetopology.openshift.io "numaresourcesscheduler" deleted
  2. 将以下 YAML 保存到文件 nro-scheduler-debug.yaml 中。此示例将日志级别更改为 Debug

    apiVersion: nodetopology.openshift.io/v1
    kind: NUMAResourcesScheduler
    metadata:
      name: numaresourcesscheduler
    spec:
      imageSpec: "registry.redhat.io/openshift4/noderesourcetopology-scheduler-container-rhel8:v4.17"
      logLevel: Debug
  3. 通过运行以下命令创建更新后的 Debug 日志记录 NUMAResourcesScheduler 资源

    $ oc create -f nro-scheduler-debug.yaml
    示例输出
    numaresourcesscheduler.nodetopology.openshift.io/numaresourcesscheduler created
验证步骤
  1. 检查 NUMA 感知调度程序是否已成功部署

    1. 运行以下命令检查 CRD 是否已成功创建

      $ oc get crd | grep numaresourcesschedulers
      示例输出
      NAME                                                              CREATED AT
      numaresourcesschedulers.nodetopology.openshift.io                 2022-02-25T11:57:03Z
    2. 通过运行以下命令检查新的自定义调度程序是否可用

      $ oc get numaresourcesschedulers.nodetopology.openshift.io
      示例输出
      NAME                     AGE
      numaresourcesscheduler   3h26m
  2. 检查调度程序的日志是否显示提高的日志级别

    1. 通过运行以下命令获取在 openshift-numaresources 命名空间中运行的 Pod 列表

      $ oc get pods -n openshift-numaresources
      示例输出
      NAME                                               READY   STATUS    RESTARTS   AGE
      numaresources-controller-manager-d87d79587-76mrm   1/1     Running   0          46h
      numaresourcesoperator-worker-5wm2k                 2/2     Running   0          45h
      numaresourcesoperator-worker-pb75c                 2/2     Running   0          45h
      secondary-scheduler-7976c4d466-qm4sc               1/1     Running   0          21m
    2. 通过运行以下命令获取辅助调度程序 Pod 的日志

      $ oc logs secondary-scheduler-7976c4d466-qm4sc -n openshift-numaresources
      示例输出
      ...
      I0223 11:04:55.614788       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.Namespace total 11 items received
      I0223 11:04:56.609114       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.ReplicationController total 10 items received
      I0223 11:05:22.626818       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.StorageClass total 7 items received
      I0223 11:05:31.610356       1 reflector.go:535] k8s.io/client-go/informers/factory.go:134: Watch close - *v1.PodDisruptionBudget total 7 items received
      I0223 11:05:31.713032       1 eventhandlers.go:186] "Add event for scheduled pod" pod="openshift-marketplace/certified-operators-thtvq"
      I0223 11:05:53.461016       1 eventhandlers.go:244] "Delete event for scheduled pod" pod="openshift-marketplace/certified-operators-thtvq"

资源拓扑导出器的故障排除

通过检查相应的 resource-topology-exporter 日志来对出现意外结果的 noderesourcetopologies 对象进行故障排除。

建议集群中的 NUMA 资源拓扑导出器实例以其引用的节点命名。例如,名为 worker 的工作程序节点应具有名为 worker 的相应 noderesourcetopologies 对象。

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

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

步骤
  1. 获取由 NUMA 资源操作符管理的 DaemonSet。每个 DaemonSet 在 NUMAResourcesOperator CR 中都有一个相应的 nodeGroup。运行以下命令

    $ oc get numaresourcesoperators.nodetopology.openshift.io numaresourcesoperator -o jsonpath="{.status.daemonsets[0]}"
    示例输出
    {"name":"numaresourcesoperator-worker","namespace":"openshift-numaresources"}
  2. 使用上一步的 name 值获取感兴趣的 DaemonSet 的标签

    $ oc get ds -n openshift-numaresources numaresourcesoperator-worker -o jsonpath="{.spec.selector.matchLabels}"
    示例输出
    {"name":"resource-topology"}
  3. 通过运行以下命令获取使用 resource-topology 标签的 Pod

    $ oc get pods -n openshift-numaresources -l name=resource-topology -o wide
    示例输出
    NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE
    numaresourcesoperator-worker-5wm2k   2/2     Running   0          2d1h   10.135.0.64   compute-0.example.com
    numaresourcesoperator-worker-pb75c   2/2     Running   0          2d1h   10.132.2.33   compute-1.example.com
  4. 检查在与您正在进行故障排除的节点相对应的工作程序 Pod 上运行的 resource-topology-exporter 容器的日志。运行以下命令

    $ oc logs -n openshift-numaresources -c resource-topology-exporter numaresourcesoperator-worker-pb75c
    示例输出
    I0221 13:38:18.334140       1 main.go:206] using sysinfo:
    reservedCpus: 0,1
    reservedMemory:
      "0": 1178599424
    I0221 13:38:18.334370       1 main.go:67] === System information ===
    I0221 13:38:18.334381       1 sysinfo.go:231] cpus: reserved "0-1"
    I0221 13:38:18.334493       1 sysinfo.go:237] cpus: online "0-103"
    I0221 13:38:18.546750       1 main.go:72]
    cpus: allocatable "2-103"
    hugepages-1Gi:
      numa cell 0 -> 6
      numa cell 1 -> 1
    hugepages-2Mi:
      numa cell 0 -> 64
      numa cell 1 -> 128
    memory:
      numa cell 0 -> 45758Mi
      numa cell 1 -> 48372Mi

更正缺少的资源拓扑导出器 ConfigMap

如果您在具有配置错误的集群设置的集群中安装 NUMA 资源操作符,则在某些情况下,操作符显示为活动状态,但资源拓扑导出器 (RTE) DaemonSet Pod 的日志显示 RTE 的配置缺失,例如

Info: couldn't find configuration in "/etc/resource-topology-exporter/config.yaml"

此日志消息表明集群中未正确应用具有所需配置的 kubeletconfig,导致缺少 RTE configmap。例如,以下集群缺少 numaresourcesoperator-worker configmap 自定义资源 (CR)

$ oc get configmap
示例输出
NAME                           DATA   AGE
0e2a6bd3.openshift-kni.io      0      6d21h
kube-root-ca.crt               1      6d21h
openshift-service-ca.crt       1      6d21h
topo-aware-scheduler-config    1      6d18h

在正确配置的集群中,oc get configmap 还会返回 numaresourcesoperator-worker configmap CR。

先决条件
  • 安装 OpenShift Container Platform 命令行界面 (oc)。

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

  • 安装 NUMA 资源操作符并部署 NUMA 感知辅助调度程序。

步骤
  1. 使用以下命令比较 kubeletconfigspec.machineConfigPoolSelector.matchLabels 的值和 MachineConfigPool (mcp) 工作程序 CR 中 metadata.labels 的值

    1. 通过运行以下命令检查 kubeletconfig 标签

      $ oc get kubeletconfig -o yaml
      示例输出
      machineConfigPoolSelector:
        matchLabels:
          cnf-worker-tuning: enabled
    2. 通过运行以下命令检查 mcp 标签

      $ oc get mcp worker -o yaml
      示例输出
      labels:
        machineconfiguration.openshift.io/mco-built-in: ""
        pools.operator.machineconfiguration.openshift.io/worker: ""

      cnf-worker-tuning: enabled 标签未出现在 MachineConfigPool 对象中。

  2. 编辑 MachineConfigPool CR 以包含缺少的标签,例如

    $ oc edit mcp worker -o yaml
    示例输出
    labels:
      machineconfiguration.openshift.io/mco-built-in: ""
      pools.operator.machineconfiguration.openshift.io/worker: ""
      cnf-worker-tuning: enabled
  3. 应用标签更改并等待集群应用更新的配置。运行以下命令

验证
  • 检查是否已应用缺少的 numaresourcesoperator-worker configmap CR

    $ oc get configmap
    示例输出
    NAME                           DATA   AGE
    0e2a6bd3.openshift-kni.io      0      6d21h
    kube-root-ca.crt               1      6d21h
    numaresourcesoperator-worker   1      5m
    openshift-service-ca.crt       1      6d21h
    topo-aware-scheduler-config    1      6d18h

收集 NUMA 资源操作符数据

您可以使用 oc adm must-gather CLI 命令来收集有关集群的信息,包括与 NUMA 资源操作符相关的功能和对象。

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

  • 您已安装 OpenShift CLI (oc)。

步骤
  • 要使用 must-gather 收集 NUMA 资源操作符数据,您必须指定 NUMA 资源操作符 must-gather 镜像。

    $ oc adm must-gather --image=registry.redhat.io/numaresources-must-gather/numaresources-must-gather-rhel9:v4.17