Docker 网络深度解析:从默认网络到自定义网络实战
在微服务架构中,容器间通信是核心需求。Docker 提供了灵活的网络模型,让容器既能隔离运行,又能高效协作。本文将深入剖析 Docker 网络原理,并通过实战演示如何构建可靠的容器通信方案。
为什么需要理解 Docker 网络?
- 容器 IP 动态分配,硬编码 IP 会导致服务中断
- 默认 bridge 网络不支持服务发现(无法通过容器名通信)
- 生产环境需网络隔离与安全控制
一、Docker 网络基础架构
1. 核心组件:docker0 网桥
安装 Docker 后,系统自动创建 docker0 虚拟网桥:
bash
$ ip addr show docker0
3: docker0: mtu 1500 qdisc noqueue state DOWN
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
- IP 范围 :
172.17.0.0/16(可配置) - 作用:类似物理交换机,连接所有容器
2. 网络通信原理(Bridge 模式)

每个容器启动时:
- Docker 在宿主机创建 veth pair(虚拟网卡对)
- 一端接入
docker0网桥(如veth123456) - 另一端放入容器 namespace(重命名为
eth0) - 容器获得 IP(如
172.17.0.2),网关指向docker0(172.17.0.1)
💡 关键认知 :
容器间通信 = 宿主机上 veth 接口通过 docker0 交换数据包
二、四大网络模式详解
| 模式 | 原理 | 适用场景 | 命令 |
|---|---|---|---|
| bridge | 默认模式,通过 NAT 访问外网 | 开发测试、简单应用 | --network bridge |
| host | 共享宿主机网络栈 | 高性能场景(如监控代理) | --network host |
| none | 无网络配置 | 安全隔离(如离线计算) | --network none |
| container | 共享指定容器网络 | 边车模式(Sidecar) | --network container:<容器ID> |
模式对比图解
1. Bridge 模式(默认)



- 容器有独立 IP
- 外部访问需
-p端口映射
2. Host 模式

- 容器直接使用宿主机 IP 和端口
- 无端口冲突:多个容器不能绑定同一端口
3. Container 模式


- 新容器与目标容器共享网络 namespace
- 致命缺陷:目标容器停止 → 新容器网络失效
三、自定义网络:生产环境必备
为什么需要自定义网络?
| 问题 | 默认 bridge 网络 | 自定义网络 |
|---|---|---|
| 服务发现 | ❌ 无法通过容器名通信 | ✅ 内置 DNS 解析 |
| 网络隔离 | ❌ 所有容器互通 | ✅ 按需连接 |
| IP 管理 | ❌ IP 冲突风险 | ✅ 子网隔离 |
实战:创建 Tomcat 集群
步骤 1:创建自定义网络
bash
# 创建名为 xn_network 的 bridge 网络
docker network create xn_network
# 查看网络详情
docker network inspect xn_network
关键输出:
json
{
"Name": "xn_network",
"Driver": "bridge",
"Subnet": "172.18.0.0/16", // 独立子网
"IPAMOptions": {
"Driver": "default"
}
}
步骤 2:启动容器加入网络
bash
# 启动两个 Tomcat 容器
docker run -d --network xn_network -p 8081:8080 --name t1 tomcat
docker run -d --network xn_network -p 8082:8080 --name t2 tomcat
步骤 3:验证服务发现
bash
# 从 t1 ping t2(通过容器名!)
docker exec t1 ping t2
PING t2 (172.18.0.3) 56(84) bytes of data.
64 bytes from t2.xn_network (172.18.0.3): icmp_seq=1 ttl=64 time=0.087 ms
# 从 t2 访问 t1 的 Web 服务
docker exec t2 curl http://t1:8080
<!DOCTYPE html>
...
✅ 成功标志:
- 容器名自动解析为 IP
- 无需
-p即可内部通信(但外部访问仍需端口映射)
四、高级网络操作
1. 连接/断开现有容器
bash
# 将运行中的容器加入网络
docker network connect xn_network existing_container
# 从网络断开
docker network disconnect xn_network existing_container
2. 多网络支持
单个容器可加入多个网络:
bash
docker network create net1
docker network create net2
docker run -d --network net1 --name app nginx
docker network connect net2 app
此时 app 容器拥有两个 IP(分别属于 net1 和 net2)
3. 自定义 DNS
bash
# 指定 DNS 服务器
docker run --dns 8.8.8.8 --network xn_network alpine
# 添加 hosts 条目
docker run --add-host=db:192.168.1.100 alpine
五、网络故障排查指南
常见问题 1:容器无法 ping 通
-
检查点 :
bash# 1. 是否在同一网络? docker inspect t1 | grep NetworkMode # 2. 防火墙是否阻止? iptables -L DOCKER # 3. 目标容器是否运行? docker ps -f name=t2
常见问题 2:DNS 解析失败
-
解决方案 :
bash# 查看容器内 DNS 配置 docker exec t1 cat /etc/resolv.conf # 测试 DNS 解析 docker exec t1 nslookup t2
常见问题 3:端口映射失效
-
原因 :
- 容器内服务未监听
0.0.0.0(只监听127.0.0.1) - 宿主机防火墙阻止(如 firewalld)
- 容器内服务未监听
-
验证 :
bash# 在容器内测试 docker exec t1 netstat -tuln | grep 8080 # 在宿主机测试 curl localhost:8081
六、生产环境最佳实践
1. 网络命名规范
bash
# 按环境/项目命名
docker network create prod-mysql-net
docker network create dev-redis-net
2. 最小权限原则
- Web 应用容器 → 仅加入
web-net - 数据库容器 → 仅加入
db-net - 通过
docker network connect按需互联
3. 清理未用网络
bash
# 定期清理僵尸网络
docker network prune -f
# 查看未用网络
docker network ls --filter "dangling=true"
4. 安全加固
-
禁用 ICC(容器间通信):
bashdockerd --icc=false -
使用 Macvlan/IPVLAN 实现物理网络直连(高性能场景)
七、总结:Docker 网络选型决策树
否
是
是
否
是
否
需要容器间通信?
使用 none 模式
是否需要高性能?
使用 host 模式
是否需服务发现?
创建自定义 bridge 网络
使用默认 bridge + IP 通信
🚀 行动清单:
- 为现有项目创建专用网络
- 将容器名替换硬编码 IP
- 在 CI/CD 中集成网络测试脚本
掌握 Docker 网络,你就拥有了构建高可用、可扩展、安全隔离 微服务架构的核心能力。下一步,我们将探索如何用 docker-compose 编排多容器网络!