我们之前提到Docker容器是利用操作系统的Namespace和Cgroup机制来实现资源的隔离与限制,Namespace实现隔离已经在上一讲中说过了,本讲主要探讨使用Cgropu实现资源的限制。那么如何理解资源的隔离与限制呢?举个不一定严谨但通俗的例子,假如在公路上开车,资源隔离把公路划了多个子车道,你跑在其中一个子车道上,且你不知道有其它车道存在,你以为整条路都是你的,这时你就会“飘”,要超速,这时候就要限制你的资源,限制你的速度。那么在服务器资源上,就是对内存,CPU等资源进行限制了,防止一个进程占用所有资源。
那这里就可以引出今天要讲的重点: Cgroup, 它的全称是Control Group, 主要作用是限制进程可以使用的资源上限,如内存、CPU、磁盘、网络等。Cgroup对外暴露的操作接口是文件系统, 也就是使用Cgroup的方式是通过操作目录和文件,下面我们就手动模拟Docker的进程资源限制。
查看所有Cgroup信息:
1 | bash复制代码# mount -t cgroup |
由上面输出可以看到/sys/fs/cgroup目录下有很子目录,如cpuset、memory等,这些子目录被称为子系统,子系统下面还有相应的配置文件,Cgroup通过不同子系统来限制不同的资源,每种子系统限制资源的方式都是类似的,下面列出几种常用的子系统。
- cpu子系统:控制一个容器里的所有进程(进程组)的CPU最大使用量。
- memory子系统:控制一个进程组的内存最大使用量。
- pids子系统:限制一个控制组里最多可以运行多少个进程。
- cpuset子系统:限制一个控制组里的进程可以在哪几个物理CPU上运行。
- blkio子系统:限制磁盘等块设备使用的I/O。
拿cpu子系统来说,/sys/fs/cgroup/cpu下面又有多个配置文件:
1 | python复制代码# ls /sys/fs/cgroup/cpu |
稍后我们要用到的配置文件是cpu.cfs_period_us和cpu.cfs_quota_us,它们的默认如下:
1 | shell复制代码# cat cpu.cfs_period_us |
cpu.cfs_period_us 默认值是 100 ms(100000 us),cpu.cfs_quota_us的值为-1,代表不限制。
这两个配置文件是组合使用的,它们可以表示的意思是,进程在指定时间内(period)可以使用的cpu配额(quota),下面我们就用实例来把这两个配置用起来。
在/sys/fs/cgroup/cpu下新建一个目录my-test-container, 这个my-test-container就可以理解成一个控制组,当目录被创建后,里面会自动生成了其资源限制文件,如下所示:
1 | shell复制代码# cd /sys/fs/cgroup/cpu && mkdir my-test-container && ls my-test-container/ |
下面我们写个程序,跑个死循环把cpu占满,并找到它的进程号。
1 | python复制代码# cat run_to_die.py |
当运行此程序的时候,可以看到CPU被占满了,它的进程号是31909。
1 | bash复制代码# python run_to_die.py |
它把我们的CPU占满了,我们现在就利用Cgroup来限制它只能使用20%的CPU,向 container 组里的 cpu.cfs_quota_us 文件写入 20 ms(20000 us),含义是在每 100 ms 的时间里,被该控制组限制的进程只能使用 20 ms 的 CPU 时间。
1 | shell复制代码# echo 20000 > /sys/fs/cgroup/cpu/my-test-container/cpu.cfs_quota_us |
下面把run_to_die.py程序的进程号写入my-test-container下的task文件中。
1 | shell复制代码# echo 31909 > /sys/fs/cgroup/cpu/my-test-container/tasks |
用top指令查看我们的run_to_die.py程序只能用到20%的CPU了。
1 | less复制代码top: |
所以现在可以知道,Docker对于资源限制这里,要做的东西也非常简单,它只需要在指定的目录里建目录,再把相关的参数写到相应的文件里就可以了,下面我们实际启动一个docker容器,并指定相关参数,去相关目录下看看,是不是像我们期待一的一样。
用busybox启动一个镜像,依然限制它使用20%的CPU。
1 | shell复制代码# docker run -it --cpu-quota=20000 busybox /bin/sh |
查看/sys/fs/cgroup下相关文件内容,是不是我们输入的20000。
1 | shell复制代码# cat /sys/fs/cgroup/cpu/docker/5ee9d255d1191fac0cfdb6f052aeeea788df1f20de9244c3793d204ecfb0f6f2/cpu.cfs_quota_us |
一切都在意料之中。
本文转载自: 掘金