第16章 Docker网络进阶
在第15章中,我们掌握了Docker网络基础。本章将深入学习高级网络能力,包括Overlay跨主机通信、Macvlan/IPvlan、网络策略、安全加固和故障排查。
·
在第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
- 网络监控与安全策略
本章思考题:
- Overlay网络适合什么场景?它依赖哪些端口?
- Macvlan和IPvlan的主要区别是什么?
- 为什么Macvlan下主机默认不能访问容器?
- 如何快速排查容器无法上网的问题?
- 生产环境如何选择合适的网络模式?
相关资源:
- 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/
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)