前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >容器底层-Cgroups 的使用

容器底层-Cgroups 的使用

作者头像
syy
发布2020-12-17 14:24:33
9380
发布2020-12-17 14:24:33
举报
文章被收录于专栏:多选参数多选参数多选参数

Linux Cgroups(Linux Control Group)是 Linux 内核中用来为进程设置资源限制的一个功能。它最主要的作用就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等。此外,Cgroups 还能够对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

那么为什么除了 Namespace 之外还需要 Cgroups 呢?因为虽然容器里的 1 号进程只能看到容器里的情况,但是在宿主机上,它作为 100 号进程(比如宿主机上它的 PID 是 100)与其他所有进程之间依然是平等的竞争关系。也就是说,虽然 100 号进程表面上被隔离了起来,但是它能够使用的资源(比如 CPU、内存)是全部的,它可能把所有资源耗光。那么这样显然不是一个容器应该表现出来的合理行为。

在 Linux 中,Cgroups 给用户暴露出来的操作接口是文件系统,即操作接口是以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。我们可以通过 mount 命令来查看一下,可以发现输出结果是一系列文件系统目录。

我们查看 /sys/fs/cgroup 的时候还可以看到一系列子目录,这些子目录又被称为子系统。这些都是我这台机器上当前可以被 Cgroups 进行限制的资源种类。比如:

  • cpu 只要限制 CPU 的使用时间
  • cpuset 为进程分配单独的 CPU 核和对应的内存节点
  • memory 为进程设定内存使用的限制
  • blkio 块设备设定 IO 限制,一般用于磁盘等设备

而在子目录下面可以看到该子系统对应的资源可以被限制的方法,比如对于 CPU 子系统来说,我们可以看到如下几个配置文件。

其中 cpu.cfs_period_us 和 cpu.cfs_quota_us 这两个文件组合使用可以限制进程在长度为 cfs_period 的一段时间内,只能被分配到总量为 cfs_quota 的 CPU 时间。

Cgoups 配置示例

下面基于 Cgroups 提供的操作接口进行配置,我们先在相应的子系统中再创建一个目录,比如 container ,这个目录就被称为“控制组”。当将这个目录创建好了之后,你会发现这个目录已经生成了该子系统对应的资源限制文件。

接下去,我们通过修改 container 中的文件内容来设置限制。比如向 container 中的 cpu.cfs_quota_us 中写入 20 ms,也就是 20000,就表示每 cpu_period_us (100ms)被控制组限制的进程只能使用 20ms 的 CPU 时间。

接下去我们把要限制的进程 PID 写入 container 目录中的 tasks 文件中,那么该设置对要限制的进程就有效了。

Docker 实现

对于 Docker 等 Linux 容器项目来说,它们只需要在每个子系统下面,为每个容器创建一个控制组(也就是创建一个新目录),然后在启动容器进程之后,把这个进程的 PID 写入到这个控制组的 tasks 文件中即可。而控制组中的资源限制要填上什么值,就要看用户执行 docker run 时指定的参数内容。在 Docker 主机中,每个子系统下面都有 docker 控制组。

下面我们来演示 docker 进行设置的效果,就会在 CPU 子系统的 docker 控制组中进行相关的设置。

docker run -it --rm --cpu-period=100000 --cpu-quota=20000 -d alpine sleep 500s

如下所示,docker 还会在 docker 控制组创建一个新的目录,在这个目录中对资源进行设置,从而达到限制资源使用的效果。

总结

跟 Namespace 情况类似,Cgoups 对资源的限制能力也有很多不完善的地方,其中被提及最多的是 /proc 文件系统的问题。/proc 目录存储着当前内核运行状态的一系列特殊文件,用户可以通过访问这些文件,查看系统以及当前正在运行的进程的信息,比如 CPU 使用情况、内存占用率等,这些文件也是 top 指令查看系统信息的主要数据来源。

但是,如果你在容器里执行 top 指令,就会发现,它显示的信息居然还是宿主机的 CPU 和内存数据。这是因为 /proc 文件系统并不知道用户通过 Cgroups 给这个容器做了什么样的资源限制,所以它返回的还是整个宿主机的。那么这个问题会导致,容器内的应用程序读取到的 CPU 核数、可用内存等信息还是宿主机的,而不是做了限制之后的。这就是容器相比较于虚拟机另一个不尽如人意的地方。

当然,为了解决上面的那个问题。直观的做法就是容器不挂载宿主机的该目录就可以了,那么实际上可以通过 lxcfs 来实现隔离,lxcfs 在宿主机上维护进程组的信息,然后容器启动的时候将 lxcfs 维护的进程组信息所在的目录挂载到容器的 /proc 目录,当容器中获取 /proc 信息时,实际上获取宿主机上对该容器的进程组信息。

★20201008理解:/proc 存的是当前宿主机内核运行状态的情况,比如 CPU 使用情况、内存占用率等。容器在它看来其实就是一个做了限制的进程而已,它做计算还是针对整个内核的情况。但是,容器内的实际使用情况应该是根据容器中的相关限制来得出的,比如已经对容器做了 CPU 使用的限制,那么 top 命令得到的应该是在这个限制下,容器内进程的实际使用情况。 ”

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 多选参数 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Cgoups 配置示例
  • Docker 实现
  • 总结
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档