在 Docker 容器内使用 cgroup v2
内容提要
在Docker容器内管理cgroup v2需用`--privileged --cgroupns=host`启动,否则无法修改cgroup.procs。作者在AWS实例上用Docker做模糊测试,因内存超限导致OOM杀死整个容器及恢复守护进程。通过该配置获得主机cgroup控制权,将OOM影响隔离到模糊测试器,保护守护进程,维持实验弹性。
延伸解读
为何默认 Docker 限制下 OOM 会杀死整个容器
在默认的 Docker 配置中,容器内的进程共享一个 cgroup,内存限制作用于整个容器。当容器总内存超过限制时,Linux OOM 杀手会终止容器内的进程,可能导致整个容器退出。文章作者在 AWS 实例上运行模糊测试时,内存超限导致容器被杀死,连带自动恢复守护进程也终止,影响了实验的连续性。
关键配置:--privileged 与 --cgroupns=host 的作用
仅挂载 /sys/fs/cgroup 并赋予特权不足以修改 cgroup.procs,因为 Docker 默认使用私有 cgroup 命名空间,限制了对主机 cgroup 的控制。添加 --cgroupns=host 后,容器与主机共享 cgroup 命名空间,从而获得直接操作主机 cgroup 的权限。结合 --privileged,容器内可以创建新的 cgroup 并将进程加入其中,实现更细粒度的资源控制。
隔离 OOM 影响的实际效果与代价
通过上述配置,作者能够将模糊测试器放入独立的 cgroup,使 OOM 杀手仅终止测试器进程,而不影响守护进程。这提升了实验的弹性,但代价是容器获得了较高的主机权限,可能带来安全风险。此外,文章提到 --pid=host 可便于检查其他 cgroup.procs,但并非当前设置所必需,读者应根据实际需求权衡是否启用。
Q&A
在 Docker 容器内使用 cgroup v2 需要哪些启动参数?
需要使用 --privileged --cgroupns=host 启动 Docker 容器。
为什么在 Docker 容器内修改 cgroup.procs 会报错 'no such file or directory'?
因为 Docker 容器默认使用了一个限制对主机 cgroup 设置控制的命名空间,导致即使文件可见,修改也受到限制。
如何让 OOM 杀手只终止模糊测试器而不影响守护进程?
通过使用 --privileged --cgroupns=host 启动容器,获得对主机 cgroup 的控制权,从而将 OOM 影响隔离到模糊测试器,保护自动恢复守护进程。
--pid=host 选项在 cgroup 管理中有什么作用?
它将容器的 PID 命名空间与主机对齐,使用实际 PID 便于直接检查其他 cgroup.procs 文件,适用于更复杂的系统交互,但对当前设置不是必需的。
在 AWS 实例上使用 Docker 进行模糊测试时,遇到了什么内存问题?
当容器内存使用超过 3.5GB 时,Linux OOM 杀手会终止整个容器,包括重要的自动恢复守护进程。
使用 --privileged --cgroupns=host 启动容器后,能达到什么效果?
能够获得对容器内 cgroups 的所需控制,有效地将 OOM 杀手的影响隔离到仅模糊测试器,从而保护自动恢复守护进程,维持实验的弹性和效率。