在 Docker 容器内使用 cgroup v2

💡 原文中文,约1200字,阅读约需3分钟。
📝

内容提要

在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 杀手的影响隔离到仅模糊测试器,从而保护自动恢复守护进程,维持实验的弹性和效率。

🏷️

标签

➡️

继续阅读