Docker rootless 已有 cgroup v2,Driver 仍是 none
系统已有 cgroup v2,rootless Docker Driver 仍为 none:核对 systemd 条件和实际后端。参数被接受、容器健康都不能证明资源上限已经实施。
系统已挂载 cgroup2,rootless Docker 和 Compose 容器也能运行,docker info 却显示 Cgroup Driver: none、Cgroup Version: 2,同时提示 rootless 模式需要 systemd 才能启用 cgroups。这个组合说明“系统有 cgroup v2”尚未满足 rootless Docker 实施资源限制的完整条件。
当前 Docker rootless 的 cgroup 资源限制要求 cgroup v2 与 systemd 同时具备。条件不满足时,--memory、--cpus、--pids-limit 这类 cgroup 参数会被忽略;容器能启动不能证明上限已实施。
先确认查的是同一个 rootless daemon
在创建容器的同一终端读取状态:
docker context show
docker version
docker info
核对实际 context、连接的 daemon、rootless 安全选项、Cgroup Driver、Cgroup Version 和警告。不同用户或终端可能连接不同的 Docker 后端,不能拿 rootful daemon 的结果解释另一个 rootless 容器。
docker stats 显示 0B / 0B 不证明进程没有使用内存;容器内 free 看到宿主机总内存,也不能单独证明上限失效。判断需回到实际 cgroup 支持和对应容器的限制。
OpenRC 上不能靠 unified 模式补齐 systemd
Alpine 常用 OpenRC。即使设置了统一 cgroup 模式,挂载输出已有 cgroup2,rootless daemon 仍可能没有满足 Docker 要求的 systemd 条件。把 cgroup v1 换成 v2 只补上其中一项。
普通 rootful Docker 支持哪些 cgroup 驱动,与 rootless 的资源限制前提是不同的问题。不能因为 rootful 文档提到 cgroupfs,就认定 rootless 也可以通过同一选项绕过 systemd。
如果该主机确实没有 systemd,不应照抄 user@.service.d 的 systemd 委托配置作为现场修复。需要容器级硬上限时,可评估迁到满足官方条件的运行环境,或按原安全设计采用合适的部署方式;这涉及主机服务和权限边界,需先准备迁移、数据备份和回退方案。
Driver 已是 systemd 时,再查控制器
在 cgroup v2 与 systemd 条件满足的环境,仍要核对用户服务实际得到哪些控制器。当前常见默认委托包含 memory、pids,其他控制器不一定已授权。因此 CPU 限制不能工作时,不能直接推断内存也缺少委托,更不能把增加 Delegate=memory 当作所有问题的统一处理。
检查用户服务的控制器及目标容器实际所在的 cgroup,确认所需控制器存在、限制文件中的值与预期一致。cgroup 路径取决于实际用户和服务布局,不要从另一台主机复制路径后就当作当前容器的限制。配置对象中的 Memory 数值也只表示声明,不能代替内核限制值。
ulimit、cpulimit 可以提供某些进程粒度的约束,但不等同于容器 cgroup 硬上限,不能借此承诺相同的隔离效果。
修复或迁移后,重新核对同一后端的 Driver、版本、控制器和目标容器的实际限制,并在隔离环境验证业务行为。无需在生产故意制造 OOM。只看到 healthy 或参数被接受,仍不足以证明资源限制已经生效;有问题时按保存的部署配置和备份回退。


