容器化2024-04-0430 分钟阅读

Docker 网络模式完全指南:从原理到实战配置

深入讲解 Docker 的五种网络模式(bridge、host、none、container、overlay),包括工作原理、使用场景、配置方法和常见问题,帮助你彻底掌握 Docker 网络

Docker网络容器运维DevOps

Docker 网络概述

Docker 网络是容器之间以及容器与外部世界通信的基础。理解 Docker 网络模式对于构建高效、安全的容器化应用至关重要。

Docker 网络的核心概念

  • 网络驱动(Network Driver):决定容器如何连接网络
  • 网络命名空间(Network Namespace):隔离容器的网络栈
  • 虚拟网桥(Virtual Bridge):连接容器的虚拟交换机
  • veth pair:连接容器和宿主机的虚拟网卡对

Docker 支持的网络模式

Docker 提供了五种网络模式:

网络模式说明使用场景
bridge桥接模式(默认)单机容器通信
host主机模式高性能网络需求
none无网络模式完全隔离的容器
container容器模式共享网络栈
overlay覆盖网络模式跨主机容器通信

Bridge 网络模式(桥接模式)

Bridge 是 Docker 的默认网络模式,也是最常用的模式。

工作原理

  1. Docker 启动时创建一个名为 docker0 的虚拟网桥
  2. 每个容器启动时,Docker 创建一对 veth pair(虚拟网卡对)
  3. 一端连接到容器内部(eth0),另一端连接到 docker0 网桥
  4. 容器通过 docker0 网桥与其他容器和外部网络通信
宿主机
  ├── docker0 (172.17.0.1)
  │     ├── veth1 <---> 容器1 eth0 (172.17.0.2)
  │     ├── veth2 <---> 容器2 eth0 (172.17.0.3)
  │     └── veth3 <---> 容器3 eth0 (172.17.0.4)
  └── eth0 (宿主机网卡)

查看默认网桥

# 查看 Docker 网络列表
docker network ls

# 输出示例
NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
1234567890ab   host      host      local
abcdef123456   none      null      local

# 查看 bridge 网络详情
docker network inspect bridge

# 查看宿主机网桥
ip addr show docker0
# 或
ifconfig docker0

创建自定义 Bridge 网络

自定义网络比默认 bridge 更强大,支持容器名解析(DNS)。

# 创建自定义网络
docker network create --driver bridge my-network

# 指定子网和网关
docker network create \
  --driver bridge \
  --subnet 192.168.100.0/24 \
  --gateway 192.168.100.1 \
  my-custom-network

# 查看网络详情
docker network inspect my-custom-network

使用 Bridge 网络

# 使用默认 bridge 网络
docker run -d --name web1 nginx

# 使用自定义网络
docker run -d --name web2 --network my-network nginx

# 为运行中的容器连接网络
docker network connect my-network web1

# 断开网络连接
docker network disconnect my-network web1

# 指定容器 IP(仅自定义网络支持)
docker run -d --name web3 \
  --network my-custom-network \
  --ip 192.168.100.10 \
  nginx

端口映射

Bridge 模式下,容器端口需要映射到宿主机才能被外部访问。

# 映射单个端口
docker run -d -p 8080:80 --name web nginx
# 宿主机 8080 端口 -> 容器 80 端口

# 映射多个端口
docker run -d \
  -p 8080:80 \
  -p 8443:443 \
  --name web nginx

# 映射到随机端口
docker run -d -p 80 --name web nginx

# 查看端口映射
docker port web

# 指定监听地址
docker run -d -p 127.0.0.1:8080:80 --name web nginx
# 只允许本机访问

# 映射所有端口
docker run -d -P --name web nginx
# 自动映射 Dockerfile 中 EXPOSE 的所有端口

容器间通信

默认 bridge 网络

# 启动两个容器
docker run -d --name web1 nginx
docker run -d --name web2 nginx

# 查看容器 IP
docker inspect web1 | grep IPAddress
# 输出:172.17.0.2

# 从 web2 访问 web1(只能用 IP)
docker exec web2 ping 172.17.0.2

自定义 bridge 网络

# 创建自定义网络
docker network create my-net

# 启动容器
docker run -d --name web1 --network my-net nginx
docker run -d --name web2 --network my-net nginx

# 从 web2 访问 web1(可以用容器名)
docker exec web2 ping web1
# 自动 DNS 解析容器名

# 从 web2 访问 web1 的服务
docker exec web2 curl http://web1

Bridge 模式的优缺点

优点

  • ✅ 容器之间网络隔离,安全性好
  • ✅ 支持端口映射,灵活性高
  • ✅ 自定义网络支持容器名解析
  • ✅ 适合单机部署

缺点

  • ❌ 性能略低于 host 模式(多一层 NAT)
  • ❌ 端口映射可能导致端口冲突
  • ❌ 不支持跨主机通信

适用场景

  • 单机运行多个容器
  • 需要网络隔离的应用
  • Web 应用、数据库、缓存等常规服务

Host 网络模式(主机模式)

Host 模式下,容器直接使用宿主机的网络栈,不进行网络隔离。

工作原理

  • 容器不会获得独立的 Network Namespace
  • 容器直接使用宿主机的 IP 地址和端口
  • 容器内的进程可以直接绑定宿主机的任意端口
  • 没有 NAT 转换,性能最优
宿主机 (192.168.1.100)
  └── eth0
        ├── 宿主机进程
        └── 容器进程(共享网络栈)

使用 Host 网络

# 启动容器使用 host 网络
docker run -d --name web --network host nginx

# 查看容器网络配置
docker exec web ip addr
# 输出与宿主机完全相同

# 容器内的 Nginx 直接监听宿主机的 80 端口
# 无需端口映射,直接访问宿主机 IP:80
curl http://宿主机IP:80

Host 模式的特点

优点

  • ✅ 网络性能最优(无 NAT 损耗)
  • ✅ 配置简单,无需端口映射
  • ✅ 容器可以直接使用宿主机的网络资源

缺点

  • ❌ 容器与宿主机共享网络,隔离性差
  • ❌ 端口冲突风险高
  • ❌ 安全性较低
  • ❌ 不支持在同一主机上运行多个相同端口的容器

适用场景

  • 对网络性能要求极高的应用
  • 需要监听大量端口的应用
  • 网络监控、抓包工具
  • 单容器部署的场景

实战示例

# 运行高性能 Web 服务
docker run -d --name nginx-high-perf \
  --network host \
  nginx

# 运行网络监控工具
docker run -it --rm \
  --network host \
  nicolaka/netshoot \
  tcpdump -i eth0

# 运行需要访问宿主机服务的容器
docker run -d --name app \
  --network host \
  myapp:latest

None 网络模式(无网络模式)

None 模式下,容器拥有独立的 Network Namespace,但不进行任何网络配置。

工作原理

  • 容器有独立的网络栈
  • 只有 loopback 接口(127.0.0.1)
  • 没有其他网络接口
  • 完全与外界隔离

使用 None 网络

# 启动无网络容器
docker run -d --name isolated --network none nginx

# 查看容器网络
docker exec isolated ip addr
# 输出:
# 1: lo: <LOOPBACK,UP,LOWER_UP>
#     inet 127.0.0.1/8 scope host lo

# 容器无法访问外网
docker exec isolated ping 8.8.8.8
# ping: bad address '8.8.8.8'

手动配置网络

如果需要,可以手动为 none 模式的容器配置网络:

# 创建容器
docker run -d --name test --network none busybox sleep 3600

# 获取容器 PID
PID=$(docker inspect -f '{{.State.Pid}}' test)

# 创建 veth pair
ip link add veth0 type veth peer name veth1

# 将 veth1 加入容器的网络命名空间
ip link set veth1 netns $PID

# 配置容器内的网络
nsenter -t $PID -n ip addr add 192.168.1.2/24 dev veth1
nsenter -t $PID -n ip link set veth1 up

None 模式的优缺点

优点

  • ✅ 最高级别的网络隔离
  • ✅ 安全性最高
  • ✅ 适合不需要网络的任务

缺点

  • ❌ 无法与外界通信
  • ❌ 使用场景有限

适用场景

  • 数据处理任务(不需要网络)
  • 安全敏感的应用
  • 需要完全自定义网络配置的场景

Container 网络模式(容器模式)

Container 模式下,新容器与指定的已存在容器共享网络栈。

工作原理

  • 新容器不创建独立的 Network Namespace
  • 与指定容器共享 IP 地址、端口范围、路由表
  • 两个容器的网络配置完全相同
  • 类似于 Kubernetes 的 Pod 网络模型
容器1 (Network Namespace)
  ├── eth0 (172.17.0.2)
  ├── 容器1 进程
  └── 容器2 进程(共享网络栈)

使用 Container 网络

# 启动第一个容器
docker run -d --name web nginx

# 启动第二个容器,共享 web 的网络
docker run -d --name sidecar \
  --network container:web \
  busybox sleep 3600

# 查看两个容器的网络配置
docker exec web ip addr
docker exec sidecar ip addr
# 输出完全相同

# sidecar 可以通过 localhost 访问 web
docker exec sidecar wget -O- http://localhost:80

实战场景:Sidecar 模式

# 主应用容器
docker run -d --name app \
  -p 8080:8080 \
  myapp:latest

# 日志收集 sidecar
docker run -d --name log-collector \
  --network container:app \
  -v /var/log:/logs \
  fluentd:latest

# 监控 sidecar
docker run -d --name metrics \
  --network container:app \
  prom/node-exporter

Container 模式的优缺点

优点

  • ✅ 容器间通信使用 localhost,性能高
  • ✅ 简化网络配置
  • ✅ 适合 Sidecar 模式

缺点

  • ❌ 容器间网络不隔离
  • ❌ 端口冲突风险
  • ❌ 一个容器停止会影响另一个

适用场景

  • Sidecar 模式(日志收集、监控、代理)
  • 需要紧密协作的容器
  • 模拟 Kubernetes Pod 行为

Overlay 网络模式(覆盖网络)

Overlay 网络用于跨主机的容器通信,是 Docker Swarm 和 Kubernetes 的基础。

工作原理

  • 基于 VXLAN 技术实现
  • 在物理网络之上创建虚拟网络
  • 容器可以跨主机通信,就像在同一网络
  • 需要 key-value 存储(etcd、Consul)或 Swarm 模式
主机1 (192.168.1.10)              主机2 (192.168.1.20)
  ├── 容器1 (10.0.0.2)              ├── 容器3 (10.0.0.4)
  └── 容器2 (10.0.0.3)              └── 容器4 (10.0.0.5)
        │                                  │
        └──────── Overlay 网络 ────────────┘
               (VXLAN 隧道)

初始化 Swarm 模式

# 在主节点初始化 Swarm
docker swarm init --advertise-addr 192.168.1.10

# 输出加入命令,在其他节点执行
docker swarm join --token SWMTKN-xxx 192.168.1.10:2377

# 查看节点
docker node ls

创建 Overlay 网络

# 创建 overlay 网络
docker network create \
  --driver overlay \
  --subnet 10.0.0.0/24 \
  --gateway 10.0.0.1 \
  my-overlay

# 创建可附加到独立容器的 overlay 网络
docker network create \
  --driver overlay \
  --attachable \
  my-attachable-overlay

# 查看网络
docker network ls

使用 Overlay 网络

# 创建服务(自动使用 overlay 网络)
docker service create \
  --name web \
  --network my-overlay \
  --replicas 3 \
  nginx

# 查看服务
docker service ls
docker service ps web

# 在不同主机上的容器可以互相通信
# 主机1
docker run -it --rm \
  --network my-attachable-overlay \
  --name test1 \
  busybox

# 主机2
docker run -it --rm \
  --network my-attachable-overlay \
  --name test2 \
  busybox

# 在 test1 中 ping test2
ping test2

Overlay 网络加密

# 创建加密的 overlay 网络
docker network create \
  --driver overlay \
  --opt encrypted \
  secure-overlay

# 使用加密网络
docker service create \
  --name secure-web \
  --network secure-overlay \
  nginx

Overlay 模式的优缺点

优点

  • ✅ 支持跨主机容器通信
  • ✅ 自动服务发现和负载均衡
  • ✅ 支持网络加密
  • ✅ 适合微服务架构

缺点

  • ❌ 配置复杂,需要 Swarm 或 K8s
  • ❌ 性能略低于 bridge(封装开销)
  • ❌ 需要额外的网络组件

适用场景

  • 跨主机的容器编排(Swarm、Kubernetes)
  • 微服务架构
  • 分布式应用
  • 需要服务发现和负载均衡的场景

网络故障排查

常用排查命令

# 查看容器网络配置
docker inspect <container_id> | grep -A 20 NetworkSettings

# 进入容器网络命名空间
docker exec -it <container_id> bash

# 查看容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_id>

# 查看容器端口映射
docker port <container_id>

# 测试容器网络连通性
docker exec <container_id> ping <target>
docker exec <container_id> curl <url>
docker exec <container_id> telnet <host> <port>

# 查看容器路由表
docker exec <container_id> ip route

# 查看容器 DNS 配置
docker exec <container_id> cat /etc/resolv.conf

# 抓包分析
docker exec <container_id> tcpdump -i eth0 -w /tmp/capture.pcap

常见问题及解决

问题 1:容器无法访问外网

排查步骤

# 1. 检查容器 DNS
docker exec <container_id> cat /etc/resolv.conf

# 2. 测试 DNS 解析
docker exec <container_id> nslookup google.com

# 3. 检查路由
docker exec <container_id> ip route

# 4. 检查宿主机 IP 转发
cat /proc/sys/net/ipv4/ip_forward
# 应该输出 1

# 5. 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 或永久启用
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

# 6. 检查 iptables NAT 规则
iptables -t nat -L -n

问题 2:容器间无法通信

排查步骤

# 1. 检查容器是否在同一网络
docker network inspect <network_name>

# 2. 检查防火墙规则
iptables -L -n

# 3. 检查容器 IP
docker inspect <container_id> | grep IPAddress

# 4. 测试连通性
docker exec <container1> ping <container2_ip>

# 5. 检查端口是否监听
docker exec <container_id> netstat -tlnp

问题 3:端口映射不生效

排查步骤

# 1. 检查端口映射配置
docker port <container_id>

# 2. 检查容器内服务是否启动
docker exec <container_id> netstat -tlnp | grep <port>

# 3. 检查宿主机端口是否被占用
netstat -tlnp | grep <port>

# 4. 检查防火墙
iptables -L -n | grep <port>

# 5. 检查 Docker 代理规则
iptables -t nat -L -n | grep <port>

问题 4:DNS 解析失败

解决方案

# 方法 1:指定 DNS 服务器
docker run -d \
  --dns 8.8.8.8 \
  --dns 114.114.114.114 \
  nginx

# 方法 2:修改 Docker 守护进程配置
cat > /etc/docker/daemon.json <<EOF
{
  "dns": ["8.8.8.8", "114.114.114.114"]
}
EOF

# 重启 Docker
systemctl restart docker

# 方法 3:使用宿主机 DNS
docker run -d \
  --dns-search example.com \
  nginx

最佳实践

1. 网络规划

  • ✅ 为不同环境使用不同的网络(开发、测试、生产)
  • ✅ 使用自定义网络而非默认 bridge
  • ✅ 合理规划 IP 地址段,避免冲突
  • ✅ 使用有意义的网络名称

2. 安全配置

# 禁用容器间通信(默认 bridge)
docker network create \
  --driver bridge \
  --opt com.docker.network.bridge.enable_icc=false \
  isolated-net

# 限制容器只能访问特定网络
docker run -d \
  --network isolated-net \
  --cap-drop=NET_RAW \
  nginx

3. 监控和日志

# 查看网络统计
docker stats

# 查看网络事件
docker events --filter type=network

# 导出网络配置
docker network inspect my-net > network-config.json

4. 清理无用网络

# 查看未使用的网络
docker network ls --filter dangling=true

# 删除未使用的网络
docker network prune

# 删除指定网络
docker network rm my-net

总结

网络模式选择指南

场景推荐模式原因
单机多容器Bridge(自定义)隔离性好,支持容器名解析
高性能需求Host无 NAT 损耗,性能最优
完全隔离None安全性最高
Sidecar 模式Container共享网络栈,通信高效
跨主机通信Overlay支持分布式部署

关键要点

✅ 默认使用自定义 bridge 网络,而非默认 bridge
✅ 生产环境避免使用 host 模式(安全风险)
✅ 合理规划网络,避免 IP 冲突
✅ 使用容器名而非 IP 地址进行通信
✅ 定期清理无用网络资源
✅ 监控网络性能和连接状态

参考资料