靠默认网络或简单桥接无法实现“极细粒度防墙访问”,关键在于用好 compose 的自定义网络 + 服务多网接入 + dns 隐式隔离三层机制:定义职责明确的独立网络(如 public_net、backend_net、internal_db、monitoring),严格控制服务网络归属与跨网能力(仅显式声明多网络才可通信),禁用默认网络并关闭自动 dns 泛解析,配合健康检查与启动顺序加固边界。

靠默认网络或简单桥接无法实现“极细粒度防墙访问”,关键在于用好 Compose 的 自定义网络 + 服务多网接入 + DNS 隐式隔离 三层机制。它不依赖 iptables 或外部防火墙,而是通过容器网络层天然阻断未声明的跨网通信,做到“不通即禁止”。
定义职责明确的独立网络
每个网络代表一个安全域,用途必须单一、边界清晰。不要复用网络承载不同语义的流量。
- public_net:仅暴露给宿主机或外网,只允许 api-gateway、nginx 等入口服务接入
- backend_net:服务间调用通道,user-service、order-service、payment-service 可互通
- internal_db:数据库专属网络,仅允许 backend_net 中被授权的服务(如 user-service)显式加入
- monitoring:Prometheus、Grafana 等运维组件专用,与业务网络物理隔离
严格控制服务的网络归属与跨网能力
一个服务默认只能访问自己所属网络内的其他服务。要让它访问另一网络的服务,必须在 networks 下**显式列出两个网络名**——这是唯一合法的“放行”方式。
- db 服务只写
- internal_db→ 它无法被 frontend 或 public_net 中任何容器 ping 通 - user-service 写
- backend_net和- internal_db→ 它能连 PostgreSQL,但不会出现在 public_net 的 DNS 列表里 - api-gateway 只写
- public_net和- backend_net→ 它可转发请求到后端,但绝不能碰数据库网络
禁用默认网络并关闭自动 DNS 泛解析
默认的 default 网络是隐患源头。务必在顶层声明 networks: 并显式定义所有网络,同时设置 driver: bridge 和 attachable: false(除非需要 docker run 临时接入)。
- 删掉所有服务的
network_mode: "bridge"或隐式依赖 default 网络的写法 - 不为 network 声明
ipam以外的额外配置(如enable_ipv6: true),避免干扰 DNS 解析逻辑 - 验证方法:进容器执行
cat /etc/resolv.conf,确认 nameserver 是 127.0.0.11(Docker 内置 DNS),且nslookup db在非 internal_db 网络中应返回 NXDOMAIN
配合健康检查与启动顺序加固边界
网络隔离只是第一道门,防止“误连成功但实际不可用”的假象。用 healthcheck 和 depends_on: condition: service_healthy 强制服务在目标网络就绪后再启动。
- db 加 healthcheck,确保端口监听且认证就绪
- user-service 的 depends_on 指向 db,且 condition 设为
service_healthy - 这样即使网络层面可达,也会等 db 真正可用才发起连接,避免因时序导致的越权探测尝试











