Kubernetes开启CPU管理策略:pod使用独占核心
背景
业务内部存在计算密集型pod和GPU相关的模型服务,在业务高峰期时服务的性能会产生下降趋势,猜测是服务之间存在CPU时间片竞争,尝试去开始Pod独占核心去解决这个问题。
基本环境介绍
| 组件名称 | 版本号 |
|---|---|
| Kubernetes | v1.32.2 |
| Containerd | v1.6.9 |
| 10.21.36.6 | kubectl控制机 |
| 10.21.34.238 | 问题节点 |
开启Kubernetes的CPU管理策略
参考文档:https://kubernetes.io/zh-cn/docs/concepts/policy/node-resource-managers/
说明:
当启用 static 策略时,要求使用 --kube-reserved 和/或 --system-reserved 或 --reserved-cpus 来保证预留的 CPU 值大于零。 这是因为零预留 CPU 值可能使得共享池变空。
- 对指定节点进行封锁和排空
[root@10.21.36.6 ~]# kubectl cordon np-5ev2omtb.156 #封锁节点
[root@10.21.36.6 ~]# kubectl drain np-5ev2omtb.156 #驱逐节点Pod
- 登录节点开启CPU管理策略
[root@10.21.34.238 ~]# systemctl stop kubelet
[root@10.21.34.238 ~]# rm /var/lib/kubelet/cpu_manager_state
[root@10.21.34.238 ~]# cat /etc/kubernetes/kubelet
....
CPU_MANAGER_POLICY="--cpu-manager-policy=static" #设置CPU管理策略为static
CPU_MANAGER_POLICY_OPTION="--cpu-manager-policy-options=full-pcpus-only=true" #设置Pod独占一个完整的物理核心
[root@10.21.34.238 ~]# cat /usr/lib/systemd/system/kubelet.service #加入到systemctl启动参数里面
[Unit]
Description=kubelet
[Service]
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=..... ${CPU_MANAGER_POLICY} ${CPU_MANAGER_POLICY_OPTION}
.....
[root@10.21.34.238 ~]# systemctl daemon-reload #重新reload配置
[root@10.21.34.238 ~]# systemctl start kubelet #启动kubelet
[root@10.21.34.238 ~]# cat /var/lib/kubelet/cpu_manager_state #检查是否生效
{"policyName":"static"...}
Pod调度测试(必须是Guaranteed级别)
- Pod关键配置如下
resources:
requests:
cpu: "4" #占用两个物理核心
memory: "2Gi"
limits:
cpu: "4"
memory: "2Gi"
- 查看独占是否生效

当业务配置为3的时候,事件出现了SMT相关错误,SMT Alignment Error: requested 1 cpus not multiple cpus per core = 2
SMT扩展知识(同步多线程)
- 查看问题节点的CPU信息
[root@10.21.34.238 ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 2
Core(s) per socket: 16
Socket(s): 1
NUMA node(s): 1
Vendor ID: AuthenticAMD
BIOS Vendor ID: Red Hat
CPU family: 25
Model: 17
Model name: AMD EPYC 9K84 96-Core Processor
BIOS Model name: 3.0
Stepping: 0
CPU MHz: 2600.030
BogoMIPS: 5200.06
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 32768K
NUMA node0 CPU(s): 0-31
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid amd_dcm tsc_known_freq pni pclmulqdq monitor ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw topoext perfctr_core invpcid_single ibpb vmmcall fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 avx512_bf16 clzero xsaveerptr wbnoinvd arat avx512vbmi umip avx512_vbmi2 vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid fsrm
根据上面的信息,机器存在16个物理核心和32个逻辑核心(默认云厂商的机器都以逻辑核心的数量为准),配置的CPU管理策略中Pod必须独占一个物理核心,所以Pod配置时需要以2的倍数关系来变更。
- 查看核心对应关系
[root@10.21.34.238 ~]# lscpu -e
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
0 0 0 0 0:0:0:0 yes
1 0 0 0 0:0:0:0 yes
2 0 0 1 1:1:1:0 yes
3 0 0 1 1:1:1:0 yes
4 0 0 2 2:2:2:0 yes
5 0 0 2 2:2:2:0 yes
6 0 0 3 3:3:3:0 yes
7 0 0 3 3:3:3:0 yes
8 0 0 4 4:4:4:0 yes
9 0 0 4 4:4:4:0 yes
10 0 0 5 5:5:5:0 yes
11 0 0 5 5:5:5:0 yes
12 0 0 6 6:6:6:0 yes
13 0 0 6 6:6:6:0 yes
14 0 0 7 7:7:7:0 yes
15 0 0 7 7:7:7:0 yes
16 0 0 8 8:8:8:1 yes
17 0 0 8 8:8:8:1 yes
18 0 0 9 9:9:9:1 yes
19 0 0 9 9:9:9:1 yes
20 0 0 10 10:10:10:1 yes
21 0 0 10 10:10:10:1 yes
22 0 0 11 11:11:11:1 yes
23 0 0 11 11:11:11:1 yes
24 0 0 12 12:12:12:1 yes
25 0 0 12 12:12:12:1 yes
26 0 0 13 13:13:13:1 yes
27 0 0 13 13:13:13:1 yes
28 0 0 14 14:14:14:1 yes
29 0 0 14 14:14:14:1 yes
30 0 0 15 15:15:15:1 yes
31 0 0 15 15:15:15:1 yes
可以确定,0,1逻辑核心对应 0号物理核心,比例是2:1。
NUMA扩展知识
UMA(Uniform Memory Access)统一内存访问
┌─────────────────────────────────────────┐
│ 共享内存控制器 │
├──────┬──────┬──────┬──────┬──────┬──────┤
│ CPU0 │ CPU1 │ CPU2 │ CPU3 │ CPU4 │ CPU5 │
└──────┴──────┴──────┴──────┴──────┴──────┘
│ │ │ │
└────────┴────────┴────────┘
所有 CPU 访问内存
速度相同
NUMA(Non-Uniform Memory Access)非统一内存访问
┌───────── NUMA 节点0 ─────────┐ ┌───────── NUMA 节点1 ─────────┐
│ ┌──────┐ ┌──────┐ │ │ ┌──────┐ ┌──────┐ │
│ │ CPU0 │ │ CPU1 │ │ │ │ CPU2 │ │ CPU3 │ │
│ └──┬───┘ └──┬───┘ │ │ └──┬───┘ └──┬───┘ │
│ │ │ │ │ │ │ │
│ ┌──┴─────────────┴──┐ │ │ ┌──┴─────────────┴──┐ │
│ │ 本地内存 │ │ │ │ 本地内存 │ │
│ │ (快速访问) │ │ │ │ (快速访问) │ │
│ └───────────────────┘ │ └──┼───────────────────┘ │
└──────────────┬──────────────┘ └──────────────┬──────────────┘
│ │
└─────────── 互联总线 ───────────────┘
(较慢的远程内存访问)
NUMA 是一种多处理器系统的内存设计架构:
- 每个 CPU 有自己"本地"的快速内存
- 访问其他 CPU 的内存较慢(需要经过互联)
- 访问速度"不均匀"(非统一)
总结: 一台服务器可能有多个NUMA node,每个NUMA node绑定了机器一部分的核心和内存,当不同的NUMA node远程访问的时候,访问速度会降低。
常用的numa命令
[root@10.21.34.238 ~]# numastat
node0
numa_hit 1195541677
numa_miss 0
numa_foreign 0
interleave_hit 24491
local_node 1195541677
other_node 0
[root@10.21.34.238 ~]# numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 0 size: 94532 MB
node 0 free: 3162 MB
node distances:
node 0
0: 10
结语
Kubernetes 的 CPU 管理策略演进揭示了一个重要趋势:基础设施正变得越来越"智能"。它不再仅仅提供资源,而是理解资源的特性、关联和最佳使用方式。
从 SMT 感知到 NUMA 优化,从静态分配到拓扑感知调度,这些技术进步最终服务于同一个目标:让应用在云原生环境中获得可预测、高性能的运行体验。对于技术决策者和架构师而言,深入理解这些底层机制,不再是可选的高级技能,而是构建高性能云原生应用的必备素养。
更多推荐
所有评论(0)