04|容器技术基本原理之Cgroups

我们之前提到Docker容器是利用操作系统的Namespace和Cgroups机制来实现资源的隔离与限制,Namespace实现隔离已经在上一讲中说过了,本讲主要探讨使用Cgropu实现资源的限制。那么如何理解资源的隔离与限制呢?举个不一定严谨但通俗的例子,假如在公路上开车,资源隔离把公路划了多个子车道,你跑在其中一个子车道上,且你不知道有其它车道存在,你以为整条路都是你的,这时你就会“飘”,要超速,这时候就要限制你的资源,限制你的速度。那么在服务器资源上,就是对内存,CPU等资源进行限制了,防止一个进程占用所有资源。

那这里就可以引出今天要讲的重点: Cgroups, 它的全称是Control Group, 主要作用是限制进程可以使用的资源上限,如内存、CPU、磁盘、网络等。Cgroups对外暴露的操作接口是文件系统, 也就是使用Cgroups的方式是通过操作目录和文件,下面我们就手动模拟Docker的进程资源限制。

查看所有Cgroups信息:

# 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/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
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/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)

由上面输出可以看到/sys/fs/cgroup目录下有很子目录,如cpuset、memory等,这些子目录被称为子系统,子系统下面还有相应的配置文件,Cgroup通过不同子系统来限制不同的资源,每种子系统限制资源的方式都是类似的,下面列出几种常用的子系统。

  • cpu子系统:控制一个容器里的所有进程(进程组)的CPU最大使用量。
  • memory子系统:控制一个进程组的内存最大使用量。
  • pids子系统:限制一个控制组里最多可以运行多少个进程。
  • cpuset子系统:限制一个控制组里的进程可以在哪几个物理CPU上运行。
  • blkio子系统:限制磁盘等块设备使用的I/O。

拿cpu子系统来说,/sys/fs/cgroup/cpu下面又有多个配置文件:

# ls /sys/fs/cgroup/cpu
assist                 cgroup.procs          cpuacct.usage         cpu.cfs_quota_us   cpu.shares  docker             system.slice
cgroup.clone_children  cgroup.sane_behavior  cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat    notify_on_release  tasks
cgroup.event_control   cpuacct.stat          cpu.cfs_period_us     cpu.rt_runtime_us  default     release_agent      user.slice

稍后我们要用到的配置文件是cpu.cfs_period_us和cpu.cfs_quota_us,它们的默认如下:

# cat cpu.cfs_period_us
100000
# cat cpu.cfs_quota_us
-1

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就可以理解成一个控制组,当目录被创建后,里面会自动生成了其资源限制文件,如下所示:

# cd /sys/fs/cgroup/cpu && mkdir my-test-container && ls my-test-container/

output:
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks

下面我们写个程序,跑个死循环把cpu占满,并找到它的进程号。

# cat run_to_die.py

#!/usr/bin/env python
while True:
    pass

当运行此程序的时候,可以看到CPU被占满了,它的进程号是31909。

# python run_to_die.py

top:
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

[root@iZ2zec5wzaupsrdu55oeaiZ ~]# ps -ef | grep python
root       910     1  0 7月14 ?       00:07:44 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
root     31909 31612 99 08:16 pts/3    00:01:01 python run_to_die.py
root     31963 31777  0 08:17 pts/4    00:00:00 grep --color=auto python

它把我们的CPU占满了,我们现在就利用Cgroups来限制它只能使用20%的CPU,向 container 组里的 cpu.cfs_quota_us 文件写入 20 ms(20000 us),含义是在每 100 ms 的时间里,被该控制组限制的进程只能使用 20 ms 的 CPU 时间。

# echo 20000 > /sys/fs/cgroup/cpu/my-test-container/cpu.cfs_quota_us

下面把run_to_die.py程序的进程号写入my-test-container下的task文件中。

# echo 31909 > /sys/fs/cgroup/cpu/my-test-container/tasks

用top指令查看我们的run_to_die.py程序只能用到20%的CPU了。

top:
%Cpu1  : 20.0 us,  0.0 sy,  0.0 ni, 80.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
复制代码

所以现在可以知道,Docker对于资源限制这里,要做的东西也非常简单,它只需要在指定的目录里建目录,再把相关的参数写到相应的文件里就可以了,下面我们实际启动一个docker容器,并指定相关参数,去相关目录下看看,是不是像我们期待一的一样。

用busybox启动一个镜像,依然限制它使用20%的CPU。

# docker run -it --cpu-quota=20000 busybox /bin/sh

查看/sys/fs/cgroup下相关文件内容,是不是我们输入的20000。

# cat /sys/fs/cgroup/cpu/docker/5ee9d255d1191fac0cfdb6f052aeeea788df1f20de9244c3793d204ecfb0f6f2/cpu.cfs_quota_us
20000

一切都在意料之中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值