Docker容器间进程与网络完全隔离的本质是组合启用PID和Network Namespace。默认每个容器拥有独立的pidns和netns,可通过docker inspect查主进程PID,再用ls -l /proc//ns/{pid,net}比对命名空间ID是否不同;也可进容器执行ip addr show和ps aux验证IP与进程互不可见;慎用--network=container或--pid=host等共享选项,否则会主动破坏隔离。

容器间进程与网络的完全隔离,本质是组合启用 PID 和 Network 两种 Namespace,并确保它们互不共享。Docker 默认就做了这件事,但理解底层逻辑才能真正掌控隔离效果。
确认每个容器拥有独立的 PID 和 Network Namespace
隔离是否生效,不能只看命令有没有执行,而要看内核实际分配的命名空间 ID 是否不同。
- 查容器主进程 PID:docker inspect -f '{{.State.Pid}}'
- 查其 PID Namespace:ls -l /proc/
/ns/pid ,输出类似 pid:[4026532518] - 查其 Network Namespace:ls -l /proc/
/ns/net ,输出类似 net:[4026532519] - 对比两个容器的 pid:[…] 和 net:[…] 数字:只要任一数字不同,就说明对应资源已隔离
避免意外共享——慎用 --network=container 和 --pid=host
手动指定共享选项会主动打破隔离,必须清楚后果再使用。
-
--network=container:
:两个容器共用同一 netns → IP、端口、路由、iptables 全部一致,无法实现网络隔离 - --pid=host 或 --network=host:直接复用宿主机命名空间 → 容器内能看到所有宿主机进程或网络设备,彻底丧失隔离性
- 默认不加任何网络或 PID 参数时,Docker 自动为每个容器创建全新 netns 和 pidns,这是最安全的起点
验证隔离效果的实用方法
光看数字不够直观,动手验证才能建立真实感知。
- 进容器 A 执行:ip addr show → 记下 eth0 的 IP(如 172.17.0.2)
- 进容器 B 执行:ip addr show → 得到另一个 IP(如 172.17.0.3),且看不到 A 的网卡
- 在容器 A 中运行:ps aux → 只看到自己启动的进程(如 nginx),看不到容器 B 的任何进程
- 尝试从容器 A ping 容器 B 的 IP → 默认 bridge 网络下能通,但这属于 Docker 网桥转发,不是命名空间失效;如需彻底不通,改用 --network=none 或自定义无互通的网络
手动模拟隔离(仅用于理解原理)
绕过 Docker 直接操作可加深理解,但生产环境请始终用标准 Docker 命令。
- 创建带 PID + Network 隔离的新 shell:unshare --pid --net --fork --mount-proc /bin/bash
- 此时 ps aux 只显示当前命名空间内进程,ip link 只看到 lo
- 手动配网需额外步骤:创建 veth pair、挂载一端到该 netns、配 IP、启路由 → 这正是 Docker 启动容器时自动完成的整套流程
- 关键点:--pid 和 --net 必须同时启用,缺一不可;单独用其中一个,另一类资源仍全局可见










