k8s cpu独占优化

控制节点上的 CPU 管理策略

1.前言

在业务中使用Kubernetes编排容器时,通常会使用到Request & Limits参数对容器进行CPU与内存的使用限制.
但是对于某些比较消耗系统资源的业务,可能需要进行资源的独占分配(以保证其运行的性能).
所以使用单一的资源限制,还不能达到pod运行的性能,所以需要进行资源独占的分配编排.
在Kubernetes 版本> v1.12中,有CPU Manager技术去实现Pod级别的绑定运行CPU.

1.1 理解CPU Manager作用


每个worker节点运行多个pod,某些Pods可能会运行高CPU负载的业务,这些高负载的pod,很有可能在当前的节点上
抢占CPU的资源,影响当前节点上其他pod的运行性能.所以采用此技术来解决这个问题.


1.2 CPU 管理策略配置


CPU 管理策略通过 kubelet 参数 --cpu-manager-policy 来指定。Kubernetes 支持两种管理策略:
none: 默认策略,表示现有的调度行为。
static: 允许为节点上的某些消耗CPU资源的pod对cpu有独占性。

CPU管理器定期通过CRI写入资源更新,以保证内存中CPU分配与cgroupfs一致.
同步频率通过新增的 Kubelet 配置参数 --cpu-manager-reconcile-period 来设置.
如果不指定,默认与 --node-status-update-frequency 的周期相同。


1.3 none策略


none 策略显式地启用现有的默认CPU亲和方式,
不提供操作系统调度器默认行为之外的亲和性策略.
通过 CFS 配额来实现 Guaranteed pods 的 CPU 使用限制.

1.4 static 策略


static 策略针对具有整数型(容器对 CPU 资源的限制值是一个大于或等于1的整数值) CPU requests的 Guaranteed Pod,
它允许该类 Pod 中的容器访问节点上的独占CPU资源.
这种独占性是使用 cpuset cgroup 控制器来实现的.

#独占的CPU资源计算
可用的独占性 CPU 资源数量等于节点的 CPU 总量减去通过 --kube-reserved 或 --system-reserved 参数保留的 CPU 。

#注意事项
当启用static策略时,要求使用--kube-reserved
或 --system-reserved 或 --reserved-cpus 来保证预留的CPU值大于零.(避免cpu共享池为空)

1.5 具体配置


#增加参数配置
--cpu-manager-policy=static
--kube-reserved=cpu=0.5,memory=1G
--feature-gates=CPUManager=true

#配置项(注意修改主机名)
[root@node-1 bin]#cat >/etc/kubernetes/cfg/kubelet<<EOF
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=192.168.91.21 \
--kubeconfig=/etc/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/etc/kubernetes/cfg/bootstrap.kubeconfig \
--config=/etc/kubernetes/cfg/kubelet.config \
--cert-dir=/etc/kubernetes/ssl \
--kube-reserved=cpu=0.5,memory=1G \
--cpu-manager-policy="static" \
--feature-gates="CPUManager=true" \
--pod-infra-container-image=docker.io/kubernetes/pause:latest"
EOF


#说明
--kube-reserved:节点保留的cpu与内存


#重启服务
[root@node-1 ~]# systemctl daemon-reload && systemctl restart kubelet


1.6 测试


#注意测试之前需要将节点cpu调整到4 CORE
#查询当前机器的核心
[root@node-1 ~]# cat /proc/cpuinfo | grep process
processor : 0
processor : 1
processor : 2
processor : 3

#导入镜像
[root@node-1 ~]# docker load -i k8s.gcr.io.pause.3.1.tar.gz

#创建yaml
[root@master-1 nginx]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cpu-manager-demo
labels:
app: cpu-manager-demo
spec:
replicas: 2
selector:
matchLabels:
app: cpu-manager-demo
template:
metadata:
labels:
app: cpu-manager-demo
spec:
containers:
- name: cpu-manager-demo
image: nginx
resources:
requests:
cpu: 2
memory: "256M"
limits:
cpu: 2
memory: "256M"
ports:
- containerPort: 80

#创建deployment
[root@master-1 nginx]# kubectl apply -f nginx-deployment.yaml
deployment.apps/cpu-manager-demo created


#在节点获取容器
[root@node-1 ~]# docker ps | grep cpu-manager-demo
e5efcefacc84 nginx "/docker-entrypoint.…" 2 minutes ago
Up 2 minutes
k8s_cpu-manager-demo_cpu-manager-demo-67bbfc5d96-bvp5w_default_271fa62c-089f-4677-9c2b-778dfb898411_0

#获取容器pid
[root@node-1 ~]# docker inspect e5efcefacc84 | grep Pid
"Pid": 20114,
"PidMode": "",
"PidsLimit": null,

#查询 PID= 20114 的线程可用的CPU核心
[root@node-1 ~]# taskset -c -p 20114
pid 20114's current affinity list: 0,1


#如果没有设置CPU绑定,则是每个核心都可以运行
[root@node-3 ~]# taskset -c -p 5634
pid 5634's current affinity list: 0-3

 

posted @ 2024-11-03 19:52  滴滴滴  阅读(61)  评论(0编辑  收藏  举报