Docker网络模式:5分钟搞懂4种模式 + 避坑指南(附命令)
先看结论一张表帮你选对模式模式一句话说明适合你吗坑点提醒bridge默认模式每个容器有自己的私有IP✅ 单机大多数场景需要端口映射才能从外部访问host直接使用宿主机网络栈无隔离 对性能极致追求的场景端口冲突风险高隔离性差none完全无网络 极少数特殊场景需要自己配网卡麻烦container共享另一个容器的网络 “网络伴侣”场景俩容器绑死牵一发而动全身自定义bridge用户自己建的桥接网络⭐强烈推荐生产首选需要主动创建我会按顺序逐个讲透跳过那谁都能背的概念直接上命令和踩过的坑。一、Bridge模式默认模式1.1 发生了什么启动Docker时它会自动在宿主机上创建一个叫docker0的虚拟网桥。每个容器从这段私有IP默认172.17.0.2/16里拿一个IP容器之间通过这个网桥互连。更准确地说每个容器里有张虚拟网卡eth0宿主机有对应的vethxxx这俩是一对。所有vethxxx都挂在docker0上容器间就能通信了。外部想访问容器里的服务必须用-p 8080:80做端口映射——这也是Docker在iptables里自动加NAT规则实现的。1.2 什么时候用它刚学Docker时练手单机跑几组隔离的微服务开发环境快速验证但是生产环境我不建议直接用默认的bridge网络。原因很致命——默认网络不支持容器名的DNS解析。容器A想访问容器B的服务只能写死IP而容器重启IP是会变的。1.3 命令速查# 查现有网络 docker network ls # 用默认bridge启动两个nginx做端口映射 docker run -d --name nginx1 -p 8081:80 nginx docker run -d --name nginx2 -p 8082:80 nginx # 看容器的私有IP docker inspect nginx1 | grep IPAddress # 容器间互ping需要先装ping或者用alpine镜像 docker exec nginx2 ping 172.17.0.2 # 假设nginx1的IP是172.17.0.2预期输出宿主机上curl localhost:8081能看到nginx欢迎页nginx2pingnginx1成功二、自定义Bridge模式生产推荐2.1 为什么非要自定义一个出来前面说了默认桥接网络不支持容器名DNS自动解析这是个大坑。Docker官方也明确写着用户自定义的桥接网络优于默认的bridge。自定义网络的两大核心优势同一个自定义桥接网络里的容器可以直接用容器名互相访问自动DNS解析不用写死IP配置更灵活——子网、网关、IP范围都可以自己定避免与主机网段冲突2.2 两分钟创建自定义网络# 创建自定义桥接网络不指定子网Docker会选一个 docker network create mynet # 或指定子网避免冲突 docker network create --subnet 10.88.0.0/16 --gateway 10.88.0.1 mynet2 # 查看刚才创建的网络 docker network ls docker network inspect mynet # 在自定义网络中启动容器 docker run -d --name app1 --network mynet nginx docker run -d --name app2 --network mynet nginx # 关键验证app2中能否用app1的名字ping通 docker exec app2 ping app1 # 应该能通并且解析到10.88.x.x的IP这条ping app1直接能用就是自定义网络最大的价值开发体验提升巨大。三、Host模式3.1 原理和适用场景Host模式下容器直接共享宿主机的网络命名空间不再有自己的IP。-p参数失效容器里开什么端口就直接暴露在宿主机上。适合的场景对网络性能要求极高避免NAT开销需要监控宿主机完整网络栈比如网络监控工具、抓包容器端口充足的测试/单机环境不推荐在以下场景用同一宿主机需要跑多个同类服务会抢端口任何对隔离性有要求的场景容器能直接操作宿主机网络3.2 示例docker run -d --name host-nginx --network host nginx # 此时直接访问宿主机的80端口就能看到nginx访问http://your-host-ip就能看到Nginx欢迎页无需端口映射。四、None模式这个最简单--network none启动的容器只有一块lo回环网卡没有eth0没有路由ping不通任何人。只有特殊场景才需要离线批处理、手动配置网络栈的极客玩法、安全要求极高的隔离环境。平时基本用不上。五、Container模式共享模式这种模式的写法是--network container:existing-container-name。新容器与已存在的容器共享网络命名空间换句话说它们的IP相同端口也共用。听起来有点绕看个例子就懂了# 先跑一个有nginx的容器 docker run -d --name web --network bridge nginx # 第二个容器用container模式共享web的网络命名空间 docker run -it --name monitor --network container:web alpine sh # 进去之后 ip addr show能看到和web容器完全一样的网络接口适合的实战场景调试/监控——你想从另一个容器里抓web容器的网络包用这个模式可以直接抓某些Sidecar代理——sidecar需要“紧贴”主容器和它共享网络栈踩过坑提醒共享网络时一个容器改了iptables规则另一个容器也会受影响。最好只用于临时调试。六、一图看懂几种模式关系Bridge模式 宿主机 ←→ docker0 ←→ vethxxx ←→ 容器1172.17.0.2 ↳ vethyyy ←→ 容器2172.17.0.3 Host模式 宿主机 ←→ 容器共享网络栈无隔离 Custom Bridge模式 同上结构但容器之间可直接用容器名通信 Container模式 容器A ←→ 容器B共享网络命名空间IP完全一样 None模式 容器只有lo回环无任何网络七、你以为你懂了这里有个大坑iptables这条在生产环境吃过亏的人一定有共鸣Docker在Linux上用iptables和ip6tables规则来实现网络隔离、端口发布和过滤。7.1 规则链在filter表里Docker建了这些链DOCKER-USER——用户自定义规则的占位符优先处理DOCKER——根据容器端口转发配置判断是否接纳数据包DOCKER-FORWARD——Docker网络的处理第一阶段DOCKER-ISOLATION-STAGE-1/2——隔离Docker网络DOCKER-INGRESS——与Swarm网络相关关键点Docker把FORWARD链的默认策略设置成了DROP需手动更改才能允许额外转发这个细节容易漏常见的场景是容器能ping通外网但宿主机访问不了容器端口——检查一下FORWARD链是否被外部工具覆盖了7.2 为什么说这里是大坑很多人在宿主机上配置自己的防火墙比如Ufw、firewalld时会不小心影响到Docker的规则链结果容器网络突然不灵了。Docker官方不建议手动添加iptables规则来修复端口映射——规则链很复杂容易引入新问题。我吃过一次亏某个业务凌晨3点报警容器网络突然不通。排查了一通发现是systemctl restart ufw之后iptables规则变了Docker的FORWARD链被覆盖。解决办法很简单重启Docker容器。Docker会重新生成所有必要规则。# 规则被覆盖后的救急三板斧 systemctl restart docker # 重启Docker # 或 docker restart 容器名 # 重启单个容器 # 如果还不行检查IP转发 cat /proc/sys/net/ipv4/ip_forward # 如果返回0临时开启一下 echo 1 /proc/sys/net/ipv4/ip_forward # 永久开启改 /etc/sysctl.conf加 net.ipv4.ip_forward17.3 如何在冲突时插入自己的iptables规则如果你必须在Docker的规则生效前加自己的规则用DOCKER-USER链。举例只允许来源IP192.168.1.100访问8080端口iptables -I DOCKER-USER -p tcp --dport 8080 -s 192.168.1.100 -j ACCEPT iptables -I DOCKER-USER -p tcp --dport 8080 -j DROP八、跨主机通信怎么搞一句话总结Bridge/host/none 都只能在单机上玩。跨主机你有三种主流方案。8.1 Overlay最通用底层用VXLAN隧道封装不同主机的容器通信时IP包被封装到UDP包中通过4789端口传输需要Swarm模式或K8s支持支持加密--opt encrypted例docker swarm init --advertise-addr 你的IP docker network create --driver overlay --attachable my-overlay docker run -d --name app1 --network my-overlay nginx推荐场景生产级多主机集群、服务发现、微服务8.2 Macvlan让每个容器看起来像物理设备——有独立的MAC地址直接暴露在物理网络上。docker network create -d macvlan \ --subnet192.168.1.0/24 \ --gateway192.168.1.1 \ -o parenteth0 macnet推荐场景对延迟极敏感的应用重传统应用的迁移原来在物理机上跑的应用一刀不改造迁到容器里缺点有些交换机/云平台限制每端口MAC地址数量比如AWS可能会被限。8.3 IPvlan跟Macvlan类似但共享MAC地址——不会为每个容器分配单独的MAC。docker network create -d ipvlan \ --subnet192.168.1.0/24 \ --gateway192.168.1.1 \ -o parenteth0 ipvnet推荐场景交换机/云平台对MAC地址数量有限制时IPvlan是更好的选择。 内核版本需≥4.2。8.4 三种方案横向对比方案适合什么场景明显缺点Overlay生产集群、微服务有VXLAN封装开销~50字节全场景延时~5%~10%配置稍复杂Macvlan极低延迟场景、传统应用移植MAC地址可能受限容器需自行配置IPIPvlanMac地址受限的云环境内核版本要求较高≥4.2九、排查Docker网络故障的4个实用小技巧判断故障范围先确定是哪不通容器之间不通容器访问外网失败宿主机访问容器端口超时还是curl镜像都拉不下来进容器手动测docker exec -it myapp bash ping 8.8.8.8 # 通吗 ping google.com # DNS正常吗检查DNScat /etc/resolv.conf # 正常应该指向 8.8.8.8 或 114.114.114.114三板斧重启docker restart 容器名 # 重启容器最常见修复 systemctl restart docker # 重启Docker会重新生成iptables规则 我自己的推荐带主观判断在生产环境单机多容器微服务我强烈推荐创建自定义桥接网络docker network create mynet然后把所有需要互相通信的服务放进这个网络里。✅ 提供容器名自动DNS解析比写死IP灵活百倍✅ 可指定子网避免IP冲突✅ 方便编排docker-compose或K8s迁移时改动小自定义网络绝对比默认bridge好用。99%的单机生产环境都应该这么做。至于host和none除非有明确的需求否则不要随便碰。讲真在生产中用host需要格外小心隔离性差不说端口冲突排查起来能把你搞疯。版本信息Docker 26.xLinux内核≥4.x| 本文基于2026年4月Docker主流版本编写 | 上次更新2026年4月24日 你遇到过什么Docker网络“灵异事件”欢迎在评论区分享你的踩坑经历我们一起避坑如果这篇文章对你有用欢迎分享给更多同行~