Skip to content
Docker 网络

Docker 网络

Docker 的网络子系统负责容器之间、容器与宿主机之间、容器与外部世界之间的通信。


网络驱动概览

驱动 默认 隔离性 适用场景
bridge 宿主机内部 单机容器间通信
host 无隔离 高性能网络需求
none 完全隔离 无需网络的容器
overlay 跨宿主机 Swarm 多机通信
macvlan 物理网络级 容器直接接入物理网络
ipvlan 物理网络级 替代 macvlan(少 MAC 限制)

bridge — 桥接模式

默认 bridge

# 不指定网络时,容器使用默认 bridge(docker0)
docker run -d --name c1 nginx
docker run -d --name c2 nginx
┌──────────────────────────────────────┐
│              宿主机                  │
│  ┌─────────┐    ┌─────────┐         │
│  │ 容器 c1  │    │ 容器 c2  │         │
│  │172.17.0.2│    │172.17.0.3│         │
│  └────┬─────┘    └────┬─────┘         │
│       └───────┬───────┘               │
│         ┌─────▼──────┐                │
│         │  docker0   │ ← 虚拟网桥     │
│         │ 172.17.0.1 │                │
│         └─────┬──────┘                │
│         ┌─────▼──────┐                │
│         │ iptables   │ ← NAT         │
│         │ (DNAT/SNAT)│                │
│         └─────┬──────┘                │
│         ┌─────▼──────┐                │
│         │    eth0    │ ← 物理网卡     │
│         └────────────┘                │
└──────────────────────────────────────┘

🚨 默认 bridge 的限制:容器之间只能通过 IP 通信,不能通过容器名 DNS 解析。需要 DNS 的服务发现应使用自定义 bridge 网络

自定义 bridge(用户定义网络)

docker network create --driver bridge my_bridge

# 创建时指定子网
docker network create \
  --driver bridge \
  --subnet=192.168.100.0/24 \
  --gateway=192.168.100.1 \
  my_bridge

docker run -d --name web --network my_bridge nginx
docker run -d --name api --network my_bridge my_api

🔬 深入原理:自定义 bridge 网络相比默认 bridge 的核心区别:

特性 默认 bridge 自定义 bridge
DNS 解析(容器名) ❌ 不支持 ✅ 支持
容器互联(–link) 需要手动 自动
网络配置 固定 可自定义子网/网关/IP
隔离性 所有容器共享 按网络隔离

容器连接/断开网络

# 将运行中的容器连接到网络
docker network connect my_bridge web

# 连接时指定 IP
docker network connect --ip 192.168.100.10 my_bridge web

# 断开连接
docker network disconnect my_bridge web

💡 一个容器可以连接到多个网络,实现不同网络间的隔离访问。


host — 主机模式

docker run -d --network host nginx
不使用 namespace 隔离网络
容器直接使用宿主机的网络栈
宿主机 :80 → 容器的 80 端口(无需 -p 映射)
优缺点 说明
✅ 性能最高 无 NAT 转发、无虚拟网桥开销
✅ 无需端口映射 容器端口直接暴露在宿主机上
❌ 端口冲突 容器端口占用宿主机端口
❌ 安全隔离差 容器网络和宿主机完全共享
❌ 仅 Linux Windows/Mac 不支持真正 host 模式

性能提示:对网络延迟敏感的数据库、消息队列等场景,可考虑 host 模式。如 Redis 官方镜像在基准测试时推荐 --network host


none — 无网络

docker run -d --network none my_app

容器没有网络接口,只有 lo 回环。适用于:

  • 批量计算任务
  • 安全隔离极高的场景
  • 不需要任何网络通信的后台任务

端口映射详解

# 基本格式:-p [宿主机IP:][宿主机端口:]容器端口[/协议]
docker run -p 8080:80 nginx                   # 0.0.0.0:8080 → 容器:80
docker run -p 127.0.0.1:8080:80 nginx         # 仅本地 8080 → 容器:80
docker run -p 53:53/udp dns_server            # UDP 端口
docker run -p 8080:80 -p 443:443 nginx        # 多个端口

# 随机端口映射(-P):将 EXPOSE 声明的端口随机映射
docker run -d -P nginx                         # EXPOSE 80 → 随机端口
docker port <container_id>                     # 查看映射结果

🔬 深入原理:端口映射通过 iptables 的 DNAT(目标地址转换)实现:

外部请求 0.0.0.0:8080
    │
    ▼
iptables DNAT: 0.0.0.0:8080 → 容器IP:80
    │
    ▼
docker-proxy 或直接 iptables 转发
    │
    ▼
容器 eth0:80

overlay — 跨主机网络(Swarm)

# 创建 overlay 网络(需要 Swarm 模式)
docker swarm init
docker network create --driver overlay --attachable my_overlay

# 创建服务跨多节点通信
docker service create --name web --network my_overlay --replicas 3 nginx
Node A: 容器 web.1 ──┐                    Node B: 容器 web.2 ──┐
                     │                                         │
               overlay 网络 (VXLAN 隧道加密)                    │
                     │                                         │
               ┌─────▼──────────────────────────────▼─────┐
               │       跨主机容器可直接通信               │
               └──────────────────────────────────────────┘

macvlan / ipvlan — 接入物理网络

macvlan

# 创建一个 macvlan 网络,容器获得独立 MAC 地址
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

容器直接接入物理网络,获得独立的 MAC 地址和 IP,看起来像一台独立的物理机。

🚨 陷阱:macvlan 模式下,宿主机本身无法直接与同一网卡的 macvlan 容器通信(Linux 内核限制)。如需宿主机和容器互通,需要创建子接口或使用 ipvlan。

ipvlan(推荐)

docker network create -d ipvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  -o ipvlan_mode=l2 \
  my_ipvlan
模式 特点
l2 二层桥接,类似 macvlan,共享宿主机 MAC(适用于 DHCP/MAC 受限环境)
l3 三层路由,需要手动添加路由(适用于大型网络、多子网)

DNS 解析机制

# 查看容器的 DNS 配置
docker exec web cat /etc/resolv.conf

# 输出示例:
# nameserver 127.0.0.11     ← Docker 内置 DNS
# options ndots:0

🔬 深入原理:Docker 内置 DNS 服务器监听 127.0.0.11

  • 自定义网络:自动 DNS 解析,容器名和 service 名均可解析
  • 默认 bridge:不支持 DNS 解析,只能通过 --link 添加 /etc/hosts
  • 容器名解析ping web127.0.0.11:53 → 返回容器 IP
  • TTL:默认由 Docker 守护进程管理,容器重建后 DNS 自动更新
# 自定义 DNS 服务器
docker run -d --dns 8.8.8.8 --dns 114.114.114.114 nginx

# 自定义搜索域
docker run -d --dns-search example.com nginx

网络调试命令

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

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

# 查看 iptables 规则
iptables -t nat -L -n | grep DOCKER

# 查看网桥信息
brctl show docker0
# 或
ip link show docker0

# 查看网络连接的容器
docker network inspect my_bridge

# 容器间连通性测试
docker exec web ping api
docker exec web nslookup api

网络模式总结对比

特性 bridge custom bridge host overlay macvlan
容器间 DNS N/A
端口映射 -p -p 不需要 -p 不需要
外部访问 NAT NAT 直接 NAT/LB 直接
性能 中等 中等 最高 较低(VXLAN)
跨主机
容器名解析 N/A

常见陷阱

陷阱 说明 正确做法
默认 bridge 无法 DNS 容器名无法解析 使用自定义 bridge 网络
host 模式端口冲突 容器与宿主机端口冲突 注意端口规划
macvlan 宿主机不通 宿主机无法访问 macvlan 容器 使用 ipvlan 或创建子接口
忘记创建网络 启动时 --network 指向不存在的网络 docker network create
Compose 网络名冲突 不同项目创建同名网络 默认自动加项目前缀隔离
internal: true 误解 内部网络容器无法访问外网 根据需求选择是否启用