发生了什么?
我的节点有250Gi内存和64核CPU,有两个NUMA节点,每个节点都是125Gi和32核CPU,拓扑策略是单NUMA节点。
创建了两个pod,其中一个pod的init-container有1核CPU和1Gi内存,app container有26核和32Gi内存。
第一个pod创建成功。
第二个pod会因为TopologyAffinityError失败。lscpu
的结果:
NUMA node0 CPU(s): 0-15,32-47
NUMA node1 CPU(s): 16-31,48-63
在/var/lib/kubelet/cpu_manager_state
文件中:
{
"policyName": "static",
"defaultCpuSet": "1,3,15-31,47-63",
"entries": {
"69aa6124-4e0e-4c66-94ea-feae7df25b68": { # the second Pod, init-container use NUMA 0
"init-container": "35"
},
"e49ac32c-22a3-4c8c-8be3-721bd1fd9eaa": { # the first Pod, use NUMA 0
"centos": "0,2,4-14,32,34,36-46",
"init-container": "33"
}
},
"checksum": 3748757820
}
预期会发生什么?
两个pod都能成功创建。
第一个pod使用NUMA 0;
第二个pod的init-container可以使用NUMA 0或NUMA 1,但app container使用NUMA 1;
我们如何尽可能精确地重现它?
- 创建一个pod,使用该节点上32(Numa Node)CPU中的10个CPU
- 创建另一个pod,需要init-container 1核CPU,app container需要大部分NUMA Node CPU,例如25核(大于左侧的第一个NUMA)
- 第二个pod会因为TopologyAffinityError失败。
我们需要了解其他任何信息吗?
我认为bug存在于generateCPUTopologyHints
函数中:
kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go
第623行 in 7ea3d02
| | for_, c:=rangereusableCPUs.List() { |
- 当分配init-container CPU时,CPUManager会将cpuToReuse记录为pod的cpuToReuse。
kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go
第345行 in 7ea3d02
| | p.updateCPUsToReuse(pod, container, cpuset) | - 在调用
generateCPUTopologyHints
之前,获取pod的cpuToReuse作为可重用的cpuToReuse。
kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go
第587行 in 7ea3d02
| | reusable:=p.cpusToReuse[string(pod.UID)] | - 当计算app container CPU时,CPUManager会过滤掉与reusableCPU的NUMA Node不相等的NUMA Node。
即使NUMA 1是唯一适合CPU资源获取的地方,它仍然会在计算TopologyHint时通过;NUMA 0与reusableCPU相匹配,但CPU剩余不足。
Kubernetes版本
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.17", GitCommit:"a7736eaf34d823d7652415337ac0ad06db9167fc", GitTreeState:"clean", BuildDate:"2022-12-08T11:47:36Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.17", GitCommit:"a7736eaf34d823d7652415337ac0ad06db9167fc", GitTreeState:"clean", BuildDate:"2022-12-08T11:42:04Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}
云提供商
OS版本
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here
# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
4条答案
按热度按时间368yc8dk1#
/sig node
3bygqnnd2#
/triage已接受
是的,这是一个导致TopologyAffinityError的bug,可以避免。
vktxenjb3#
/cc
w51jfk4q4#
/priority important-longterm