前言
集群中一个计算节点可以运行很多个Pods,其中一些Pods可能会运行高CPU负载的业务。在这样的情况下,这些Pods很可能会在当前节点上竞争CPU资源,当一个Pod原先所在的CPU资源被占用时,工作负载将会自动切换到另外的空闲CPU上去。
Kubernetes平台针对独占隔离模式(Exclusive)推出了CPU Manager(v1.12 beta)进行Pod级别的绑核及隔离自动编排;Kubernetes平台针对CPU隔离、内存及设备局部性的优化诉求推出了Topology Manager(v1.16 alpha,Kubernetes v1.18 [beta])。
这样的调度策略对于那些上下文切换敏感的负载来说,会带来一些性能的损失。CPU Manager的设计目的就是为了针对这部分的工作负载进行CPU资源独占隔离,提供更好的性能,理论上来说具备以下几种特点的工作负载都可以使用:
-
对CPU节流影响敏感; -
对上下文切换敏感; -
对处理器Cache Miss敏感; -
最好能独享一个处理器的微架构资源(I-Cache & D-Cache); -
对跨Socket内存访问敏感; -
对同一个物理核的超线程敏感或有特定需求。
最佳绑核实践
1.确认Kubernetes版本和实际绑核需求
-
Kubernetes Version >= 1.18(此版本之后功能处于beta版本) -
另外绑核将会进行CPU独占,请事先确定是否一定需要进行独占。 -
查看机器NUMA情况,8个NUMA,每个NUMA8个CPU。
[root@lin ~]# lscpu | grep NUMA
NUMA node(s): 8
NUMA node0 CPU(s): 0-7
NUMA node1 CPU(s): 8-15
NUMA node2 CPU(s): 16-23
NUMA node3 CPU(s): 24-31
NUMA node4 CPU(s): 32-39
NUMA node5 CPU(s): 40-47
NUMA node6 CPU(s): 48-55
NUMA node7 CPU(s): 56-63
2.修改Kubelet配置文件(集群计算节点均需要修改配置)
-
systemctl status kubelet查看kubelet配置文件目录。不同安装方法此目录可能定义不同的名字。
[root@lin ~]# systemctl status kubelet
● kubelet.service - Kubernetes Kubelet
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; disabled; vendor preset: disabled)
-
编辑配置文件,vi /usr/lib/systemd/system/kubelet.service,在原来内容下添加ExecStartPre、ExecStartPre两行和ExecStart最后面添加–kube-reserved打头内容,且–kube-reserved内容前要加换行符””。 -
本文介绍single-numa-node和best-effort两种策略,不同策略,需要在kubelet配置不同参数,即–topology-manager-policy后面值对应不同的策略值。
[root@lin ~]# vi /usr/lib/systemd/system/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/hugetlb/system.slice/kubelet.service
# 如果是采取single-numa-node方式则在topology-manager-policy后填入single-numa-node,如果为best-effort策略改处填入best-effort字样。
[Service]
ExecStart=/opt/bin/kubelet
...
--kube-reserved=cpu=2,memory=250Mi --cpu-manager-policy=static --feature-gates=CPUManager=true --topology-manager-policy=single-numa-node
3.删除cpu管理状态
rm -f /var/lib/kubelet/cpu_manager_state
4.重启kubelet
systemctl daemon-reload && systemctl restart kubelet
5. 对yaml文件,显式标注资源诉求,并配置为Guaranteed Pod
具体yaml文件实践
1. yaml文件中独占CPU配置和共享CPU配置说明
-
策略为single-numa-node时,则yaml中的CPU个数一定不能超过最大每个numa的个数,本文环境最大为8,即不能超过8个。 -
策略为best-effort时,yaml中limit的cpu和request的cpu设置相同且cpu值为整数,则为独占CPU。 -
策略为best-effort时,yaml中只设置了limit,但没有设置request的cpu,且limit设置的cpu为整数,则为独占CPU。 -
策略为best-effort除了以上两种情况,都是为共享CPU池,不符合本文要求。
2.策略为single-numa-node的业务绑核效果。
-
kubelet配置文件中–topology-manager-policy设置为single-numa-node -
yaml文件resources设置
resources:
requests:
cpu: 8
limits:
cpu: 8运行该pod,且业务量增加效果时,通过htop的cpu绑核效果
3.策略为best-effort的业务绑核效果。
-
kubelet配置文件中–topology-manager-policy设置为best-effort -
yaml文件resources设置
resources:
requests:
cpu: 20
limits:
cpu: 20
-
运行该pod,且业务量增加效果时,通过docker inspect查看cpu绑核效果
[root@lin ~]# docker ps | grep test
1c9a2d4a80bd 2027cb8a07ab "sh -c '/usr/local/r…" 7 seconds ago Up 6 seconds k8s_test_ed5ba90c-28bc-4681-b0ce-0ec5d54ed3b5_0
[root@lin ~]# docker inspect 1c9a2d4a80bd | grep Cpuset
"CpusetCpus": "3-6,8-23",
"CpusetMems": "",
总结
特定的有时延敏感、CPU独占、高性能等需求的业务来说,可以通过绑定业务到指定的cpu运行。本文提供了topology-manager-policy策略为single-numa-node和best-effort两种实践方法,大概思路为,需要在k8s1.18以上环境、修改kubelet配置文件和yaml文件设置cpu的个数等三大过程。
参考文档
-
Kubernetes拓扑管理策略 -
Kubernetes CPU管理策略
原文始发于微信公众号(云原生内经):Kubernetes 平台如何使用CPU Manager + Topology Manager 达成最佳绑核实践
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/167941.html