背景与价值
在AI模型开发、训练和推理业务场景下,CPU亲和性与NUMA亲和性调度至关重要。现代服务器通常采用多Socket、多NUMA节点的架构,GPU等加速设备通过PCIe连接到特定的NUMA节点。如果CPU、内存和GPU分配在不同的NUMA节点上,数据访问将产生跨NUMA的内存延迟,显著降低训练和推理性能。通过合理配置CPU亲和性和NUMA亲和性,可以确保计算资源(CPU)、内存和加速设备(GPU)在同一NUMA节点内协同工作,最大化数据局部性,减少跨节点通信开销,从而提升AI工作负载的整体性能。
以典型的8卡GPU服务器为例,其拓扑结构如下:
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 CPU Affinity NUMA Affinity
GPU0 X PIX NODE NODE SYS SYS SYS SYS 0-31,64-95 0
GPU1 PIX X NODE NODE SYS SYS SYS SYS 0-31,64-95 0
GPU2 NODE NODE X PIX SYS SYS SYS SYS 0-31,64-95 0
GPU3 NODE NODE PIX X SYS SYS SYS SYS 0-31,64-95 0
GPU4 SYS SYS SYS SYS X PIX NODE NODE 32-63,96-127 1
GPU5 SYS SYS SYS SYS PIX X NODE NODE 32-63,96-127 1
GPU6 SYS SYS SYS SYS NODE NODE X PIX 32-63,96-127 1
GPU7 SYS SYS SYS SYS NODE NODE PIX X 32-63,96-127 1
可以看到:
GPU 0-3连接到NUMA 0,对应CPU 0-31, 64-95GPU 4-7连接到NUMA 1,对应CPU 32-63, 96-127
通过Kubernetes的NUMA亲和性调度,可以确保使用GPU 0-3的Pod被分配到NUMA 0对应的CPU核心上。
Kubernetes NUMA 亲和性关键组件
Kubernetes通过kubelet中的多个Manager组件协同工作来实现NUMA亲和性调度:
┌─────────────────────────────────────────────────────────────┐
│ Topology Manager │
└─────────────────────────────────────────────────────────────┘
↑ ↑ ↑
│ │ │
┌────────┴────────┐ ┌───────┴────────┐ ┌───────┴────────┐
│ CPU Manager │ │ Memory Manager │ │ Device Manager │
└─────────────────┘ └────────────────┘ └────────────────┘
组件功能概述
| 组件 | 功能 | 说明 |
|---|---|---|
CPU Manager | CPU亲和性管理 | 为Guaranteed QoS Pod分配独占CPU核心,提供CPU级别的拓扑提示 |
Memory Manager | 内存NUMA亲和性 | 为Pod分配特定NUMA节点的内存,确保内存访问本地化 |
Device Manager | 设备亲和性 | 管理GPU等设备的分配,提供设备所在NUMA节点的拓扑提示 |
Topology Manager | 拓扑协调中心 | 收集各Manager的拓扑提示,根据策略决定资源分配和Pod准入 |
工作流程
Pod被调度到节点后,kubelet的Topology Manager开始协调资源分配- 各
Manager作为Hint Provider,向Topology Manager提供拓扑亲和性提示(Hints) Topology Manager根据配置的策略合并这些Hints,计算最优的NUMA节点分配- 根据策略决定
Pod的准入或拒绝 - 准入后,各
Manager根据拓扑提示分配对应NUMA节点上的资源
关键组件配置详解
以下是启用CPU亲和性和NUMA亲和性调度的完整kubelet配置示例,该配置通常位于宿主机上的/var/lib/kubelet/config.yaml。随后我们会详细介绍每个组件的配置项:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# ============= CPU Manager 配置 =============
cpuManagerPolicy: static # 启用静态CPU管理策略
cpuManagerReconcilePeriod: 10s # 调和周期
cpuManagerPolicyOptions:
full-pcpus-only: "true" # 仅分配完整物理核心
distribute-cpus-across-numa: "true" # 跨NUMA均匀分配(可选)
# ============= Topology Manager 配置 =============
topologyManagerPolicy: restricted # 严格要求NUMA对齐
topologyManagerScope: pod # Pod级别对齐
topologyManagerPolicyOptions:
prefer-closest-numa-nodes: "true" # 优先选择距离最近的NUMA节点
# ============= Memory Manager 配置 =============
memoryManagerPolicy: Static # 启用静态内存管理策略
reservedMemory:
- numaNode: 0
limits:
memory: 2Gi # NUMA 0 预留内存
- numaNode: 1
limits:
memory: 2Gi # NUMA 1 预留内存
# ============= 资源预留配置 =============
kubeReserved:
cpu: "2"
memory: 2Gi
systemReserved:
cpu: "2"
memory: 2Gi
reservedSystemCPUs: "0-3" # 预留CPU 0-3给系统
# ============= 驱逐配置 =============
evictionHard:
memory.available: "100Mi"
nodefs.available: "10%"
imagefs.available: "15%"
# ============= Feature Gates(可选)=============
featureGates:
CPUManagerPolicyOptions: true
CPUManagerPolicyBetaOptions: true
TopologyManagerPolicyOptions: true
CPU Manager
CPU Manager负责为Guaranteed QoS的Pod分配独占CPU核心,避免CPU资源竞争带来的性能抖动。
实现原理
- 共享池管理:
CPU Manager维护一个共享CPU池,初始包含节点所有CPU(除预留CPU外) - 独占分配:对于
Guaranteed QoS且CPU请求为整数的容器,从共享池中分配独占CPU - 亲和性设置:通过
Linux cgroups的cpuset将容器绑定到特定CPU核心 - 状态持久化:分配状态存储在
/var/lib/kubelet/cpu_manager_state文件中
前置配置要求
| 前置要求 | 说明 |
|---|---|
| 静态策略前提 | 使用static策略时,必须配置CPU预留(kubeReserved、systemReserved或reservedSystemCPUs中至少一个大于0) |
QoS要求 | 只有Guaranteed QoS的Pod才能获得独占CPU |
CPU请求要求 | CPU的requests和limits必须相等,且为整数值 |
配置示例
# ============= CPU Manager 配置 =============
cpuManagerPolicy: static # 启用静态CPU管理策略
cpuManagerReconcilePeriod: 10s # 调和周期
cpuManagerPolicyOptions:
full-pcpus-only: "true" # 仅分配完整物理核心
distribute-cpus-across-numa: "true" # 跨NUMA均匀分配(可选)
# ============= 资源预留配置 =============
kubeReserved:
cpu: "2"
memory: 2Gi
systemReserved:
cpu: "2"
memory: 2Gi
reservedSystemCPUs: "0-3" # 预留CPU 0-3给系统
配置参数
| 参数名称 | 可选值 | 默认值 | 是否必须 | 说明 |
|---|---|---|---|---|
cpuManagerPolicy | none, static | none | 否 | CPU管理策略。none不提供亲和性;static为Guaranteed Pod分配独占CPU |
cpuManagerReconcilePeriod | Duration | 10s | 否 | CPU Manager调和周期,定期检查并修正CPU分配 |
cpuManagerPolicyOptions | Map | nil | 否 | 策略选项,用于精细调整static策略行为 |
reservedSystemCPUs | CPU列表 | "" | static策略时必须 | 为系统进程预留的CPU列表,如0-3,8-11 |
cpuManagerPolicyOptions(策略选项)
| 选项名称 | 版本要求 | 说明 |
|---|---|---|
full-pcpus-only | v1.22+ (GA: v1.33+) | 仅分配完整物理核心:启用后,CPU Manager只会为容器分配完整的物理核心,而不会分配单个硬件线程(超线程)。这可以有效避免SMT(Simultaneous Multithreading,超线程)带来的"吵闹邻居"问题,即多个进程共享同一物理核心的执行单元导致的性能干扰。对于CPU密集型和延迟敏感的AI训练任务,建议启用此选项以获得更稳定的性能表现。例如,在开启超线程的64核服务器上(128个逻辑核心),启用此选项后容器最多只能获得64个完整物理核心 |
distribute-cpus-across-numa | v1.23+ | 跨NUMA均匀分配CPU:当容器请求多个CPU核心时,CPU Manager会尽可能将这些核心均匀分配到多个NUMA节点上,而不是集中在单个NUMA节点。这种策略适合能够感知NUMA拓扑并进行并行计算的应用程序,可以充分利用多NUMA节点的内存带宽。但需要注意,此选项可能会增加跨NUMA内存访问的开销,不适合需要严格NUMA局部性的场景。通常与Topology Manager的best-effort策略配合使用 |
align-by-socket | v1.25+ | 按Socket对齐:在多Socket服务器上,优先在物理Socket边界对齐CPU分配,而非逻辑NUMA边界。在某些服务器架构中,一个Socket可能包含多个NUMA节点,此选项会尝试将容器的所有CPU分配在同一个物理Socket上,以减少跨Socket通信延迟。这对于需要频繁CPU间通信的应用(如共享L3 Cache)有性能优势。注意:此选项为Alpha特性,默认隐藏,需要启用CPUManagerPolicyAlphaOptions Feature Gate |
distribute-cpus-across-cores | v1.31+ | 跨物理核心分配虚拟核心:将虚拟核心(有时称为硬件线程)分配到不同的物理核心上,而不是集中在少数物理核心的多个硬件线程上。这样可以减少同一物理核心内多个线程之间的资源竞争(如执行单元、缓存冲突),提升整体吞吐量。例如,请求4个CPU时,会分配4个不同物理核心的单个线程,而不是2个物理核心的4个线程。注意:此选项为Alpha特性,默认隐藏,需要启用CPUManagerPolicyAlphaOptions Feature Gate |
strict-cpu-reservation | v1.32+ (GA: v1.35+) | 严格CPU预留:启用后,会严格隔离通过reservedSystemCPUs预留的CPU核心,确保任何Pod(包括BestEffort、Burstable和Guaranteed QoS)都无法使用这些预留的CPU。未启用时,预留的CPU仅对Guaranteed QoS的独占分配有效,BestEffort和Burstable Pod仍可能调度到这些核心上。对于需要为系统关键进程(如kubelet、容器运行时、系统守护进程)保证稳定CPU资源的生产环境,强烈建议启用此选项,避免节点过载导致的稳定性问题 |
prefer-align-cpus-by-uncorecache | v1.32+ | 优先按Uncore Cache对齐:Uncore Cache通常指Last Level Cache(LLC,最后级缓存),它在多个CPU核心之间共享。启用此选项后,CPU Manager会尽最大努力将容器的所有CPU核心分配到共享同一LLC的核心组中。这可以显著提高缓存命中率,减少内存访问延迟,对于数据局部性要求高的应用(如AI推理服务、数据库)有明显性能提升。在现代服务器架构中,通常一个NUMA节点内的核心共享一个LLC,因此此选项与NUMA亲和性策略配合效果更佳 |
Topology Manager
Topology Manager是NUMA亲和性的核心协调器,负责收集各Manager的拓扑提示并做出准入决策。
实现原理
- Hint收集:从
CPU Manager、Memory Manager、Device Manager收集拓扑亲和性Hints - Hint合并:根据配置的策略合并所有
Hints,找出满足所有资源需求的最优NUMA节点组合 - 准入决策:根据策略决定是否允许
Pod在该节点运行 - 资源协调:通知各
Manager按照合并后的NUMA节点分配资源
配置示例
topologyManagerPolicy: restricted # 严格要求NUMA对齐
topologyManagerScope: pod # Pod级别对齐
topologyManagerPolicyOptions:
prefer-closest-numa-nodes: "true" # 优先选择距离最近的NUMA节点
配置参数
| 参数名称 | 可选值 | 默认值 | 是否必须 | 说明 |
|---|---|---|---|---|
topologyManagerPolicy | none, best-effort, restricted, single-numa-node | none | 是(启用NUMA亲和性时) | 拓扑管理策略,决定NUMA对齐的严格程度 |
topologyManagerScope | container, pod | container | 否 | 拓扑管理的作用范围 |
topologyManagerPolicyOptions | Map | nil | 否 | 策略选项,用于精细调整策略行为 |
topologyManagerPolicy 详解
| Policy | 说明 | 适用场景 |
|---|---|---|
none | 不执行任何拓扑对齐,不影响资源分配 | 默认行为,不需要NUMA亲和性 |
best-effort | 优先选择NUMA对齐,但不强制。即使没有最优NUMA对齐,Pod也会被准入 | 希望NUMA对齐但允许降级 |
restricted | 仅允许NUMA对齐的Pod准入。如果无法满足最优对齐,Pod被拒绝 | 推荐用于AI训练/推理场景 |
single-numa-node | 仅允许所有资源都在同一个NUMA节点的Pod准入 | 延迟极度敏感的工作负载 |
topologyManagerScope 详解
| Scope | 说明 | 特点 |
|---|---|---|
container | 在每个容器级别进行资源对齐 | 同一Pod的不同容器可能分配到不同NUMA节点 |
pod | 在Pod级别进行资源对齐 | 推荐:所有容器分配到相同的NUMA节点集合,适合需要进程间通信的应用 |
topologyManagerPolicyOptions(策略选项)
| 选项名称 | 说明 |
|---|---|
prefer-closest-numa-nodes | 优先选择距离最近的NUMA节点集合,减少跨NUMA通信延迟 |
max-allowable-numa-nodes | 允许超过8个NUMA节点的系统启用Topology Manager(默认限制8个) |
Memory Manager
Memory Manager负责为Pod分配特定NUMA节点的内存,确保内存访问本地化。
实现原理
- 内存计数:跟踪每个
NUMA节点的可用内存和已分配内存 - NUMA感知分配:根据
Topology Manager的决策,从指定NUMA节点分配内存 - Hint提供:向
Topology Manager提供内存的NUMA亲和性提示 - 状态持久化:分配状态存储在
/var/lib/kubelet/memory_manager_state文件中
配置示例
memoryManagerPolicy: Static # 启用静态内存管理策略
reservedMemory:
- numaNode: 0
limits:
memory: 2Gi # NUMA 0 预留内存
- numaNode: 1
limits:
memory: 2Gi # NUMA 1 预留内存
配置参数
| 参数名称 | 可选值 | 默认值 | 是否必须 | 说明 |
|---|---|---|---|---|
memoryManagerPolicy | None, Static | None | 否 | 内存管理策略。Static为Guaranteed Pod提供内存NUMA亲和性 |
reservedMemory | MemoryReservation列表 | nil | Static策略时必须 | 每个NUMA节点预留的内存量 |
Reserved Memory 配置
使用Static策略时,必须配置每个NUMA节点预留的内存,且需满足:
sum(reserved-memory) = kube-reserved + system-reserved + eviction-hard
其中:
- kube-reserved:为
Kubernetes系统组件(如kubelet、容器运行时)预留的资源 - system-reserved:为操作系统守护进程(如
sshd、systemd)预留的资源 - eviction-hard:硬驱逐阈值,当节点资源使用达到该阈值时,
kubelet会立即驱逐Pod以回收资源,避免节点资源耗尽。常见的驱逐信号包括:memory.available:可用内存低于阈值nodefs.available:节点文件系统可用空间低于阈值imagefs.available:镜像文件系统可用空间低于阈值pid.available:可用PID数量低于阈值
evictionHard配置示例:
# kubelet配置
evictionHard:
memory.available: "100Mi" # 可用内存低于100Mi时立即驱逐Pod
nodefs.available: "10%" # 节点文件系统可用空间低于10%时驱逐
imagefs.available: "15%" # 镜像文件系统可用空间低于15%时驱逐
nodefs.inodesFree: "5%" # 节点文件系统可用inode低于5%时驱逐
当kubelet配置不满足sum(reserved-memory) = kube-reserved + system-reserved + eviction-hard规则时,会报类似如下的错误:
Failed to initialize memory manager" err="the total amount "xxx" of type "memory" is not equal to the value "xxx" determined by Node Allocatable feature"
Device Manager
Device Manager本身由设备插件(Device Plugin)实现,如NVIDIA GPU的nvidia-device-plugin。它向Topology Manager提供GPU设备所在NUMA节点的信息。
工作机制
- NUMA拓扑检测:
Device Plugin启动时通过读取/sys/bus/pci/devices/<busid>/numa_node文件自动检测每个GPU的NUMA节点信息 - 设备注册:向
kubelet注册设备资源(如nvidia.com/gpu),并在设备的TopologyInfo字段中携带NUMA节点信息 - Hints提供:当
Pod请求GPU时,通过GetPreferredAllocation接口返回NUMA感知的设备分配建议 - 拓扑协调:
Topology Manager结合CPU、Memory和GPU的Hints,选择最优的NUMA节点组合
NUMA感知功能说明
重要特性:NVIDIA Device Plugin从v0.2.0版本开始原生支持NUMA感知功能,无需额外配置即可自动启用。该功能基于以下机制:
- 自动检测:通过
NVML库和sysfs自动获取GPU的NUMA节点信息 - 透明传递:通过
Kubernetes Device Plugin API的TopologyInfo结构体将NUMA信息传递给kubelet - 智能分配:实现了
GetPreferredAllocation接口,根据设备类型采用不同的分配策略:- 对齐分配:对于完整
GPU,优先选择同一NUMA节点的设备 - 分布式分配:对于
MIG、Time-slicing等共享模式,均匀分布设备
- 对齐分配:对于完整
配置方式
NVIDIA Device Plugin支持多种配置方式,可以通过ConfigMap、命令行参数或Helm Chart进行配置。
ConfigMap配置示例
apiVersion: v1
kind: ConfigMap
metadata:
name: nvidia-device-plugin-config
namespace: nvidia-device-plugin
data:
config.yaml: |
version: v1
flags:
migStrategy: "none" # MIG策略: none, single, mixed
failOnInitError: true # 初始化失败时是否终止
nvidiaDriverRoot: "/" # NVIDIA驱动根目录
plugin:
passDeviceSpecs: false # 是否传递设备规范(与CPU Manager兼容时设为true)
deviceListStrategy: "envvar" # 设备列表策略: envvar, volume-mounts
deviceIDStrategy: "uuid" # 设备ID策略: uuid, index
关键配置参数
| 参数名称 | 可选值 | 默认值 | 说明 |
|---|---|---|---|
migStrategy | none, single, mixed | none | MIG模式策略。none表示不使用MIG;single表示每个MIG设备作为独立资源;mixed表示同时暴露完整GPU和MIG设备 |
failOnInitError | true, false | true | 初始化失败时是否终止插件。建议生产环境设为true |
passDeviceSpecs | true, false | false | 是否传递设备规范给容器。当启用CPU Manager的static策略时,需要设为false以避免权限问题 |
deviceListStrategy | envvar, volume-mounts | envvar | 设备列表传递方式。envvar通过环境变量NVIDIA_VISIBLE_DEVICES传递;volume-mounts通过挂载/dev设备节点 |
deviceIDStrategy | uuid, index | uuid | 设备标识策略。uuid使用GPU UUID;index使用设备索引 |
关键组件配置更新
在执行测试之前,我们对kubelet的配置进行修改以启用NUMA亲和性特性:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# ============= CPU Manager 配置 =============
cpuManagerPolicy: static # 启用静态CPU管理策略
cpuManagerReconcilePeriod: 10s # 调和周期
cpuManagerPolicyOptions:
full-pcpus-only: "true" # 仅分配完整物理核心
# ============= Topology Manager 配置 =============
topologyManagerPolicy: restricted # 严格要求NUMA对齐
topologyManagerScope: pod # Pod级别对齐
topologyManagerPolicyOptions:
prefer-closest-numa-nodes: "true" # 优先选择距离最近的NUMA节点
# ============= Memory Manager 配置 =============
memoryManagerPolicy: Static # 启用静态内存管理策略
reservedMemory:
- numaNode: 0
limits:
memory: 2Gi # NUMA 0 预留内存
- numaNode: 1
limits:
memory: 2Gi # NUMA 1 预留内存
# ============= 资源预留配置 =============
# 注意需要保证公式:
# sum(reserved-memory) = kube-reserved + system-reserved + eviction-hard
kubeReserved:
cpu: "2"
memory: 1Gi
systemReserved:
cpu: "2"
memory: 1Gi
evictionHard:
memory.available: "2Gi" # 可用内存低于2Gi时立即驱逐Pod
nodefs.available: "10%" # 节点文件系统可用空间低于10%时驱逐
imagefs.available: "15%" # 镜像文件系统可用空间低于15%时驱逐
nodefs.inodesFree: "5%" # 节点文件系统可用inode低于5%时驱逐
# ============= Feature Gates(可选)=============
featureGates:
CPUManagerPolicyOptions: true
# 低版本K8S需要此项启用策略选项,如笔者当前的1.27.3版本
CPUManagerPolicyBetaOptions: true
TopologyManagerPolicyOptions: true
# 低版本K8S需要此项启用策略选项,如笔者当前的1.27.3版本
TopologyManagerPolicyAlphaOptions: true
# ... 其他配置项保持不变 ...
按照以下步骤更新kubelet配置并重启:
# 1. Drain节点(建议)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# 2. 停止kubelet
systemctl stop kubelet
# 3. 删除状态文件
rm /var/lib/kubelet/cpu_manager_state
rm /var/lib/kubelet/memory_manager_state
# 4. 修改kubelet配置
vim /var/lib/kubelet/config.yaml
# 5. 启动kubelet
systemctl start kubelet
# 6. Uncordon节点(若前面执行了drain)
kubectl uncordon <node-name>
需要注意切换策略需要清理状态文件,否则会报类似如下的错误:
start cpu manager error: could not restore state from checkpoint: configured policy "static" differs from state checkpoint policy "none", please drain this node and delete the CPU manager checkpoint file "/var/lib/kubelet/cpu_manager_state" before restarting Kubelet"
测试示例
验证NUMA亲和性
以下示例使用NVIDIA CUDA镜像,通过nvidia-smi topo -m命令验证GPU的NUMA亲和性配置:
apiVersion: v1
kind: Pod
metadata:
name: numa-affinity-test
spec:
restartPolicy: Never
containers:
- name: cuda-container
image: nvidia/cuda:12.2.0-base-ubuntu20.04
command:
- /bin/bash
- -c
- |
echo "========== GPU Topology Information =========="
nvidia-smi topo -m
echo ""
echo "========== CPU Affinity Information =========="
echo "Current CPU affinity: $(taskset -p $$)"
cat /proc/self/status | grep -E "Cpus_allowed|Mems_allowed"
echo ""
echo "========== NUMA Information =========="
numactl --hardware 2>/dev/null || echo "numactl not available"
echo ""
echo "========== Process CPU Binding =========="
cat /proc/self/cpuset
echo ""
echo "========== Sleeping for observation =========="
sleep 3600
resources:
# Guaranteed QoS: requests == limits
# CPU必须是整数才能获得独占CPU
requests:
cpu: "4"
memory: "8Gi"
nvidia.com/gpu: "1"
limits:
cpu: "4"
memory: "8Gi"
nvidia.com/gpu: "1"
多GPU NUMA亲和性测试
以下示例请求同一NUMA节点的多个GPU:
apiVersion: v1
kind: Pod
metadata:
name: multi-gpu-numa-test
namespace: default
spec:
restartPolicy: Never
containers:
- name: cuda-multi-gpu
image: nvidia/cuda:12.2.0-base-ubuntu20.04
command:
- /bin/bash
- -c
- |
echo "========== GPU Topology =========="
nvidia-smi topo -m
echo ""
echo "========== Allocated GPUs =========="
echo "NVIDIA_VISIBLE_DEVICES: $NVIDIA_VISIBLE_DEVICES"
echo ""
echo "========== GPU Details =========="
nvidia-smi --query-gpu=index,name,pci.bus_id,memory.total --format=csv
echo ""
echo "========== CPU Binding =========="
cat /proc/self/status | grep -E "Cpus_allowed_list|Mems_allowed_list"
echo ""
sleep 3600
resources:
requests:
cpu: "8"
memory: "16Gi"
nvidia.com/gpu: "2" # 请求2个GPU
limits:
cpu: "8"
memory: "16Gi"
nvidia.com/gpu: "2"
故障排查
TopologyAffinityError
当Pod无法满足Topology Manager的策略要求时,会出现此错误:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
numa-affinity-test 0/1 TopologyAffinityError 0 10s
排查步骤:
- 检查节点可用资源是否满足
NUMA对齐要求 - 降低策略严格程度(如从
single-numa-node改为restricted) - 减少
Pod的资源请求
切换CPU Manager Policy
切换策略需要清理状态文件:
# 1. Drain节点(建议)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# 2. 停止kubelet
systemctl stop kubelet
# 3. 删除状态文件
rm /var/lib/kubelet/cpu_manager_state
rm /var/lib/kubelet/memory_manager_state
# 4. 修改kubelet配置
vim /var/lib/kubelet/config.yaml
# 5. 启动kubelet
systemctl start kubelet
# 6. Uncordon节点
kubectl uncordon <node-name>
查看Kubelet日志
journalctl -u kubelet -f | grep -E "cpu_manager|topology_manager|memory_manager"
最佳实践
-
AI训练场景推荐配置:
topologyManagerPolicy: restrictedtopologyManagerScope: podcpuManagerPolicy: static
-
资源请求规范:
- 确保
Pod是Guaranteed QoS(requests == limits) CPU请求使用整数值以获得独占CPU
- 确保
-
多GPU场景:
- 使用
single-numa-node策略确保多GPU在同一NUMA节点 - 或使用
prefer-closest-numa-nodes选项减少跨NUMA延迟
- 使用
-
性能监控:
- 监控跨
NUMA内存访问(通过numastat命令) - 监控
CPU上下文切换和缓存命中率
- 监控跨