默认情况下,k8s不会对pod的资源使用进行限制,也就是说,pod可以无限使用主机的资源,例如CPU、内存等。为了保障k8s整体环境运行的稳定性,一般情况下,建议是对pod的资源使用进行限制,将其限制在一个范围内,防止起过度使用主机资源造成节点负载过大,导致其上面运行的其他应用受到影响。
前提
已有的k8s环境(这里安装的是k8s-v1.18.12版本)
k8s集群安装了metrics-server服务(这里借助rancher搭建k8s集群,默认安装了该服务)
何为CGroup参考Wiki,cgroups其名称源自控制组群(英语:control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)。
也就是说,通过设置CGroup,可以达到对资源的控制,例如限制内存、CPU的使用。在k8s中,对pod的资源限制就是通过CGroup这个技术来实现的。
内存限制 pod示例首先创建一个pod,并设置内存限制
resources: limits: memory: "200Mi" requests: memory: "100Mi"内存单位:E、P、T、G、M、K、Ei、Pi、Ti、Gi、Mi、Ki
其中M = 1000 x 1000,Mi = 1024 x 1024
limit必须要≥request
完整yaml参考
apiVersion: v1 kind: Pod metadata: name: stress-memory namespace: default spec: containers: - name: stress image: polinux/stress imagePullPolicy: IfNotPresent command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"] resources: limits: memory: "200Mi" requests: memory: "100Mi" nodeName: node01 ## 这里指定调度到某个节点上,方便接下来的操作这里设置了内存的limit为"200Mi",内存的request为"100Mi",并通过stress,指定分配150M的内存空间
接着我们运行该yaml
kubectl create -f stress-memory.yaml等到pod运行起来后,我们看一下pod的详细信息
kubectl get pod stress-memory -oyaml输出结果如下
... ... name: stress-memory namespace: default ... ... uid: b84cf8e8-03b3-4365-b5b5-5d9f99969705 ... ... resources: limits: memory: 200Mi requests: memory: 100Mi ... ... status: ... ... qosClass: Burstable ... ...从上述输出中可以获取如下两个信息:
pod的uid为b84cf8e8-03b3-4365-b5b5-5d9f99969705
pod的QoSClass为Burstable
这里Burstable对应的就是pod在CGroup中的路径,我们进入到CGroup的memory目录下,并进入到kubepods/Burstable目录中
cd /sys/fs/cgroup/memory/kubepods/burstable/ # ls ... podb84cf8e8-03b3-4365-b5b5-5d9f99969705 ...通过执行ls命令,能看到其中一个目录为podb84cf8e8-03b3-4365-b5b5-5d9f99969705,正好对应上面我们获得pod的uid,也就是说,对pod的资源限制,就是在这个CGroup目录下实现的
我们看一下这个目录下有什么文件
cd podb84cf8e8-03b3-4365-b5b5-5d9f99969705/ ls -1 8c9adca52f2bfd9e1862f6abaac5b435bdaf233925b7d640edb28e36da0b9b39 ca20137f7d5a42910e22425cca06443c16246c90ee9caa27814442e34a832b21 cgroup.clone_children cgroup.event_control cgroup.procs memory.failcnt memory.force_empty memory.kmem.failcnt memory.kmem.limit_in_bytes memory.kmem.max_usage_in_bytes memory.kmem.slabinfo memory.kmem.tcp.failcnt memory.kmem.tcp.limit_in_bytes memory.kmem.tcp.max_usage_in_bytes memory.kmem.tcp.usage_in_bytes memory.kmem.usage_in_bytes memory.limit_in_bytes memory.max_usage_in_bytes memory.memsw.failcnt memory.memsw.limit_in_bytes memory.memsw.max_usage_in_bytes memory.memsw.usage_in_bytes memory.move_charge_at_immigrate memory.numa_stat memory.oom_control memory.pressure_level memory.soft_limit_in_bytes memory.stat memory.swappiness memory.usage_in_bytes memory.use_hierarchy notify_on_release tasks相关文件作用如下:
文件 作用cgroup.event_control 用于event_fd()接口
cgroup.procs 展示process列表
memory.failcnt 内存使用达到限制的次数
memory.force_empty 强制触发当前CGroup中的内存回收
memory.limit_in_bytes 内存限制的最大值
memory.max_usage_in_bytes 记录该CGroup中历史最大内存使用量
memory.move_charge_at_immigrate 设置/显示当前CGroup的进程移动到另一个CGroup时,当前已占用的内存是否迁移到新的CGroup中,默认为0,即不移动
memory.numa_stat 显示numa相关的内存信息
memory.oom_control 设置/显示oom相关信息,其中oom_kill_disable为0,则超过内存会被kill;oom_kill_disable为1则停止进程,直至额外的内存被释放,当进程被暂停时,under_oom返回1
memory.pressure_level 设置内存压力的通知事件,配合cgroup.event_control一起使用
memory.soft_limit_in_bytes 设置/显示内存的软限制,默认不限制
memory.stat 显示当前CGroup中内存使用情况
memory.swappiness 设置/显示vmscan的swappiness参数(参考sysctl的vm.swappiness)
memory.usage_in_bytes 显示当前内存使用情况
memory.use_hierarchy 如果该值为0,将会统计到root cgroup里;如果值为1,则统计到它的父cgroup里面
notify_on_release 是否在cgroup中最后一个任务退出时通知运行release agent,默认情况下是0,表示不运行。(release_agent在CGroup最顶层的目录)
tasks 控制的进程组(这里看不到对应进程,需要进入到子group中查看)
不涉及内核内存(memory.kmem.*)和swap分区内存(memory.memsw.*),这里就不详细介绍
主要关注这几个文件