K8S部署容器时可以指定CPU和内存的资源限制,其真正实现也是通过CGroups做到的。我们来看个例子:
1 | apiVersion: v1 |
limits表示指定资源的上限,requests表示创建容器时初始的资源请求。cpu的单位m表示1/1000核,比如这里的500m,其实表示0.5核心。如果不带单位,比如1或者1.0,则表示分配1核cpu。内存的单位可以是Mi、Gi,分别表示MB和GB。这里的设置就表示初始时cpu 0.2核,内存200M;上限cpu 0.5核,内存400M。
首先来看cpu。
1 | $ kubectl get pod nginx -o=jsonpath='{.spec.containers[0].resources}' |
可以看到确实设置了初始和上限。
1 | $ docker ps|grep nginx|grep -v pause|cut -d' ' -f1 |
我们看到这里返回CpuShares是204,而不是200。这是因为K8S以1000为单位,而Docker以1024为单位。0.2*1024 =204.8。
1 | $ ps -ef|grep nginx |
最终我们在/sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod6500174f-9bd6-11e9-9708-08002716449c/7ac3aef786af10a26528a0f805933ebfc5749223a2ed44f3e7fe49f20aa9b971/cpu.shares
找到了这个初始值。
另外,HostConfig.CpuPeriod对应cpu.cfs_period_us,HostConfig.CpuQuota对应cpu.cfs_quota_us。
1 | $ cat /sys/fs/cgroup/cpu,cpuacct/kubepods/burstable/pod6500174f-9bd6-11e9-9708-08002716449c/7ac3aef786af10a26528a0f805933ebfc5749223a2ed44f3e7fe49f20aa9b971/cpu.cfs_period_us |
这两个需要这样来换算。首先将单个核心cpu的带宽定义为0.1秒,也就是100000微秒。我们前面指定了上限500m,那么就是0.5*100000 = 5000微秒。这里的cpu.cfs_period_us也就是100000微秒。
再来看内存的部分。
1 | $ docker inspect 7ac3aef786af --format '{{.HostConfig.Memory}}' |
也就是我们设置的内存上限。
1 | $ cat /proc/23814/cgroup |grep memory |
可以看到和CGroups中对应的memory.limit_in_bytes是相同的,也就是内存限制通过CGroups实现的方式。