This is the 9th day of my participation in Gwen Challenge
1 Kubernetes restrictions on resources
In Kubernetes, the limits on resources (CPU, memory, etc.) need to be defined in YAML, using Deployment as an example:
apiVersion: v1
kind: Pod
metadata:
name: cpu-overload
namespace: test
spec:
containers:
- name: cpu-overload
image: stress/stress:latest
resources:
limits:
cpu: "2"
memory: 1000Mi
requests:
cpu: "1"
memory: 500Mi
command: ["stress"]
args: ["-c"."2"]
Copy the code
The CPU has two limitations:
- Requests are the minimum request resources for a container. The requests are relative and cannot be strictly restricted.
- -Serena: It’s an absolute. You can’t go beyond it.
In this example, the CPU limit for the container CPU-overload is that two cores can be used at most when one core is applied for computing resources.
It is important to note that the so-called maximum of 2 cores is actually evenly distributed. If the container really triggers the computing bottleneck, the CPU usage in docker is 200%, but in the host machine, it is not full of 2 cores, but the pressure is spread across multiple CPU cores.
To calculate the resource limit of a POD, add up the resources of each pod container.
2 Passing of resource limits
Kubernetes can be thought of as a large tool wrapped in a series of components. In terms of resource limits, Kubernetes can’t do this by itself. Instead, it passes the resource limits, defined in YAML, to the Docker container. For example, the CPU limit of the container in Deployment is 2 cores at most, and Kubernetes will pass this limit to Docker. Therefore, in essence, the limit of Kubernetes resources comes from Docker, and to what extent can Docker limit resources? It also depends on cgroups of Linux, so Docker was not supported to run on Windows platform long ago. In the final analysis, it is because Cgroups is the product supported by Linux kernel.
Having said that, we can illustrate this transitivity with an example. Before we begin, here are the steps:
- Start a single POD in Kubernetes with a resource limit of up to 4 CPU cores.
- 2. Find the container for this POD and check the container configuration to see if it is limited to 4 cores.
- Find the Cgroups configuration for the container and see if it limits the container to 4 cores. 3, the experimental
2.1 Create a POD with a limit of 1 core
apiVersion: v1
kind: Pod
metadata:
labels:
system: centos7
name: centos7
namespace: test
spec:
containers:
- image: centos:7
imagePullPolicy: IfNotPresent
name: centos7
command: [ "/bin/bash"."-c"."--" ]
args: [ "while true; do sleep 30; done;" ]
ports:
- containerPort: 30008
hostPort: 30008
name: http
protocol: TCP
resources:
limits:
cpu: "1"
memory: 2000Mi
requests:
cpu: "0.1"
memory: 100Mi
hostNetwork: true
restartPolicy: Always
Copy the code
In this YAML, we limit centos containers to 1 core 2 gb memory. We’re through
kubectl apply -f centos.yaml
Copy the code
Run the POD.
2.2 View the runtime limits of the container
After running as a container, look at the node where the POD is located, go to the node, find the container, and view the runtime configuration of the container with the following instructions
[root@kubernetes-master ~]# kubectl get po -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos7 1/1 Running 0 2m10s 172.20. 511. kubernetes-node1 <none> <none>
docker inspect 7e5f03672fb6
Copy the code
Then, from the pile of output, find the following highlights:
"Isolation": ""."CpuShares": 102."Memory": 2097152000."NanoCpus": 0."CgroupParent": "kubepods-burstable-podb4283fa0_6576_4bd2_8c52_2183a5e2a566.slice"."BlkioWeight": 0."BlkioWeightDevice": null."BlkioDeviceReadBps": null."BlkioDeviceWriteBps": null."BlkioDeviceReadIOps": null."BlkioDeviceWriteIOps": null."CpuPeriod": 100000."CpuQuota": 100000."CpuRealtimePeriod": 0."CpuRealtimeRuntime": 0."CpusetCpus": ""."CpusetMems": ""."Devices": []."DeviceCgroupRules": null."DeviceRequests": null."KernelMemory": 0."KernelMemoryTCP": 0."MemoryReservation": 0."MemorySwap": 2097152000."MemorySwappiness": null."OomKillDisable": false."PidsLimit": null."Ulimits": null."CpuCount": 0."CpuPercent": 0.Copy the code
Among them:
- Memory: Indicates the limit of Memory resources, expressed in byte. 2097152000 = 2 GB
- CpuShares: Relative weight of CPU usage, one core is 1024, we set request CPU to 0.1, so it is 102
- CpuPeriod: a CPU is 100000, that is, 100 milicPu. This usually does not need to be changed.
- CpuQuota: The absolute limit of CPU resources, usually combined with CpuPeriod. CpuQuota/CpuPeriod is the number of cores that can be used. 100000/100000=1, indicating that one CPU core can be used at most.
- CpusetCpus: specifies the number of cpus to which the container is bound when it is running. Note that this value is not the number of cpus, but the number of cpus to which the container is bound, separated by commas.
From the docker runtime constraints above, this is exactly what Kubernetes defines as a Pod. Now look at the Cgroups restrictions, which are the core.
2.3 Check the restricted content of Cgroups by container
First, let’s look at the name of pod:
[root@kubernetes-master ~]# kubectl get po -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos7 1/1 Running 0 2m10s 172.20. 511. kubernetes-node1 <none> <none>
Copy the code
Then, on the host where the pod resides, find the container Id for this pod
docker ps | grep centos7
[root@kubernetes-node1 ~]# docker ps | grep centos7
7e5f03672fb6 7e6257c9f8d8 "/ bin/bash - c - 'wh..." 6 minutes ago Up 6 minutes k8s_centos7_centos7_test_b4283fa0-6576-4bd2-8c52-2183a5e2a566_0
67d02f7cf04d k8s.gcr.io/pause:3.2 "/pause" 6 minutes ago Up 6 minutes k8s_POD_centos7_test_b4283fa0-6576-4bd2-8c52-2183a5e2a566_0
Copy the code
Pause: Kubernetes: Kubernetes: Kubernetes: Kubernetes: Kubernetes: Kubernetes: Kubernetes: Kubernetes: Kubernetes We just need Centos7:7E5F03672FB6 to get the Cgroup information of this container
[root@kubernetes-node1 ~]# docker inspect 7e5f03672fb6 | grep Cgroup
"Cgroup": ""."CgroupParent": "kubepods-burstable-podb4283fa0_6576_4bd2_8c52_2183a5e2a566.slice"."DeviceCgroupRules": null.Copy the code
Ok, that’s it, let’s go straight to the Cgroup configuration directory:
cd /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podb4283fa0_6576_4bd2_8c52_2183a5e2a566.sl iceCopy the code
In this directory, there are many files:
[root@kubernetes-node1 kubepods-burstable-podb4283fa0_6576_4bd2_8c52_2183a5e2a566.slice]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 17 14:50 cgroup.clone_children
--w--w--w- 1 root root 0 Nov 17 14:50 cgroup.event_control
-rw-r--r-- 1 root root 0 Nov 17 14:50 cgroup.procs
-r--r--r-- 1 root root 0 Nov 17 14:50 cpuacct.stat
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpuacct.usage
-r--r--r-- 1 root root 0 Nov 17 14:50 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.shares
-r--r--r-- 1 root root 0 Nov 17 14:50 cpu.stat
drwxr-xr-x 2 root root 0 Nov 17 14:50 docker-67d02f7cf04d6eb6ed637e40e1ccebd18b09eb323ad262c1fe3e8aa75ea46edf.scope
drwxr-xr-x 2 root root 0 Nov 17 14:50 docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope
-rw-r--r-- 1 root root 0 Nov 17 14:50 notify_on_release
-rw-r--r-- 1 root root 0 Nov 17 14:50 tasks
Copy the code
Where, the current directory has a lot of Cgroup content, and there are two subdirectories:
docker-67d02f7cf04d6eb6ed637e40e1ccebd18b09eb323ad262c1fe3e8aa75ea46edf.scope
docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope
Copy the code
These two directories are actually the two containers in pod (pause, Centos7), and we are entering the centos7 directory
cd docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope
Copy the code
Check the contents in the directory
-rw-r--r-- 1 root root 0 Nov 17 14:50 cgroup.clone_children
--w--w--w- 1 root root 0 Nov 17 14:50 cgroup.event_control
-rw-r--r-- 1 root root 0 Nov 17 14:50 cgroup.procs
-r--r--r-- 1 root root 0 Nov 17 14:50 cpuacct.stat
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpuacct.usage
-r--r--r-- 1 root root 0 Nov 17 14:50 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Nov 17 14:50 cpu.shares
-r--r--r-- 1 root root 0 Nov 17 14:50 cpu.stat
-rw-r--r-- 1 root root 0 Nov 17 14:50 notify_on_release
-rw-r--r-- 1 root root 0 Nov 17 14:50 tasks
Copy the code
You can see several familiar words, such as cpu.cfs_quota_us, which limit CPU resources. Let’s take a look at the contents:
[root@kubernetes-node1 ...scope]# cat cpu.cfs_quota_us
100000
Copy the code
Yes, the value is 100000, which is 1 CPU.
2.4 How is the Linux Cgroup associated with the Dock?
In the above way, we have found out how the restrictions on CPU, memory and so on are traced to Cgroup step by step through the Deployment of Kubernets. So how does a Linux Cgroup relate to a container?
Let’s look at tasks in a cgroup directory
[root@kubernetes-node1 docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope]# cat tasks
22552
Copy the code
This value is the process ID, so Cgroup limits the resource by the process ID. Let’s look at the process ID
[root@kubernetes-node1 docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope]# ps -ef | grep 22552
root 22552 22534 0 14:50 ? 00:00:00 /bin/bash -c -- while true; do sleep 30; done;
root 30414 22552 0 15:08 ? 00:00:00 sleep 30
root 30443 23532 0 15:08 pts/0 00:00:00 grep --color=auto 22552
Copy the code
The process ID is the cAdvisor process ID, and the parent process must be a container process:
[root@kubernetes-node1 docker-7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2.scope]# ps -ef | grep 22534
root 22534 906 0 14:50 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/7e5f03672fb63500910b092ecfcc793a8f21450528bb32c9d078d31dc4846cb2 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root 22552 22534 0 14:50 ? 00:00:00 /bin/bash -c -- while true; do sleep 30; done;
root 30875 23532 0 15:09 pts/0 00:00:00 grep --color=auto 22534
Copy the code
3 summary
- Kubernete limit on resources, by Docker, Docker limit on resources, by Linux Cgroup.
- Linux Cgroup limits resources and processes. You only need to add the process ID to the Tasks file in the Cgroup configuration directory. The restriction takes effect immediately.
- Linux Cgroup can limit not only CPU, memory, but also disk IO, etc.