在Docker容器内使用cgroup v2
内容提要
在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。