k8s配置CPU绑核后无法使用npu-smi info

问题描述

使用Atlas 800 3000服务器(Arm),操作系统centos 7.6,使用K8s (版本1.12)进行NPU相关业务调度。配置K8s的参数 --kube-reserved=cpu=2,memory=250Mi --cpu-manager-policy=static --feature-gates=CPUManager=true,开启K8s的绑核, 绑核后运行npu-smi info报错如下:

原因

默认情况下kubelet创建的Pod都是通过CFS配额的方式来分配使用物理机的cpu资源。cpu manager启动时,如果是none cpu manager policy,就直接返回了;如果是static cpu manager则会启动一个gorouting做reconcile。

在reconcileState方法中,cm会不停的通过GetCPUSetOrDefault方法获取容器的cpu set,更新容器的cpu set。GetCPUSetOrDefault方法根据containerID获取cpu set,如果Pod是一个guaranteed pod,返回的就是容器的cpu set;否则,则返回的就是default值。default值得含义是:“除了guaranteed pod分配走的cpu core外,其余的所有的cpu core都算在了default值里”,因此所有的容器在运行过程中都会定时、动态的更新cpu set值。

Ascend Docker Runtime将昇腾驱动库的so文件和NPU设备信息通过文件挂载的方式挂载到容器中,并添加cgroup访问权限。而挂载的过程中,没有将这部分信息同步给docker engine。runc在update过程中调用device Set方法,是根据容器的cgroup config中的内容重新调整device相关的文件,在这个过程中,就会丢失挂载时添加的cgroup访问权限。

解决方法

Ascend Device Plugin插件自身可以进行(/dev/davinciX /dev/davinci_manager /dev/devmm_svm)挂载,使用Ascend-device-plugin挂载覆盖Ascend Docker Runtime挂载,可以保证cgroup访问权限不丢失。修改Ascend Device Plugin驱动参数“-useAscendDocker=false”,然后重新安装Ascend Device Plugin。