要实现容器间“极其严格”的资源隔离,必须启用PID、Network、MNT、UTS、IPC、User六类基础Namespace,禁用共享通道(如--host模式、--privileged),强化User Namespace用户映射,并可选启用Time、Cgroup Namespace及SELinux/AppArmor增强控制。

要实现容器间“极其严格”的资源隔离,仅靠默认的 Namespace 启用是不够的。Docker 等工具虽自动启用多数 Namespace,但它们默认不启用 User Namespace,且部分 Namespace(如 Time、Cgroup)需显式配置或较新内核支持。真正严格的隔离,核心在于组合启用全部必要 Namespace + 关闭共享通道 + 强化用户映射。
必须启用全部六类基础 Namespace
Linux 提供 6 种关键隔离维度,缺一不可:
-
PID Namespace:确保容器内 PID=1 进程只看到自身进程树,宿主机和其他容器进程完全不可见;禁用
--pid=host类参数 -
Network Namespace:为每个容器分配独立协议栈(网卡、IP、路由、iptables、socket),禁用
--network=host或--network=container:共享模式 -
MNT Namespace:隔离挂载点,配合 overlay2 等联合文件系统构建专属根文件系统;避免使用
--privileged或mount --bind向外暴露宿主机路径 -
UTS Namespace:隔离主机名和域名,防止通过
uname -n泄露环境标识;禁用--uts=host -
IPC Namespace:隔离 System V 消息队列、信号量、共享内存,阻断跨容器 IPC 通信;禁用
--ipc=host或--ipc=container: -
User Namespace:这是最关键一环——将容器内 root(UID 0)映射为宿主机上的非特权 UID(如 100000),从根本上防止容器逃逸后获得宿主机 root 权限;需在 daemon.json 中配置
{"userns-remap": "default"}并重启 dockerd
主动禁用隐性共享通道
很多看似“隔离”的容器,其实仍通过以下方式泄露或共享资源:
- 禁用
/proc/sys和/sys/fs/cgroup的直接挂载:避免容器通过写 sysctl 或 cgroup 接口影响宿主机策略 - 不挂载
/dev全局设备节点:改用--device显式授权,或启用devices.cgroup.subtree控制设备访问粒度 - 关闭
ambient capabilities:启动时指定--cap-drop=ALL,再按需--cap-add,而非保留默认能力集 - 避免使用
--privileged—— 它会绕过几乎所有 Namespace 隔离限制
补充增强型 Namespace(高安全场景建议)
Linux 内核 5.6+ 支持更细粒度控制,可进一步收紧边界:
-
Time Namespace:隔离系统时钟(
CLOCK_MONOTONIC、CLOCK_BOOTTIME),防止容器通过时间戳推测宿主机负载或进行定时攻击;需手动启用unshare --time --user或 runc 配置 - Cgroup Namespace:使容器内
/proc/cgroups和/sys/fs/cgroup只显示本容器视图,避免窥探其他容器的资源限制配置;启用需内核支持并配置"cgroup-parent"或--cgroupns=private - 结合 SELinux/AppArmor:Namespace 提供“看不见”,而 MAC(强制访问控制)提供“即使看见也不许动”;例如为容器进程打上专用 SELinux type,限制其对文件、端口、dbus 的访问范围
验证是否真正隔离
启动容器后,应逐项检查:
- 执行
ls -l /proc/1/ns/,确认 6 类 Namespace inode 均为唯一值(不同容器不能相同) - 在容器内运行
cat /proc/1/status | grep Uid,确认 Real/Effective Uid 是非零映射值(如 100000) - 尝试
ip link、ps aux、mount、uname -n,结果应完全独立于宿主机及其他容器 - 从宿主机执行
nsenter -t $(pgrep -f "your-container-cmd") -U -r -n -p /bin/sh进入该容器的全部 Namespace,再反向验证视角一致性


















