docker无法实现绝对物理隔离,但可通过网络命名空间、自定义桥接网络、iptables策略、宿主机防火墙及dns剥离五层叠加,达成逻辑上不可穿透的强隔离效果。

所谓“绝对物理隔离”在 Docker 场景中并不存在——容器始终运行在共享的 Linux 内核上,无法像物理机或虚拟机那样实现硬件级隔离。但可以通过网络命名空间 + 自定义桥接网络 + iptables 策略 + 宿主机防火墙协同,达成接近“逻辑上不可穿透”的强隔离效果,满足金融、政务等对横向访问零容忍的业务线要求(如支付线与日志线、核心账务线与营销线)。
用独立网络命名空间切断默认通信路径
Docker 默认 bridge 网络(docker0)会让所有未指定网络的容器自动互通,这是最大风险源。必须禁用默认网络并为每条业务线创建专属网络:
- 创建无重叠子网的自定义桥接网络,例如:
docker network create --driver bridge --subnet 172.20.10.0/24 --gateway 172.20.10.1 finance-linedocker network create --driver bridge --subnet 172.20.20.0/24 --gateway 172.20.20.1 marketing-line - 启动容器时显式指定网络,禁止使用
--network bridge或省略网络参数;可配合--network none进一步收紧(仅需 loopback 的场景) - 验证隔离:进入 finance-line 中的容器执行
ping 172.20.20.5(marketing-line 某容器 IP),应完全超时;nslookup也无法解析对方服务名
启用 Libnetwork 的 DOCKER-ISOLATION 链阻断跨网桥流量
Docker 1.13+ 自带的 DOCKER-ISOLATION 链是关键防线,它在 FORWARD 链最前端拦截跨桥通信。确认规则已生效:
- 运行
iptables -L DOCKER-ISOLATION -n,应看到类似规则:-A DOCKER-ISOLATION -i br-abc123 -o br-def456 -j DROP-A DOCKER-ISOLATION -i br-def456 -o br-abc123 -j DROP - 若缺失,手动插入(Docker 重启后可能重置):
iptables -I DOCKER-ISOLATION -i br-$(docker network inspect finance-line -f '{{.Id}}' | cut -c1-12) -o br-$(docker network inspect marketing-line -f '{{.Id}}' | cut -c1-12) -j DROP - 该规则作用于网桥接口之间,不依赖容器 IP,即使容器配置了静态路由或 host-gw 模式也无法绕过
关闭容器间 DNS 自动发现与服务发现
默认情况下,同一网络内容器可通过服务名互访,而跨网络虽不能直连,但若 DNS 泛解析或外部 DNS 服务器返回错误记录,仍可能造成信息泄露或误配置:
- 启动容器时添加
--dns 127.0.0.1并禁用内置 DNS(需配合自建轻量 DNS 或 /etc/hosts 管理) - 在 docker-compose.yml 中明确关闭网络别名:
services:<br> payment:<br> networks:<br> finance-line:<br> aliases: []
- 避免使用
docker run --link(已弃用)或暴露/etc/hosts自动注入机制
宿主机层补充:限制 netfilter 与 sysctl 级行为
单靠 Docker 内部规则不够,需加固宿主机网络栈:
- 禁用 IP 转发(除非确需路由):
sysctl -w net.ipv4.ip_forward=0,并写入/etc/sysctl.conf - 关闭反向路径过滤(rp_filter)防止伪造源地址绕过:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter - 在宿主机 INPUT/FORWARD 链添加兜底规则:
iptables -A FORWARD -s 172.20.10.0/24 -d 172.20.20.0/24 -j REJECT --reject-with icmp-host-prohibited
不复杂但容易忽略:真正的隔离不是靠单一手段,而是命名空间分隔、网桥隔离、iptables 封堵、DNS 剥离、宿主机加固五层叠加。只要任意一层被绕过(比如误启 host 网络、漏配 --network、开放了 Docker daemon 的 tcp socket),整个隔离即失效。











