在第15章中,我们掌握了Docker网络基础。本章将深入学习高级网络能力,包括Overlay跨主机通信、Macvlan/IPvlan、网络策略、安全加固和故障排查。

16.1 Overlay网络(跨主机通信)

16.1.1 Overlay网络原理

Overlay网络允许分布在不同主机上的容器互联,常用于Docker Swarm或Kubernetes场景。

Overlay网络架构:

Host A                                 Host B
┌─────────────────────┐               ┌─────────────────────┐
│ Docker Engine       │               │ Docker Engine       │
│  ┌───────────────┐  │               │  ┌───────────────┐  │
│  │  Container A  │  │               │  │  Container B  │  │
│  │  10.0.0.2     │  │               │  │  10.0.0.3     │  │
│  └───────────────┘  │               │  └───────────────┘  │
│         │           │               │         │           │
│  ┌──────┴──────┐    │               │  ┌──────┴──────┐    │
│  │ veth pair   │    │               │  │ veth pair   │    │
│  └──────┬──────┘    │               │  └──────┬──────┘    │
│         │           │               │         │           │
│  ┌──────┴─────────┐ │               │  ┌──────┴─────────  │
│  │ overlay bridge │ │               │  │ overlay bridge │ │
│  └──────┬─────────┘ │               │  └──────┬─────────┘ │
│         │ VXLAN     │               │         │ VXLAN     │
│  ┌──────┴─────────┐ │               │  ┌──────┴─────────┐ │
│  │    eth0        │ │               │  │    eth0        │ │
│  └──────┬─────────┘ │               │  └──────┬─────────┘ │
└─────────┼───────────┘               └─────────┼───────────┘
          │ 物理网络(LAN/WAN)                    │
          └──────────────────────────────────────┘

核心技术

  • VXLAN封装:使用UDP 4789端口
  • 分布式KV存储:保存网络状态
  • 跨主机路由:自动转发

16.1.2 Swarm模式创建Overlay网络

# 初始化Swarm(管理节点)
docker swarm init --advertise-addr 192.168.1.100

# 查看加入令牌
docker swarm join-token worker

# 在工作节点加入Swarm(在其他主机上执行)
docker swarm join \
  --token SWMTKN-1-xxx \
  192.168.1.100:2377

# 创建overlay网络
docker network create \
  --driver overlay \
  --attachable \
  --subnet 10.10.0.0/16 \
  my-overlay

# --attachable允许独立容器连接

# 在不同主机上启动容器(会自动互联)
docker run -d --name web1 --network my-overlay nginx
# 在另一台主机
# docker run -d --name web2 --network my-overlay nginx

# 互相ping通
# docker exec web1 ping web2

16.1.3 Overlay网络在Docker Compose中使用

# docker-compose.yml (Swarm stack)
version: '3.8'

services:
  web:
    image: nginx
    deploy:
      replicas: 3
    networks:
      - overlay-net

  api:
    image: myapi
    deploy:
      replicas: 2
    networks:
      - overlay-net

networks:
  overlay-net:
    driver: overlay
    attachable: true
# 部署stack
docker stack deploy -c docker-compose.yml myapp

# 查看服务
docker service ls

# 查看网络
docker network ls | grep overlay

16.1.4 Overlay常见问题

# 1. VXLAN端口未开放
# 必须开放:
# - 2377 (Swarm管理)
# - 7946 (节点发现 TCP/UDP)
# - 4789 (VXLAN UDP)

# 2. 检查overlay网络状态
docker network inspect my-overlay

# 3. 检查节点状态
docker node ls

# 4. 调试网络
# 在节点上查看vxlan接口
ip -d link show | grep vxlan

16.2 Macvlan网络

16.2.1 Macvlan原理

Macvlan让容器直接获得物理网络的MAC地址和IP,像一台独立主机一样。

Macvlan网络架构:

物理网络
┌────────────────────────────────────────┐
│        交换机/路由器                     │
└───────────┬───────────┬────────────────┘
            │           │
        主机eth0      容器MAC1      容器MAC2
        192.168.1.10  192.168.1.20  192.168.1.21

特点

  • ✅ 容器拥有独立IP(局域网可见)
  • ✅ 无需端口映射
  • ✅ 性能高(无NAT)
  • ⚠️ 主机默认无法访问容器(需额外配置)
  • ⚠️ 依赖物理网络支持(交换机需支持)

16.2.2 创建Macvlan网络

# 创建Macvlan网络
docker network create \
  --driver macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  --ip-range=192.168.1.200/28 \
  -o parent=eth0 \
  macvlan-net

# 运行容器并分配IP
docker run -d \
  --name web \
  --network macvlan-net \
  --ip 192.168.1.200 \
  nginx

# 容器从局域网访问
curl http://192.168.1.200

# 查看容器IP
docker inspect web -f '{{.NetworkSettings.Networks.macvlan-net.IPAddress}}'

16.2.3 解决主机访问容器问题

# 创建macvlan子接口(在主机上)
sudo ip link add macvlan0 link eth0 type macvlan mode bridge
sudo ip addr add 192.168.1.250/24 dev macvlan0
sudo ip link set macvlan0 up

# 现在主机可以访问容器
ping 192.168.1.200

# 解决方案脚本
cat > setup-macvlan.sh <<'EOF'
#!/bin/bash
IFACE=eth0
SUBNET=192.168.1.0/24
HOST_IP=192.168.1.250

sudo ip link add macvlan0 link $IFACE type macvlan mode bridge
sudo ip addr add $HOST_IP/24 dev macvlan0
sudo ip link set macvlan0 up

# 添加路由
sudo ip route add $SUBNET dev macvlan0

echo "Macvlan host interface setup complete"
EOF

chmod +x setup-macvlan.sh

16.2.4 Macvlan使用场景

✅ 需要容器暴露真实IP(如局域网服务)
✅ 传统应用迁移(要求固定IP)
✅ 网络设备模拟/测试
✅ 需要无NAT的高性能网络

16.3 IPvlan网络

16.3.1 IPvlan与Macvlan区别

特性 Macvlan IPvlan
MAC地址 每容器一个MAC 共享主机MAC
交换机负担 MAC数量增加 MAC数量不变
性能
主机访问容器 需额外配置 默认支持(L2模式)
适用场景 物理网络允许多MAC 网络限制MAC数量

16.3.2 创建IPvlan网络

# L2模式(同网段)
docker network create \
  --driver ipvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  -o ipvlan_mode=l2 \
  ipvlan-net

# L3模式(路由)
docker network create \
  --driver ipvlan \
  --subnet=192.168.2.0/24 \
  -o parent=eth0 \
  -o ipvlan_mode=l3 \
  ipvlan-net-l3

# 运行容器
docker run -d --network ipvlan-net nginx

16.4 网络安全与隔离

16.4.1 网络隔离策略

# 使用internal网络阻止外网访问
docker network create --internal backend-net

# 连接容器
docker run -d --name db --network backend-net postgres

# db无法访问外网
# docker exec db ping 8.8.8.8  # 失败

# 使用多网络隔离不同层
# frontend -> api -> db

16.4.2 限制容器间通信(ICC)

# 禁用默认bridge容器间通信
# /etc/docker/daemon.json
{
  "icc": false
}

# 重启Docker
sudo systemctl restart docker

# 或者创建自定义网络并禁用ICC
docker network create \
  --opt com.docker.network.bridge.enable_icc=false \
  isolated-net

16.4.3 使用iptables限制访问

# 示例:阻止容器访问某个IP
sudo iptables -I DOCKER-USER -d 10.0.0.5 -j DROP

# 允许特定容器访问
CONTAINER_IP=$(docker inspect app -f '{{.NetworkSettings.IPAddress}}')
sudo iptables -I DOCKER-USER -s $CONTAINER_IP -d 10.0.0.5 -j ACCEPT

# 查看规则
sudo iptables -L DOCKER-USER -n

16.4.4 端口暴露安全

# 仅本地访问
docker run -d -p 127.0.0.1:8080:80 nginx

# 绑定特定网卡
docker run -d -p 192.168.1.10:8080:80 nginx

# 使用防火墙限制
sudo ufw allow from 192.168.1.0/24 to any port 8080
sudo ufw deny 8080

16.5 Docker网络故障排查

16.5.1 常用排查步骤

# 1. 检查容器网络配置
docker inspect <container> --format '{{json .NetworkSettings.Networks}}' | jq

# 2. 查看DNS配置
docker exec <container> cat /etc/resolv.conf

# 3. 测试网络连通性
docker exec <container> ping -c 3 8.8.8.8

# 4. 测试DNS解析
docker exec <container> nslookup google.com

# 5. 查看路由表
docker exec <container> ip route

# 6. 检查主机iptables规则
sudo iptables -t nat -L -n | grep docker

# 7. 检查Docker网络
ip addr show docker0
brctl show

16.5.2 常见问题与解决

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

# 原因:IP转发关闭
# 解决:启用IP转发
sudo sysctl -w net.ipv4.ip_forward=1

# 永久生效
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

问题2:DNS解析失败

# 检查Docker DNS配置
cat /etc/docker/daemon.json

# 临时指定DNS
docker run --dns 8.8.8.8 --dns 1.1.1.1 alpine

# 重启Docker
sudo systemctl restart docker

问题3:端口映射不通

# 检查端口占用
sudo netstat -tulpn | grep 8080

# 检查容器端口
curl http://localhost:8080

# 检查容器内部服务
docker exec <container> netstat -tulpn

问题4:容器间无法通信

# 确认在同一网络
docker network inspect mynet

# 检查网络别名
# 使用容器名解析

# 重新连接网络
docker network disconnect mynet container
 docker network connect mynet container

16.5.3 网络诊断工具集

# 一键进入诊断容器
docker run -it --rm \
  --network container:mycontainer \
  nicolaka/netshoot

# 常用工具:
# ping, traceroute, nslookup, dig
# tcpdump, tshark
# netstat, ss, ip, route
# curl, wget
# iperf3

16.5.4 故障排查脚本

#!/bin/bash
# docker-network-debug.sh

CONTAINER=$1
if [ -z "$CONTAINER" ]; then
  echo "Usage: $0 <container>"
  exit 1
fi

echo "=== Docker Network Debug ==="

echo "1. Container Network Settings:"
docker inspect $CONTAINER --format '{{json .NetworkSettings.Networks}}' | jq

echo -e "\n2. Container DNS:"
docker exec $CONTAINER cat /etc/resolv.conf

echo -e "\n3. Container Routes:"
docker exec $CONTAINER ip route

echo -e "\n4. Ping Gateway:"
GW=$(docker exec $CONTAINER ip route | awk '/default/ {print $3}')
docker exec $CONTAINER ping -c 2 $GW

echo -e "\n5. Ping Internet:"
docker exec $CONTAINER ping -c 2 8.8.8.8

echo -e "\n6. DNS Lookup:"
docker exec $CONTAINER nslookup google.com

echo -e "\n7. Host iptables (docker):"
sudo iptables -t nat -L -n | grep docker

echo -e "\n=== Debug Complete ==="

16.6 网络性能与优化

16.6.1 网络模式性能对比

性能对比(一般情况):
Host > Macvlan ≈ IPvlan > Bridge > Overlay

- Host:无虚拟层
- Macvlan/IPvlan:二层直连
- Bridge:NAT + bridge
- Overlay:VXLAN封装,有额外开销

16.6.2 调优建议

# 1. 调整MTU(避免分片)
docker network create \
  --opt com.docker.network.driver.mtu=1450 \
  mynet

# 2. 使用多队列网卡
ethtool -L eth0 combined 8

# 3. 调整内核参数
sudo sysctl -w net.core.rmem_max=16777216
sudo sysctl -w net.core.wmem_max=16777216
sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sudo sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"

16.7 实战案例

16.7.1 真实IP容器部署(Macvlan)

# 创建macvlan网络
docker network create \
  -d macvlan \
  --subnet=192.168.10.0/24 \
  --gateway=192.168.10.1 \
  -o parent=eth0 \
  prod-macvlan

# 部署多个容器,直接暴露到局域网
docker run -d --name app1 --network prod-macvlan --ip 192.168.10.101 myapp
docker run -d --name app2 --network prod-macvlan --ip 192.168.10.102 myapp

# 局域网可直接访问
curl http://192.168.10.101

16.7.2 跨主机服务发现(Overlay)

# 创建overlay网络
docker network create -d overlay --attachable myoverlay

# 在不同节点运行容器
# Node A:
docker run -d --name api --network myoverlay myapi

# Node B:
docker run -d --name web --network myoverlay nginx

# Node B访问Node A容器
docker exec web curl http://api:8080

16.7.3 多网络隔离架构

# docker-compose.yml
version: '3.8'

networks:
  public:
  private:
    internal: true

services:
  gateway:
    image: nginx
    networks:
      - public
      - private
    ports:
      - "80:80"

  app:
    image: myapp
    networks:
      - private

  db:
    image: postgres
    networks:
      - private

16.8 小结

通过本章学习,我们掌握了Docker网络进阶知识:

Overlay网络

  • 跨主机容器通信(VXLAN)
  • Swarm模式部署

Macvlan/IPvlan

  • 容器获得真实IP
  • 适合传统应用迁移

网络安全

  • internal网络隔离
  • iptables安全控制

故障排查

  • DNS、路由、iptables诊断
  • 网络调试脚本

性能优化

  • 不同网络模式性能对比
  • MTU与内核调优

网络模式选择建议

需求                          推荐网络
────────────────────────────────────────────
跨主机通信                    Overlay
局域网真实IP                  Macvlan/IPvlan
高性能低延迟                  Host
安全隔离                      Bridge + internal
传统应用迁移                  Macvlan

下一步

在第17章中,我们将学习Docker网络实战与高级管理:

  • 复杂网络拓扑设计
  • 网络负载均衡
  • 服务发现与DNS
  • 网络监控与安全策略

本章思考题

  1. Overlay网络适合什么场景?它依赖哪些端口?
  2. Macvlan和IPvlan的主要区别是什么?
  3. 为什么Macvlan下主机默认不能访问容器?
  4. 如何快速排查容器无法上网的问题?
  5. 生产环境如何选择合适的网络模式?

相关资源

  • Overlay网络:https://docs.docker.com/network/overlay/
  • Macvlan:https://docs.docker.com/network/macvlan/
  • IPvlan:https://docs.docker.com/network/ipvlan/
  • Docker网络安全:https://docs.docker.com/engine/security/
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐