如果没有指定内存限制,则容器可以无限制的使用主机内存资源,当使用完主机的所有可用资源后,就会导致该节点调用OOMkilled,此时没有设置内存限制的pod对应的进程的score会更大,所以被kill的可能性更大。
为集群中的pod设置内存请求和限制,可以有效的利用集群上的内存资源,防止应用突发高峰期的时候内存猛涨影响其他应用的稳定运行
CPU限制 pod示例首先创建一个pod,并设置CPU限制
resources: limits: cpu: "1" requests: cpu: "0.5"CPU单位:小数值是可以使用。一个请求 0.5 CPU 的容器保证会获得请求 1 个 CPU 的容器的 CPU 的一半。 可以使用后缀 m 表示毫。例如 100m CPU、100 milliCPU 和 0.1 CPU 都相同。 精度不能超过 1m。
完整yaml参考
apiVersion: v1 kind: Pod metadata: name: stress-cpu spec: containers: - name: stress-cpu image: vish/stress resources: limits: cpu: "0.9" requests: cpu: "0.5" args: - -cpus - "2" nodeName: node01 ## 这里指定调度到某个节点上,方便接下来的操作这里设置了CPU的limit为"1",CPU的request为"0.5",并通过stress指定分配2个进程去跑满2个CPU
接着我们运行该yaml
kubectl create -f stress-cpu.yaml等到pod运行起来后,我们看一下pod的详细信息
kubectl get pod stress-cpu -oyaml输出结果如下
... ... name: stress-cpu namespace: default ... ... uid: 10929272-932f-4b4d-85c8-046a9f0e39d8 ... ... resources: limits: cpu: 900m requests: cpu: 500m ... ... status: ... ... qosClass: Burstable ... ...结合之前的内存相关的实验,从输出的结果中可以得知pod uid为10929272-932f-4b4d-85c8-046a9f0e39d8,对应的CGroup路径为kubepods/Burstable
在CGroup中可以看到cpu、cpuset、cpuacct三种跟CPU相关的CGroup,其中cpu用于对cpu使用率的划分;cpuset用于设置cpu的亲和性等,主要用于numa架构的os;cpuacct记录了cpu的部分信息。通过定义可以得知,k8s CPU限制在cpu这个目录中,我们进入到对应的pod的CGroup空间下,查看CGroup相关文件是如何工作的
# cd /sys/fs/cgroup/cpu/kubepods/burstable/pod10929272-932f-4b4d-85c8-046a9f0e39d8/ ls -1 cgroup.clone_children cgroup.procs cpuacct.stat cpuacct.usage cpuacct.usage_percpu cpu.cfs_period_us cpu.cfs_quota_us cpu.rt_period_us cpu.rt_runtime_us cpu.shares cpu.stat d5b407752d32b7cd8937eb6a221b6f013522d00bb237134017ae5d8324ce9e30 eba8c20349137130cdc0af0e9db2a086f6ea5d6f37ad118394b838adfc1325bd notify_on_release tasks相关文件作用如下:
文件 作用cgroup.clone_children 子cgroup是否会继承父cgroup的配置,默认是0
cgroup.procs 树中当前节点的cgroup中的进程组ID,现在我们在根节点,这个文件中是会有现在系统中所有进程组ID
cpu.cfs_period_us 统计CPU使用时间的周期,单位是微秒(us)。
例如如果设置该CGroup中的进程访问CPU的限制为每1秒访问单个CPU0.2秒,则需要设置cpu.cfs_period_us=200000,cpu.cfs_quota_us=1000000
cpu.cfs_quota_us 周期内允许占用的CPU时间,即CGroup中的进程能使用cpu的最大时间,该值是硬限(-1为不限制)
一旦cgroup中的任务用完了配额指定的所有时间,它们就会在该时间段指定的剩余时间中受到限制,并且直到下一个时间段才允许运行。cpu.cfs_quota_us参数的上限为1秒,下限为1000微秒
cpu.rt_period_us 仅适用于实时调度任务,CPU使用时间的周期,单位是微秒(us),默认是1s(1000000us)
cpu.rt_runtime_us 仅适用于实时调度任务,此参数指定cgroup中的任务可以访问CPU资源的最长连续时间
cpu.shares cpu.shares是软限制,理解为CPU的相对权重。
例如,A、B、C三个进程的权重为100、200、300,那么在CPU满载的情况下,A进程最多使用1/6 CPU时间片;而如果CPU不是满载的情况,则各个进程允许使用超出相对权重的大小的CPU时间
cpu.stat CPU时间统计信息,其中:
nr_periods—已经过去的周期间隔数(在cpu.cfs_period_us中指定)
nr_throttled — cgroup中的任务被限制的次数(即,由于它们已经用尽了配额所指定的所有可用时间,因此不允许运行)
throttled_time — cgroup中的任务已被限制的总持续时间(以纳秒为单位)
不涉及到cpuacct,这里就不详细介绍
在CPU的CGroup中,可以使用两个调度程序来调度对CPU资源的访问:
CFS:完全公平调度程序,比例共享调度程序,根据任务或分配给cgroup的优先级/权重,在任务组(cgroup)之间按比例划分CPU时间。
RT:实时调度程序,一种任务调度程序,它提供一种方法来指定实时任务可以使用的CPU时间。(不做讨论)
这里主要讨论k8s是如何设置CFS调度算法去限制进程对CPU使用,主要关注这几个文件