Closed Nimbus318 closed 3 weeks ago
在这个 PR #572 里,我添加了相关单测,用来覆盖「GPU container」夹在「非 GPU container」中间的情况,也可以用这个单测来复现这个 bug,但是需要注意的是,如果只运行这个单测,需要加上 device.InitDevices()
func Test_calcScore(t *testing.T) {
/*
Uncomment this line if you're running this single test.
If you're running `make test`, keep this commented out, as there's another test
(pkg/k8sutil/pod_test.go) that may cause a DATA RACE when calling device.InitDevices().
*/
// device.InitDevices()
...
}
问题描述
因为我实际的业务 pod 比较复杂,但是我可以简化为这个 pod 声明,同样可以复现这个 bug,我测试过多种情况,可以总结为:
以下是可以复现问题最简化的 Pod 声明:
只要满足我说的上述条件,Pod 就会进入 Pending 状态,Pod 的 Event Message 如下:
同时,在
hami-scheduler
的日志中出现了数组越界的错误:调用栈指向的代码行是: score.Devices[idx][ctrid] = append(score.Devices[idx][ctrid], util.ContainerDevice{}) 相关代码段如下:
问题分析
ctrid
超出了score.Devices[idx]
的长度,导致数组越界从目前的代码逻辑来看:
for idx := range score.Devices
循环遍历每个Devices
if len(score.Devices[idx]) <= ctrid
检查当前设备列表长度是否小于ctrid
,如果小于,则通过append
扩展score.Devices[idx]
的长度问题出在:
score.Devices[idx]
是一个二维数组,其中每一行的长度可能没有按照期望的ctrid
扩展ctrid
超出当前score.Devices[idx]
的长度时,即使通过append(score.Devices[idx], util.ContainerDevices{})
扩展Devices
,也只是在该idx
上添加了一个
空的ContainerDevices
,但是score.Devices[idx][ctrid]
的长度仍然不足解决方案
为了避免数组越界,需要确保
score.Devices[idx]
的长度足够容纳ctrid
在对score.Devices[idx][ctrid]
进行append
操作之前,需要确保score.Devices[idx]
的长度足够修改后的代码如下: