在Docker容器内使用cgroup v2

💡 原文英文,约400词,阅读约需2分钟。
📝

内容提要

在Docker容器内使用cgroup v2需以`--privileged --cgroupns=host`启动。作者用Docker跑模糊测试时,容器内存超限会触发OOM杀死整个容器,包括自动恢复守护进程。为让OOM只杀模糊器,需直接管理cgroup,但默认命名空间限制操作;加上`--cgroupns=host`后即可控制宿主机cgroup,保护守护进程。

🔎

延伸解读

为何默认配置下容器内无法管理cgroup

Docker默认使用独立的cgroup命名空间,容器内看到的cgroup视图与宿主机隔离,因此即使以--privileged启动并挂载/sys/fs/cgroup,尝试写入cgroup.procs时仍会报“no such file or directory”。这是因为命名空间限制了容器对宿主机cgroup的直接控制。只有通过--cgroupns=host让容器共享宿主机的cgroup命名空间,才能绕过这一限制,获得对宿主机cgroup的完全操作权限。

OOM killer作用范围与容器内存限制的关系

当容器内存超过--memory设定的上限时,Linux OOM killer会终止整个容器,包括其中的所有进程。在作者的场景中,这导致自动恢复守护进程也被杀死,模糊测试无法持续。通过直接管理cgroup,可以将OOM killer的作用范围限制在特定的模糊器进程上,从而保护守护进程。这要求容器能够操作宿主机的cgroup层级,而默认的命名空间隔离阻碍了这一点。

--pid=host的潜在用途与适用场景

文章提到,--pid=host选项可使容器的PID命名空间与宿主机一致,从而能够用真实PID直接检查其他cgroup.procs文件。这对于需要复杂系统交互的场景可能有用,例如跨容器进程监控或调试。但在作者当前的模糊测试设置中,该选项并非必需,因为核心需求只是控制cgroup以隔离OOM影响。读者应根据实际需求权衡是否启用。

❓

Q&A

如何在Docker容器内使用cgroup v2?

启动Docker容器时需添加`--privileged --cgroupns=host`参数,例如:`docker run -d --cpus=1.5 --privileged --cgroupns=host whexy/fuzztest:latest`。这样容器才能直接控制宿主机的cgroup设置。

为什么Docker容器默认无法管理cgroup?

因为Docker容器使用了cgroup命名空间,默认情况下会限制容器对宿主机cgroup设置的控制。即使挂载了`/sys/fs/cgroup`,尝试修改`cgroup.procs`时也会遇到`no such file or directory`错误。

在Docker中运行模糊测试时,OOM killer会杀死整个容器,如何避免?

通过以`--privileged --cgroupns=host`启动容器,并直接管理cgroup,可以将OOM killer的影响限制在模糊器进程,从而保护自动恢复守护进程不被杀死。

`--cgroupns=host`参数有什么作用?

`--cgroupns=host`参数使容器与宿主机共享cgroup命名空间,从而允许容器直接控制宿主机的cgroup设置,这是管理cgroup v2的关键。

`--pid=host`参数在cgroup管理中有什么用途?

`--pid=host`使容器的PID命名空间与宿主机一致,便于使用实际PID直接检查其他`cgroup.procs`文件,适用于更复杂的系统交互,但并非必需。

在Docker容器内管理cgroup v2需要哪些权限?

需要`--privileged`权限来获得必要的特权,并配合`--cgroupns=host`来突破命名空间限制,从而直接操作宿主机的cgroup。

🏷️

标签

➡️

继续阅读