Kubernetes Pod/Container NUMA亲和管理

举报
Kubeservice@董江 发表于 2024/04/19 11:38:05 2024/04/19
【摘要】 Kubernetes Pod/Container NUMA亲和管理 背景先前工作中大量使用基于CPU、Memory亲和的感知调度实现, 目前对这部分统一梳理下,NUMA 感知涉及 memory 和cpu的亲和申请,并且余内存预留和cpu预留比较紧密,此处一起介绍下 CPU 管理默认情况下,kubelet 使用 CFS 配额 来执行 Pod 的 CPU 约束。 当节点上运行了很多 CPU 密...

Kubernetes Pod/Container NUMA亲和管理

背景

先前工作中大量使用基于CPU、Memory亲和的感知调度实现, 目前对这部分统一梳理下,NUMA 感知涉及 memory 和cpu的亲和申请,并且余内存预留和cpu预留比较紧密,此处一起介绍下

CPU 管理

默认情况下,kubelet 使用 CFS 配额 来执行 PodCPU 约束。 当节点上运行了很多 CPU 密集的 Pod 时,工作负载可能会迁移到不同的 CPU 核, 这取决于调度时 Pod 是否被扼制,以及哪些 CPU 核是可用的。 许多工作负载对这种迁移不敏感,因此无需任何干预即可正常工作。

KubernetesNode 节点会运行多个 Pod,其中会有部分的 Pod属于CPU密集型的工作负载。
在这种情况下,Pod 之间会争抢节点的 CPU 资源。当争抢剧烈的时候,Pod会在不同的CPU Core之间进行频繁的切换,更糟糕的是在NUMA Node之间的切换。这种大量的上下文切换,会影响程序运行的性能。

核心

通过 Pod/Container 启动中,更新 kubelet 优先配置好的可申请集合,将其更新到具体的 cgoup 下的 cpu_set 下,尽量将 cpu申请 优先在特定cpu范围上(尽可能)

具体可查看: https://github.com/klueska/kubernetes/tree/master/pkg/kubelet/cm/cpumanager

kubelet 开启策略

1. 要求:

CPU Manager 在 Kubernetes v1.12 引用为 beta; 在 Kubernetes v1.26 获得 stable.

2. 配置管理

kubelet 参数 --cpu-manager-policyKubeletConfiguration 中的 cpuManagerPolicy 字段来指定

--cpu-manager-policy=Static

支持两种策略:

  • none: 默认策略,表示现有的调度行为。可以理解为不开启cpu manager。
  • static: 允许为节点上具有某些资源特征的 Pod 赋予增强的 CPU 亲和性和独占性。

none 策略 显式地启用现有的默认 CPU亲和方案,不提供操作系统调度器默认行为之外的亲和性策略
static 策略针对具有整数型 CPU requestsGuaranteed Pod ,它允许该类 Pod 中的容器访问节点上的独占 CPU 资源。这种独占性是使用cpu_set cgroup 控制器来实现的。

CPU 管理器定期通过 CRI 写入资源更新,以保证内存中 CPU 分配与 cgroupfs 一致。同步频率通过新增的 Kubelet 配置参数 --cpu-manager-reconcile-period 来设置。如果不指定,默认与 --node-status-update-frequency 的周期(默认10s)相同。

3. 精细化配置

static 策略的行为可以使用 --cpu-manager-policy-options 参数来微调。该参数采用一个逗号分隔的 key=value 策略选项列表。此特性可以通过 CPUManagerPolicyOptions 特性门控来完全禁用。

CPUManagerPolicyOptions 也支持3种精确化管理:

  • full-pcpus-only: 分配完整的物理核心。此策略严格(1.22 或更高版本)
  • distribute-cpus-across-numa: 需要多个 NUMA 节点来满足分配的情况下, static 策略会在 NUMA 节点上平均分配 CPU.(1.23 或更高版本)
  • align-by-socket: 试图确保从 NUMA 节点的最小数量分配所有 CPU,但不能保证这些 NUMA 节点将位于同一个 CPU 的插槽。即极限分配(1.25 或更高版本)

4. 建议使用

KubeletConfiguration配置中,添加

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: static
cpuManagerPolicyOptions:
  full-pcpus-only: "true" #分配完整的物理核心
  distribute-cpus-across-numa: "true" #需要多个 NUMA 节点来满足分配的情况下,会在 NUMA 节点上平均分配 CPU.
cpuManagerReconcilePeriod: 5s # cpu上报周期
reservedSystemCPUs: "0-1" # 预留系统0-1

内存管理器

为需要保证 QoSPo 在多 NUMA 节点保障内存和大内存页分配。这个特性非常有用,尤其是当数据库类或者使用 DPDK 进行高性能数据包处理的应用要部署到 Kubernetes 中时,内存对其性能影响至关重要。

内存管理器(Memory Manager)为 Guaranteed QoS 类 的 Pods 提供可保证的内存(及大页面)分配能力。

核心

内存管理器 通过在 Pod 部署前,将为 Pod 应用 cgroups 设置(即 cpuset.mems), 保障的内存大页分配.

具体可查看:https://github.com/klueska/kubernetes/tree/master/pkg/kubelet/cm/memorymanager

kubelet 开启策略

1. 要求:

v1.22 开始,内存管理器通过特性门控 MemoryManager 默认启用。
v1.22 之前,kubelet 必须在启动时设置如下标志:

--feature-gates=MemoryManager=true

2. 配置管理

在内存管理中,对 NUMA 分组的管理。 每当 Pod 的内存请求超出单个 NUMA 节点容量时,内存管理器会尝试创建一个包含多个 NUMA 节点的分组,从而扩展内存容量。 此策略是默认的, 并无替代策略。

kubelet 标志 --memory-manager-policy 来选择一种策略:

  • none: 默认策略。可以理解为不开启memory manager。
  • static: 允许为节点上具有某些资源特征的 Pod 的 memory 亲和到单个numa上。

3. 内存预留管理

在优化 Pod 调度过程时,会考虑可分配的内存。 前面提到的标志包括 --kube-reserved--system-reserved--eviction-threshold。 这些标志值的综合计作预留内存的总量。

1.至少为一个 NUMA 节点设置 --reserved-memory。实际上,eviction-hard 阈值默认为 100Mi, 所以当使用 Static 策略时,--reserved-memory 是必须设置的.
2.sum(reserved-memory(i)) >= kube-reserved + system-reserved + eviction-threshold

4. 建议使用

KubeletConfiguration配置中,添加

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
memoryManagerPolicy: Static
memorySwap: {} # 关掉swap内存交换
reservedMemory:
  - limits:
      memory: 1100Mi # >= 500Mi+500Mi+100Mi
      cpu: 500m
    numaNode: 0 # numa 0必须存在
kubeReserved:
  memory: 500Mi
systemReserved:
  memory: 500Mi
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 0s #驱逐等待时间

Numa拓扑管理topologyManager

CPUMemory 等设备管理进行统筹资源分配决策。

核心

kubelet 管理

TopologyManager 提供了如下几种对齐策略:

  • none:此政策不会尝试进行任何资源调整。 它的行为就像 TopologyManager 根本不存在一样。 这是默认策略。
  • best-effort:使用此策略,TopologyManager 将尝试尽可能地对齐 NUMA 节点上的分配,但即使某些分配的资源未在同一 NUMA 节点上对齐,也会始终允许 pod 启动。
  • restricted:此策略与尽力而为策略相同,但如果分配的资源无法正确对齐,它将导致 pod 准入失败。 与 single-numa-node 策略不同,如果不可能在单个 NUMA 节点上满足分配请求,则某些分配可能来自多个 NUMA 节点。
  • single-numa-node:这个策略是最严格的,只有当所有请求的 CPU 和设备都可以从一个 NUMA 节点分配时,pod 准入才会通过。

建议使用

KubeletConfiguration配置中,添加

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
topologyManagerPolicy: single-numa-node # 策略是最严格,如果pod不能不在单个numa上分配
topologyManagerScope: container # container 维度进行numa亲和

验证

使用 numactl 管理工具查看下当前机器上的情况:

dongjiang@basa:~ $ numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 20 21 22 23 24 25 26 27 28 29
node 0 size: 65186 MB
node 0 free: 9769 MB
node 1 cpus: 10 11 12 13 14 15 16 17 18 19 30 31 32 33 34 35 36 37 38 39
node 1 size: 65536 MB
node 1 free: 15206 MB
node distances:
node   0   1 
  0:  10  21 
  1:  21  10

部署 nginx:

---
apiVersion: v1
kind: Pod
metadata:
  name: cpusets-test
spec:
  containers:
...
    - name: testcontainer1 # Guaranteed 并且 cpu是整数个
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cpu: 1
          memory: 100Mi
        requests:
          cpu: 1
          memory: 100Mi
    - name: testcontainer2 # Guaranteed
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cpu: 200m
          memory: 100Mi
        requests:
          cpu: 200m
          memory: 100Mi
    - name: testcontainer3 # Burstable
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cpu: 200m
          memory: 100Mi
        requests:
          cpu: 100m
          memory: 100Mi
    - name: testcontainer4 # Best-Effort
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cpu: 200m
          memory: 100Mi
        requests:
          cpu: 100m
          memory: 100Mi

使用 ``

dongjiang@basa:~ $ kubectl describe node  kcs-cpu-test-s-wht2b
Name:               kcs-cpu-test-s-wht2b
...
Capacity:
  cpu:                4
  ephemeral-storage:  102350Mi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             15899180Ki
  pods:               128
Allocatable:
  cpu:                4
  ephemeral-storage:  96589578081
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             15796780Ki
  pods:               128
System Info:
  Machine ID:                 a679d9cff58d494e972f86fccd3e26a9
  System UUID:                A56C5525-47D0-4185-B3D9-2BA12FD70297
  Boot ID:                    c4aae965-044c-4b24-9340-838385a65a6e
  Kernel Version:             4.14.78-300.el7.bclinux.x86_64
  OS Image:                   BigCloud Enterprise Linux For LDK 7 (Core)
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.4.4
  Kubelet Version:            v1.21.5
  Kube-Proxy Version:         v1.21.5
PodCIDR:                      172.19.3.0/24
PodCIDRs:                     172.19.3.0/24
ProviderID:                   ecloud://a56c5525-47d0-4185-b3d9-2ba12fd70297
Non-terminated Pods:          (47 in total)
  Namespace                   Name                                                      CPU Requests  CPU Limits  Memory Requests    Memory Limits      Age
  ---------                   ----                                                      ------------  ----------  ---------------    -------------      ---
  default                     cpusets-test                                              1500m (4%)    1500m (4%)  400Mi (1%)         400Mi (1%)         1d
  ....
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests              Limits
  --------           --------              ------
  cpu                3091m (77%)           3722m (93%)
  memory             4607031306240m (28%)  3600398346240m (22%)
  ephemeral-storage  0 (0%)                0 (0%)
  hugepages-1Gi      0 (0%)                0 (0%)
  hugepages-2Mi      0 (0%)                0 (0%)
Events:              <none>

风险

  1. Numa最多支持8 node的管理
  2. single-numa-node 模式下,会出现 Pod 准入错误 TopologyAffinityError 并处于 Terminated 状态;

其他

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。