选对网络模式需按场景:bridge最安全,适合开发测试;host高性能但端口全局唯一;none用于离线批处理;container共享网络栈;自定义bridge支持DNS自动解析且更可靠。

怎么选对网络模式:看容器要不要和宿主机抢端口
绝大多数情况下,用默认 bridge 模式最安全——容器有独立 IP、端口不冲突、还能互相用名字通信。但如果你跑的是监控代理、日志收集器这类要监听宿主机所有接口的服务,或者对延迟极其敏感(比如高频金融行情转发),就得切到 host 模式。注意:host 模式下容器直接用宿主机的 127.0.0.1 和 iptables 规则,docker run -p 会失效,且宿主机上已被占用的端口(比如 3306、6379)容器也绝对不能碰。
-
bridge:适合开发、测试、多容器微服务,隔离性好,但跨容器通信需同网段或自定义网络 -
host:性能高、配置少,但端口全局唯一,不适合混部多个同类服务 -
none:纯离线场景,比如只做数据处理不联网的批任务,连ping都不通 -
container:另一个容器名:两个容器共享网络栈,常用于“主从绑定”(如 nginx + php-fpm 共享网络命名空间)
自定义 bridge 网络为什么比默认 docker0 更可靠
默认的 docker0 网桥是全局共享的,所有没指定 --network 的容器都往里塞,容易 IP 冲突、DNS 解析混乱、iptables 规则膨胀。而自定义 bridge 是显式创建、按需加入,支持子网、网关、MTU、IPAM 配置,更重要的是它默认启用容器间 DNS 自动解析——你 docker run --name db --network mynet postgres,另一个容器里直接 ping db 就通,不用记 IP。
- 创建带子网的网络:
docker network create --subnet=172.20.0.0/16 mynet - 启动时指定网络:
docker run --network mynet --name app nginx - 已有容器接入:
docker network connect mynet container_name - 别用
--ip硬编码,除非真需要固定地址;优先靠容器名通信
容器 ping 不通外网?先查三个地方
不是所有 bridge 网络天生能上网。常见断点在:宿主机 iptables FORWARD 链被 DROP、Docker daemon 的 iptables 选项被关、或宿主机启用了 rp_filter(反向路径过滤)。最快速验证法:docker run --rm --network host alpine ping -c2 8.8.8.8,如果通,说明问题出在容器网络层;如果不通,就是宿主机网络本身或防火墙策略问题。
- 检查 FORWARD 策略:
iptables -L FORWARD -n | grep DROP,若看到全 DROP,加一条:iptables -I FORWARD -i docker0 -o eth0 -j ACCEPT - 确认 Docker 是否接管 iptables:
grep 'iptables' /etc/docker/daemon.json,值应为true(默认) - 临时关闭 rp_filter:
echo 0 > /proc/sys/net/ipv4/conf/docker0/rp_filter - 别在容器里改
/etc/resolv.conf—— Docker 启动时会覆盖它
Macvlan 和 Overlay 不是“高级功能”,而是特定场景刚需
macvlan 是给容器发一张“物理网卡身份证”,让容器像虚拟机一样直连局域网,适用于必须暴露真实 MAC、要走交换机 ACL、或需要 DHCP 分配地址的场景。但它要求宿主机网卡支持混杂模式,且不能和宿主机在同一个子网(否则 ARP 冲突)。overlay 则只在 Swarm 集群里有意义,单机跑 docker network create -d overlay 会卡住——它依赖内置 KV 存储同步网络状态,没 Swarm manager 就起不来。
- macvlan 示例:
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 macnet - overlay 必须先
docker swarm init,再docker network create -d overlay mynet - 别试图在非 Swarm 场景硬上 overlay,你会卡在
network create命令不动 - macvlan 容器无法直接访问宿主机(除非额外配路由),这是设计使然,不是 bug
网络配置真正难的不是命令怎么写,而是得清楚每个模式背后对应的 Linux 原语:veth pair、netns、iptables、ebtables、MAC 地址学习。一旦容器通信异常,别急着重试,先 docker inspect 看 IP 和网关,再进容器 ip route 和 cat /etc/resolv.conf,最后回到宿主机看 brctl show 和 iptables -t nat -S——链路是层层嵌套的,漏掉一层就白调。

















