docker 利用 Linux 内核的 cgroup 功能,实现对容器的资源使用限制,通过将容器内的进程 PID号 加入同一个以容器ID为开头命名的cgroup控制组内,实现容器进程的资源限制

1. 验证当前主机已挂载cgroup

[root@lyx-rds-1126 ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)

2. 创建控制组 demo

cd /sys/fs/cgroup/cpu
mkdir demo
ls -l demo
#正常创建后demo控制组目录下会生成如cpu.cfs.quota_us 等文件

cgroup资源限制《深入docker底层原理》_bash

3. 生成一个CPU占用100%的进程

[root@lyx-rds-1126 demo]# while true;do : ; done &
[1] 23877

该进程会进入死循环,将当前系统cpu使用率堆到100%

4.检查当前cpu使用率,及该进程占用cpu情况

pidstat 工具可通过sysstat包安装,此处 -p 23877 表示查询PID为23877的进程, 3 表示每3秒显示一次

[root@lyx-rds-1126 demo]# pidstat -p 23877 3
Linux 3.10.0-957.el7.x86_64 (lyx-rds-1126.novalocal) 11/26/2021 _x86_64_ (1 CPU)

08:21:25 PM UID PID %usr %system %guest %CPU CPU Command
08:21:28 PM 0 23877 100.00 0.00 0.00 100.00 0 bash
08:21:31 PM 0 23877 100.00 0.00 0.00 100.00 0 bash

Average: 0 23877 100.00 0.00 0.00 100.00 - bash

5. 将该进程加入demo控制组,并限制cpu使用率为20%

cpu.cfs_period_us 值为 100000ns 表示 100ms 内该控制组下进程可以使用的CPU时间
cpu.cfs_quota_us 值为 -1 表示当前demo控制组下进程组在100ms内可以使用的cpu时间无限制

将 cpu.cfs_quota_us 修改为 20000,并将 23877 这个 PID加入到demo控制组

echo 20000 > cpu.cfs_quota_us
echo 23877 > tasks

cpu.cfs_quota_us 配置为 20000ns (20ms) 表示 100ms 内该控制组下进程可以使用20ms的cpu时间,相当于限制该进程组下的进程可以使用20%的CPU资源

[root@lyx-rds-1126 demo]# pidstat -p 23877 3
Linux 3.10.0-957.el7.x86_64 (lyx-rds-1126.novalocal) 11/26/2021 _x86_64_ (1 CPU)

08:23:06 PM UID PID %usr %system %guest %CPU CPU Command
08:23:09 PM 0 23877 20.27 0.00 0.00 20.27 0 bash
08:23:12 PM 0 23877 20.55 0.00 0.00 20.55 0 bash
08:23:15 PM 0 23877 20.48 0.00 0.00 20.48 0 bash
08:23:18 PM 0 23877 20.41 0.00 0.00 20.41 0 bash

Average: 0 23877 20.43 0.00 0.00 20.43 - bash

cgroup资源限制《深入docker底层原理》_Docker_02

6.Docker对容器的资源限制

Docker会在每个可使用cgroup限制的资源内创建一个docker目录(相当于创建一个Docker控制组),并在Docker控制组内为每个容器创建一个独立的控制组,容器启动后,将容器的进程ID 加入到tasks路径下,实现对容器的资源限制,如下截图展示了demo容器内内存限制为512M的情况

cgroup资源限制《深入docker底层原理》_docker_03