cgroup 和 namespace 共同组成了Linux容器技术的基础. 由namespace控制进程的可见空间, 由cgroup 决定进程分配的资源, 防止容器内的资源被宿主机上的其他进程所抢占
Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
可以使用命令 mount -t cgroup
查看系统挂载的 cgroups, 一般通过文件系统以文件和目录的方式组织在操作系统的 /sys/fs/cgroup
路径下, 在该路径下的诸如 cpuset
, cpu
, blkio
, memory
等目录, 称为子系统
, 而在子系统对应的资源种类下,你就可以看到该类资源具体可以被限制的方法。比如,对 CPU 子系统来说,可以执行指令 ls /sys/fs/cgroup/cpu
我们就可以看到如下几个配置文件
ls /sys/fs/cgroup/cpu
# cgroup.clone_children cgroup.sane_behavior cpuacct.usage cpu.cfs_period_us cpu.shares init.scope release_agent tasks
# cgroup.procs cpuacct.stat cpuacct.usage_percpu cpu.cfs_quota_us cpu.stat notify_on_release system.slice user.slice
在这里路径下, 我们可以关注几个文件 cpu.cfs_period_us
和 cpu.cfs_quota_us
,这两个参数需要组合使用,可以用来限制进程在长度为 cfs_period 的一段时间内,只能被分配到总量为 cfs_quota 的 CPU 时间。 被限制的进程PID 在子系统目录下的 task
文件中.
cfs_period
默认为 100000 (表 100000us, 即 100ms), cfs_quota
默认为 -1, 表示没有限制, 我们可以往 cpu.cfs_quota_us
文件中国写入 20000, 即 20ms, 它意味着在每 100 ms 的时间里,被该控制组限制的进程只能使用 20 ms 的 CPU 时间,也就是说这个进程只能使用到 20% 的 CPU . ( 当进程退出之后自动从tasks文件中删除)
<aside>
💡 手动在 /sys/fs/cgroup/cpu
下创建目录, 这样的目录称之为控制组
, 操作系统会自动生成该子系统对应的资源限制文件.
控制组的目录举例: /sys/fs/cgroup/cpu/container
</aside>
其他子系统如下:
Cgroups 对资源的限制能力也有很多不完善的地方,被提及最多的自然是 /proc 文件系统的问题。
众所周知,Linux 下的 /proc 目录存储的是记录当前内核运行状态的一系列特殊文件,用户可以通过访问这些文件,查看系统以及当前正在运行的进程的信息,比如 CPU 使用情况、内存占用率等,这些文件也是 top 指令查看系统信息的主要数据来源。
但是,你如果在容器里执行 top 指令,就会发现,它显示的信息居然是宿主机的 CPU 和内存数据,而不是当前容器的数据。
造成这个问题的原因就是,/proc 文件系统并不知道用户通过 Cgroups 给这个容器做了什么样的资源限制,即:/proc 文件系统不了解 Cgroups 限制的存在。