Docker(四)Cgroups
什么是 cgroups
容器技术本身花了很多精力在解决两方面的问题:隔离与限制。 实现隔离的方式就是 linux 的名称空间, 这一点我之前曾经讲过关于网络
docker 是如何隔离的,以及 docker 是如何利用 linux 的各种其他技术来解决被 。隔离的容器之间如何通信的问题
那么第二大主题就是限制, 限制一个容器中运行的进程能够使用的资源。 比如限制 CPU,内存,IO 等我们常见资源类型。
所以其实我们可以把一个容器就当成是一个进程组, 而 Cgroups 会去限制这个进程组所使用的资源上限。
Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括
CPU、内存、磁盘、网络带宽等等。而在 Linux 中,Cgroups
给用户暴露出来的操作接口是文件系统,即它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。 我们运行如下命令:
root@m7-prod-ssd001] ~ [ # mount -t cgroup
cgroup on /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent /usr/ltype ( =
ib/systemd/systemd-cgroups-agent,name systemd= )
cgroup on /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlbtype ( )
cgroup on /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memorytype ( )
cgroup on /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pidstype ( )
cgroup on /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_clstype ( )
cgroup on /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devicestype ( )
cgroup on /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkiotype ( )
cgroup on /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_eventtype ( )
cgroup on /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cputype ( )
cgroup on /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezertype ( )
cgroup on /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpusettype ( )
或者:
root@m7-prod-ssd001] ~ [ # ll /sys/fs/cgroup/
total 0
drwxr-xr-x 7 root root 0 Jan 7 13:49 blkio
lrwxrwxrwx 1 root root 11 Jan 7 13:49 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jan 7 13:49 cpuacct -> cpu,cpuacct
drwxr-xr-x 7 root root 0 Jan 7 13:49 cpu,cpuacct
drwxr-xr-x 6 root root 0 Jan 7 13:49 cpuset
drwxr-xr-x 7 root root 0 Jan 7 13:49 devices
drwxr-xr-x 5 root root 0 Jan 7 13:49 freezer
drwxr-xr-x 5 root root 0 Jan 7 13:49 hugetlb
drwxr-xr-x 7 root root 0 Jan 7 13:49 memory
lrwxrwxrwx 1 root root 16 Jan 7 13:49 net_cls -> net_cls,net_prio
drwxr-xr-x 5 root root 0 Jan 7 13:49 net_cls,net_prio
lrwxrwxrwx 1 root root 16 Jan 7 13:49 net_prio -> net_cls,net_prio
drwxr-xr-x 5 root root 0 Jan 7 13:49 perf_event
drwxr-xr-x 7 root root 0 Jan 7 13:49 pids
drwxr-xr-x 7 root root 0 Jan 7 13:49 systemd
我们看到,cgroups 以文件系统的方式提供给用户操作。
在这个目录下有很多的控制不同资源的目录。如果我们想要限制一个进程或者一组进程的 cpu 使用。 就可以在相应的目录下进行操作。
这里我借用张磊老师的一个例子来给大家演示一下。我们现在进入 /sys/fs/cgroup/cpu 目录下:
root@ubuntu:/sys/fs/cgroup/cpu container$ mkdir
root@ubuntu:/sys/fs/cgroup/cpu container/$ ls
cgroup.clone_children cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release
cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
这个目录就称为一个 “控制组”。你会发现,操作系统会在你新创建的 container
目录下,自动生成该子系统对应的资源限制文件。现在,我们在后台执行这样一条脚本:
: : &$ while ; do ; done
1] 226[
很显然这是一个死循环,并且它可以把 cpu 资源吃满。 如果我们使用 top 命令查看 cpu 的使用率,会发现它处于 100%
的状态。接下来我们向 container 组里的 cfs_quota 文件写入 20 ms(20000 us)。 $ echo 20000 >
/sys/fs/cgroup/cpu/container/cpu.cfs_quota_us。 接下来,我们把被限制的进程的 PID 写入 container 组里的 tasks
文件,上面的设置就会对该进程生效了:$ echo 226 > /sys/fs/cgroup/cpu/container/tasks
我们可以通过 top 命令看一下,cpu 的使用率降到了 20%。 所以我们可以通过向/sys/fs/cgroup/
这个目录下写入影响的信息而达到控制进程的目的, 所以我们在一个启动了 k8s 的节点上看看它的 cgoup 目录下的内容。 如下: