需求:
超融合私有云节点,存储的虚拟机做了CPU绑定(0-7,24-31g共16核),为了保证存储虚拟机的性能,通过k8s开通的容器、虚拟机不能调度到该16个核心上。
实现方式:
经过预研发现,k8s提供了一个保留cpu的参数,如下
设置这个参数需要k8s 1.17以上,并且开启cpuManagerPolicy为static,如果设置reservedSystemCPUs将会覆盖KubeReserved和SystemReserved的cpu值。
但实践中发现这个cpu参数只对qos是Guaranteed,就是cpu独占型的虚拟机生效,如果qos是Burstable,就是cpu超售型的虚拟机就不会生效,用的还是默认的default cpus作为cgroup
而这个默认的default cpus是通过读取宿主机/proc/cpuinfo文件获取的,所以就算/etc/default/grub设置了isolcpus,k8s还是会读到隔离的cpu。
k8s有个cpu manager的checkpoint文件,用于记录当前cpu共享池用的哪几个cpu,独占的cpu分给了哪些容器,文件路径/var/lib/kubelet/cpu_manager_state。
当kubelet启动时,如果这个文件不存在就会读取/proc/cpuinfo文件,将信息写入到defaultCpuSet作为默认cpu共享池,
所以只要修改这部分代码将defaultCpuSet减去reservedSystemCPUs就可以达到完全隔离cpu的效果。
修改后需要打包kubelet,可以参考文档https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries
测试过程,设置reservedSystemCPUs,观察checkpoint文件的默认defaultCpuSet,起一台cpu超售型虚拟机,观察虚拟机容器里面cgroup的cpuset值
然后关闭虚拟机,关闭kubelet替换新的版本,删除checkpoint文件,启动kubelet,观察checkpoint文件defaultCpuSet的变化,
重启虚拟机,观察虚拟机容器里面cgroup的cpuset值的变化。截图如下
保留0-5的cpu:
替换kubelet前:
替换kubelet后: