Docker 网络管理
一、Docker 网络概述
1.1 什么是 Docker 网络
Docker 网络是容器之间、容器与宿主机之间、容器与外部网络之间通信的基础设施。Docker 在安装时会自动创建三种默认网络,并提供多种网络驱动以满足不同场景需求。
1.2 Docker 网络的核心作用
| 作用 | 说明 |
|---|---|
| 容器间通信 | 同一宿主机上不同容器之间的互联互通 |
| 容器与外部通信 | 容器访问互联网或外部服务 |
| 外部访问容器 | 通过端口映射将容器服务暴露给外部用户 |
| 网络隔离 | 不同网络间的容器相互隔离,提升安全性 |
| 服务发现 | 容器可以通过名称互相访问(自定义网络) |
1.3 查看 Docker 网络
# 查看所有网络
docker network ls
# 输出示例
NETWORK ID NAME DRIVER SCOPE
c8e6b7d9f1a2 bridge bridge local
a1b2c3d4e5f6 host host local
f6e5d4c3b2a1 none null local
二、五种网络驱动详解
Docker 提供 5 种网络驱动,每种适用于不同场景:
| 驱动 | 说明 | 适用场景 |
|---|---|---|
| bridge | 默认网络驱动,容器通过 Docker 网桥通信 | 单机容器通信(默认) |
| host | 容器直接使用宿主机网络栈 | 高性能场景、端口固定 |
| overlay | 跨主机容器通信(Swarm/Kubernetes) | 多机集群 |
| macvlan | 容器拥有独立 MAC 地址,直连物理网络 | 需要直接暴露到物理网络 |
| none | 无网络,完全隔离 | 安全要求极高、不需要网络 |
2.1 bridge(桥接网络)
原理:Docker 在宿主机创建一个虚拟网桥 docker0,每个容器通过 veth pair 连接到该网桥,容器间通过网桥通信。
宿主机
┌─────────────────────────────────────────────────────────────────┐
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 容器 A │ │ 容器 B │ │
│ │ eth0 │ │ eth0 │ │
│ │ 172.17.0.2 │ │ 172.17.0.3 │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ veth pair │ veth pair │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ docker0 │ ← 虚拟网桥 │
│ │ 172.17.0.1 │ │
│ └──────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ 宿主机网卡 │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
常用命令:
# 查看 bridge 网络详情
docker network inspect bridge
# 创建自定义 bridge 网络(推荐)
docker network create --driver bridge my-net
# 运行容器时指定网络
docker run -d --name myapp --network my-net nginx
默认 bridge vs 自定义 bridge:
| 对比项 | 默认 bridge | 自定义 bridge |
|---|---|---|
| 容器间 DNS 解析 | 不支持(需用 IP) | 支持容器名解析 |
| 网络隔离 | 所有容器都在同一网络 | 可创建多个隔离网络 |
| 容器热插拔 | 需重启容器 | 可动态连接/断开 |
| 配置灵活性 | 低 | 高 |
2.2 host(主机网络)
原理:容器直接使用宿主机网络栈,不进行网络隔离,容器端口直接绑定到宿主机。
# 使用 host 网络
docker run -d --network host --name myapp nginx
# 此时容器中的 nginx 直接使用宿主机的 80 端口
# 访问 http://宿主机IP:80 即可访问容器服务
优点:
- 性能接近原生(无 NAT 转换)
- 端口无需手动映射
缺点:
- 无网络隔离,容器与宿主机共享端口空间
- 不同容器的端口不能冲突
适用场景:
- 对网络性能要求极高的服务
- 需要固定端口的场景
- 监控工具(如 Prometheus Node Exporter)
2.3 overlay(覆盖网络)
原理:通过 VXLAN 隧道技术,让不同宿主机上的容器像在同一网络中通信。
适用场景:Docker Swarm、Kubernetes 集群跨主机通信。
# 创建 overlay 网络(需要 Swarm 模式)
docker network create -d overlay my-overlay
# 在 Swarm 服务中使用
docker service create --network my-overlay --name web nginx
2.4 macvlan(MAC 地址网络)
原理:为容器分配独立的 MAC 地址,容器直接连接到物理网络,像独立物理机一样。
# 创建 macvlan 网络
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
my-macvlan
# 运行容器
docker run -d --network my-macvlan --ip=192.168.1.100 nginx
适用场景:传统应用迁移、需要网络流量监控的场景。
2.5 none(无网络)
原理:容器没有网络接口,完全隔离。
docker run -d --network none --name isolated nginx
适用场景:
- 不需要网络的批处理任务
- 安全性要求极高的服务
- 离线数据处理
三、容器网络通信模式
3.1 容器间通信
# 创建自定义网络
docker network create app-net
# 启动两个容器在同一网络
docker run -d --name web --network app-net nginx
docker run -d --name redis --network app-net redis
# 通过容器名互相访问(DNS 自动解析)
docker exec web ping redis # 成功
docker exec web curl http://redis:6379 # 成功
3.2 容器访问外网
默认情况下,容器通过 NAT 访问外网:
# 容器内可以 ping 通外网
docker exec web ping 8.8.8.8
docker exec web curl https://www.baidu.com
3.3 外网访问容器(端口映射)
# 端口映射格式:-p 宿主机端口:容器端口
docker run -d -p 8080:80 --name web nginx
# 访问 http://宿主机IP:8080 即可访问 nginx
# 多端口映射
docker run -d -p 8080:80 -p 8443:443 nginx
# 随机端口映射
docker run -d -P nginx # 宿主机随机分配端口
# 只绑定到特定 IP
docker run -d -p 127.0.0.1:8080:80 nginx
3.4 端口映射查看
# 查看端口映射
docker port web
# 输出示例
80/tcp -> 0.0.0.0:8080
443/tcp -> 0.0.0.0:8443
# 查看所有容器端口映射
docker ps --format "table {{.Names}}\t{{.Ports}}"
四、自定义网络
4.1 创建自定义网络
# 创建 bridge 网络
docker network create --driver bridge my-bridge
# 创建带子网配置的网络
docker network create \
--driver bridge \
--subnet=10.10.0.0/16 \
--gateway=10.10.0.1 \
--ip-range=10.10.1.0/24 \
my-custom-net
# 带标签
docker network create --label env=prod my-prod-net
4.2 连接/断开容器
# 启动时指定网络
docker run -d --name web --network my-net nginx
# 运行时连接网络
docker network connect my-net web
# 断开网络
docker network disconnect my-net web
# 查看容器网络详情
docker inspect web
4.3 删除网络
# 删除网络(需先断开所有容器)
docker network rm my-net
# 删除所有未使用的网络
docker network prune
五、网络排障命令
5.1 查看网络详情
# 查看网络列表
docker network ls
# 查看网络详情(包括连接的容器)
docker network inspect bridge
# 查看容器网络配置
docker inspect web | grep -A 10 "Networks"
5.2 网络诊断工具
# 进入容器进行网络测试
docker exec -it web /bin/bash
# 在容器内
ping 172.17.0.3 # 测试 IP 连通性
curl http://redis:6379 # 测试服务
nslookup redis # DNS 解析测试
ip addr show # 查看容器 IP
route -n # 查看路由表
5.3 常见问题排查
# 查看容器 IP
docker inspect web | grep IPAddress
# 查看宿主机网桥配置
ip addr show docker0
brctl show docker0
# 查看 iptables 规则(端口映射由 NAT 实现)
iptables -t nat -L -n
# 查看网络连接跟踪
conntrack -L | grep 172.17
六、Docker Compose 网络
6.1 默认网络
version: '3.8'
services:
web:
image: nginx
redis:
image: redis
Compose 会创建名为 项目名_default 的网络,所有服务自动加入,可通过服务名互相访问。
6.2 自定义网络
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
api:
image: myapp
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
6.3 预定义网络(外部网络)
version: '3.8'
services:
web:
image: nginx
networks:
- my-existing-net
networks:
my-existing-net:
external: true
七、网络性能优化
7.1 性能对比
| 网络模式 | 性能 | 延迟 | 适用场景 |
|---|---|---|---|
| host | 最高 | 最低 | 高性能场景 |
| bridge(自定义) | 较高 | 低 | 一般生产 |
| bridge(默认) | 一般 | 中 | 测试开发 |
| overlay | 较低 | 高 | 跨主机通信 |
7.2 优化建议
# 1. 使用自定义 bridge 而非默认 bridge
docker network create my-net
# 2. 禁用 IP 转发(仅容器间通信,无需外网)
sysctl -w net.ipv4.ip_forward=0
# 3. 调整 docker0 网桥 MTU
# 修改 /etc/docker/daemon.json
{
"mtu": 1400
}
7.3 监控网络流量
# 查看容器网络流量
docker stats --no-stream
# 查看容器网络 I/O
docker inspect web | grep -A 5 "NetworkSettings"
# 使用 iftop 监控(需安装)
docker exec web iftop -i eth0
八、网络配置持久化
8.1 /etc/docker/daemon.json 配置
{
"bip": "172.20.0.1/16", // 网桥 IP
"fixed-cidr": "172.20.10.0/24", // 容器 IP 范围
"default-address-pools": [
{
"base": "172.20.0.0/16",
"size": 24
}
],
"mtu": 1400,
"iptables": true,
"ip-forward": true
}
8.2 重启网络配置
# 修改配置后重启 Docker
sudo systemctl restart docker
# 重启后需重建自定义网络
docker network prune
九、最佳实践
9.1 网络设计原则
| 原则 | 说明 |
|---|---|
| 分类隔离 | 不同环境(dev/test/prod)使用不同网络 |
| 按功能划分 | 前端网络、后端网络、数据库网络分层隔离 |
| 自定义网络 | 不使用默认 bridge,创建自定义网络 |
| 固定子网 | 生产环境规划好子网范围,避免 IP 冲突 |
9.2 安全建议
# 1. 容器只连接需要的网络
docker network connect frontend web
docker network connect backend api
# 2. 敏感服务不暴露端口
docker run -d --network backend --name db mysql
# 3. 使用防火墙限制访问
iptables -A DOCKER -p tcp --dport 8080 -s 192.168.1.0/24 -j ACCEPT
9.3 多环境网络隔离
# 创建不同环境的网络
docker network create dev-net
docker network create test-net
docker network create prod-net
# 不同环境使用不同网络实现隔离
docker run -d --network dev-net --name app-dev myapp:dev
docker run -d --network test-net --name app-test myapp:test
9.4 网络资源清理
# 清理未使用的网络
docker network prune
# 清理所有未使用的网络(不提示)
docker network prune -f
# 查看网络占用
docker network ls
docker network inspect <network> | grep -c "Container"
十、命令速查表
| 操作 | 命令 |
|---|---|
| 查看网络列表 | docker network ls |
| 查看网络详情 | docker network inspect <网络名> |
| 创建 bridge 网络 | docker network create <网络名> |
| 创建带子网的网络 | docker network create --subnet=10.0.0.0/24 <网络名> |
| 删除网络 | docker network rm <网络名> |
| 清理未使用网络 | docker network prune |
| 连接容器到网络 | docker network connect <网络名> <容器名> |
| 断开容器与网络 | docker network disconnect <网络名> <容器名> |
| 端口映射 | -p 宿主机端口:容器端口 |
| 随机端口映射 | -P |
| 使用 host 网络 | --network host |
| 使用 none 网络 | --network none |
| 查看容器 IP | docker inspect <容器名> \| grep IPAddress |
| 查看端口映射 | docker port <容器名> |
十一、总结
Docker 网络五驱动:
- bridge:单机默认,容器间通信(最常用)
- host:性能最佳,与宿主机共享网络
- overlay:跨主机通信,Swarm/K8s 用
- macvlan:直连物理网络,独立 MAC
- none:完全隔离,安全场景生产建议:使用自定义 bridge 网络实现容器间 DNS 解析,按环境/功能划分网络实现隔离,敏感服务不暴露端口,非必要不用
--network host。