一、Intel CMK介绍
CMK(CPU-Manager-for-Kubernetes)是指面向 Kubernetes 的 CPU 管理器 (CMK) 为容器化工作负载提供 CPU 锁定 与隔离机制的解决方案。同时配合NFD(node-feature-discovery)可以在 Kubernetes 中发现英特尔® 至强® 处理器的服 务器硬件功能,如SST-BF(SpeedSelect Base Frequency)、SST-CP(SpeedSelect Core Power)功能 ,然后根据硬件功能对CPU进行隔离和绑定。
二、架构介绍
cmk会把cpu默认分成3个池exclusive、shared、infra,额外还会有exclusive-non-isolcpus
exclusive 池:从linux isolcpus集合分配,用于分配单容器独占的cpu池
shared 池:从linux isolcpus集合分配,用于分配多个容器共享使用的cpu池
infra 池:除了linux isolcpus隔离以外的cpu,用于分配多个容器共享使用的cpu池
exclusive-non-isolcpus 池:除了linux isolcpus隔离以外的cpu,但是用于分配单容器独占的cpu池
以上cpu 拓扑会记录到configmap里,每次都从configmap查询分配cpu
参考https://builders.intel.com/docs/networkbuilders/cpu-pin-and-isolation-in-kubernetes-app-note.pdf
三、CMK使用
1.首先在linux上隔离cpu
vi /etc/default/grub 比如在GRUB_CMDLINE_LINUX加上isolcpus=3,4,5,则隔离3,4,5号cpu。
然后grub2-mkconfig -o /boot/grub2/grub.cfg,再重启机器,重启后cat /proc/cmdline看到isolcpus=3,4,5则表示成功。
2. 执行cmk cluster-init容器初始化
git clone https: //github .com /intel/CPU-Manager-for-Kubernetes .git cd CPU-Manager- for -Kubernetes make kubectl apply -f resources /authorization/ 修改 resources /pods/cmk-cluster-init-pod .yaml的参数,按照需要划分exclusive、shared、infra池的cpu数量 比如 containers: - args: # Change this value to pass different options to cluster-init. - "/cmk/cmk.py cluster-init --all-hosts --saname=cmk-serviceaccount --namespace=cmk-namespace --num-exclusive-cores=2" kubectl apply -f resources /pods/cmk-cluster-init-pod .yaml |
cluster-init默认执行3个命令,init,discover,install
init命令会查询每个节点的cpu拓扑,然后保存到configmap,以后分配cpu就从这个configmap里面查询
init过程中,如果发现cpu有SST-BF(SpeedSelect Base Frequency)功能,就会固定分配到exclusive 池
如果发现cpu有SST-CP(SpeedSelect Core Power)功能就会根据特性performance、balance_performance、balance_power、power划分3个池
discover命令会根据configmap,给节点加上capacity资源数量,如cmk.intel.com/exclusive-cores可分配的独占cpu数量
install命令会在节点的/opt/bin/目录安装cmk命令
最后cluster-init会创建cmk-reconcile定时回收异常退出的pid,创建cmk-webhook用于创建pod时自动挂载/opt/bin/cmk命令
3.创建一个pod容器有3个container,分别从exclusive、shared、infra池分配cpu,脚本如下
apiVersion: v1 kind: Pod metadata: labels: app: cmk-isolate-pod name: cmk-isolate-pod namespace: cmk-namespace spec: serviceAccountName: cmk-serviceaccount tolerations: - operator: "Exists" restartPolicy: Never containers: - name: cmk-isolate-exclusive image: cmk:v1.5.2 command : - "/bin/bash" - "-c" args: - "/opt/bin/cmk isolate --pool=exclusive --namespace=cmk-namespace sleep -- inf" resources: requests: cmk.intel.com /exclusive-cores : '1' limits: cmk.intel.com /exclusive-cores : '1' env : - name: CMK_PROC_FS value: "/host/proc" - name: HOSTNAME value: "cmk-isolate-pod" volumeMounts: - mountPath: "/host/proc" name: cmk-host-proc readOnly: true - mountPath: "/opt/bin" name: cmk- install - dir - mountPath: "/etc/cmk" name: cmk-conf- dir securityContext: privileged: true # runAsNonRoot: true capabilities: drop: - all - name: cmk-isolate-shared image: cmk:v1.5.2 command : - "/bin/bash" - "-c" args: - "/opt/bin/cmk isolate --pool=shared --namespace=cmk-namespace sleep -- inf" env : - name: CMK_PROC_FS value: "/host/proc" - name: HOSTNAME value: "cmk-isolate-pod" volumeMounts: - mountPath: "/host/proc" name: cmk-host-proc readOnly: true - mountPath: "/opt/bin" name: cmk- install - dir - mountPath: "/etc/cmk" name: cmk-conf- dir securityContext: privileged: true # runAsNonRoot: true capabilities: drop: - all - name: cmk-isolate-infra image: cmk:v1.5.2 command : - "/bin/bash" - "-c" args: - "/opt/bin/cmk isolate --pool=infra --namespace=cmk-namespace sleep -- inf" env : - name: CMK_PROC_FS value: "/host/proc" - name: HOSTNAME value: "cmk-isolate-pod" volumeMounts: - mountPath: "/host/proc" name: cmk-host-proc readOnly: true - mountPath: "/opt/bin" name: cmk- install - dir - mountPath: "/etc/cmk" name: cmk-conf- dir securityContext: privileged: true # runAsNonRoot: true capabilities: drop: - all volumes: - hostPath: # Change this to modify the CMK installation dir in the host file system. path: "/opt/bin" name: cmk- install - dir - hostPath: path: "/proc" name: cmk-host-proc - hostPath: # Change this to modify the CMK config dir in the host file system. path: "/etc/cmk" name: cmk-conf- dir |
执行完查看configmap分配情况
pid 124015 独占了3号cpu,pid 124082 共享了5号cpu,pid 124093 共享了0,1,2号cpu
通过ps和taskset查看验证
四、CMK缺点
1.如果使用cmk的话,cpu的request和limit值就会变得无效,不利于统计资源,因为需要把cpu都挂到容器内不做cgroup隔离,
然后通过cmk isolate绑定用户进程的cpu亲和性,类似taskset绑定cpu
https://docs.starlingx.io/admintasks/installing-and-running-cpu-manager-for-kubernetes.html
2.类似kubevirt的virt-launcher都是自动创建的,要加入cmk isolate就需要修改对应源码
五、CMK和kubernetes的cpu manager cpu隔离对比
|
CMK
|
kubernetes cpu manager
|
---|---|---|
隔离配置 | linux isolcpus | 开启cpu-manager-policy=static特性 |
隔离范围 | 所有用户进程隔离 |
容器进程范围隔离,比如宿主机有其他进程,如ceph默认是没有cgroup隔离的,有可能占用容器隔离的cpu
|
cpu resource差别 | 不能设置request、limit | 需要设置request和limit一样的值,并且是整数,qos是Guaranteed类型 |
cpu和外部设备的numa对齐 | 不支持 | 支持 |
但如果规划好宿主机进程也可以保证隔离范围,达到CMK的效果,比如用systemctl给每个服务设置cpu亲和性
其他绑定cpu方案:
CRI-O v1.21.0有个新特性支持将容器运行在特定的cpu集合上
https://github.com/cri-o/cri-o/pull/4459 增加了infra_ctr_cpuset参数