十三、Docker容器网络与通信原理深度解析-1-docker-container-network-model-deep-dive
Docker 容器网络模型深度解析:从 Linux 内核到生产实践的网络架构完整指南
作者:云原生架构师
技术栈:Docker, Linux Kernel, Network Namespace, veth pair, iptables, Bridge
难度等级:★★★★★(专家级)
预计阅读时间:100 分钟
目录
- 引言:容器网络的复杂性与挑战
- Linux 网络命名空间深度解析
- Docker 默认网络模型架构
- 容器访问外网的完整流程
- 外网访问容器的完整流程
- iptables 规则详解
- Docker 四种网络模型
- 容器间通信机制
- 网络性能优化
- 故障排查实战
- 生产环境最佳实践
- 总结与前沿技术
1. 引言:容器网络的复杂性与挑战
1.1 容器网络的三大核心问题
问题 1:隔离性
如何实现容器间的网络隔离?
- 每个容器独立的 IP 地址
- 每个容器独立的端口空间
- 每个容器独立的路由表
- 每个容器独立的防火墙规则
技术实现:
- Network Namespace(网络命名空间)
- 独立的网络设备(eth0, lo)
- 独立的协议栈
问题 2:连通性
如何实现容器与外部通信?
- 容器访问外网(出站流量)
- 外网访问容器(入站流量)
- 容器间通信(横向流量)
- 跨主机容器通信(Overlay 网络)
技术实现:
- NAT(网络地址转换)
- 端口映射
- 网桥(Bridge)
- VXLAN 隧道
问题 3:性能
如何保证网络性能?
- 减少 NAT 转换次数
- 减少数据包复制
- 利用内核旁路技术
- 优化 MTU 设置
性能指标:
- 吞吐量:10 Gbps+
- 延迟:<0.1ms
- CPU 占用:<10%
1.2 Docker 网络架构演进
┌─────────────────────────────────────────────────────┐
│ Docker 网络架构演进 │
├─────────────────────────────────────────────────────┤
│ 2013: Docker 0.1 │
│ - 使用网桥 + NAT │
│ - 简单的端口映射 │
│ - 无网络隔离 │
│ │
│ 2014: Docker 0.7 │
│ - 引入 Network Namespace │
│ - 容器网络隔离 │
│ - veth pair 实现 │
│ │
│ 2015: Docker 1.9 │
│ - 引入 Docker Network │
│ - 支持多种网络驱动 │
│ - 支持用户自定义网络 │
│ │
│ 2016: Docker 1.12 │
│ - 引入 Overlay 网络 │
│ - 支持跨主机通信 │
│ - 内置 DNS 服务 │
│ │
│ 2018: Docker 18.06 │
│ - 引入 eBPF 网络加速 │
│ - 支持 IPvLAN │
│ - 更好的性能优化 │
└─────────────────────────────────────────────────────┘
2. Linux 网络命名空间深度解析
2.1 什么是 Network Namespace
技术定义:
Network Namespace = 独立的网络协议栈
包含:
├── 网络设备(eth0, lo, ...)
├── IP 地址和子网掩码
├── 路由表
├── 防火墙规则(iptables)
├── 套接字(sockets)
└── /proc/net 目录
命名空间隔离效果:
宿主机 Network Namespace:
┌─────────────────────────────────────┐
│ eth0: 192.168.1.100/24 │
│ docker0: 172.17.0.1/16 │
│ 路由表: │
│ default via 192.168.1.1 │
│ 172.17.0.0/16 dev docker0 │
│ iptables 规则 │
└─────────────────────────────────────┘
容器 Network Namespace:
┌─────────────────────────────────────┐
│ eth0: 172.17.0.2/16 │
│ lo: 127.0.0.1 │
│ 路由表: │
│ default via 172.17.0.1 │
│ 127.0.0.0/8 dev lo │
│ 无 iptables 规则 │
└─────────────────────────────────────┘
2.2 创建和操作 Network Namespace
手动创建命名空间:
# 创建新的 Network Namespace
ip netns add ns1
# 查看命名空间
ip netns list
# 输出:ns1
# 在命名空间中执行命令
ip netns exec ns1 ip addr
# 输出:仅显示 lo 接口
# 进入命名空间
ip netns exec ns1 bash
# 现在你在 ns1 的命名空间中
查看进程的命名空间:
# 获取容器 PID
CONTAINER_PID=$(docker inspect -f '{{.State.Pid}}' nginx)
# 查看命名空间
ls -l /proc/$CONTAINER_PID/ns/net
# 输出:net:[4026532460]
# 比较宿主机和容器的命名空间
ls -l /proc/1/ns/net
ls -l /proc/$CONTAINER_PID/ns/net
# 输出不同的 inode,说明在不同命名空间
2.3 veth pair(虚拟网线)
veth pair 原理:
veth pair = 两个虚拟网络接口 + 点对点连接
特点:
1. 成对出现(A 和 B)
2. 数据从 A 进,从 B 出
3. 数据从 B 进,从 A 出
4. 可以跨越命名空间
┌─────────────┐ ┌─────────────┐
│ Namespace1 │ │ Namespace2 │
│ │ │ │
│ veth-A │◄───────►│ veth-B │
│ │ │ │
└─────────────┘ └─────────────┘
│ │
容器内 宿主机
创建 veth pair:
# 创建 veth pair
ip link add veth0 type veth peer name veth1
# 查看 veth pair
ip link show
# 输出:
# 3: veth0@if4: <BROADCAST,MULTICAST> ...
# 4: veth1@if3: <BROADCAST,MULTICAST> ...
# 移动 veth1 到另一个命名空间
ip link set veth1 netns ns1
# 现在:
# veth0 在宿主机
# veth1 在 ns1 命名空间
3. Docker 默认网络模型架构
3.1 Docker 网络组件
docker0 网桥:
# 查看 docker0 网桥
ip addr show docker0
# 输出:
# 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
# link/ether 02:42:ac:11:00:01
# inet 172.17.0.1/16 brd 172.17.255.255
# inet6 fe80::42:acff:fe11:1/64 ...
# 功能:
# 1. 连接所有容器
# 2. 分配 IP 地址(172.17.0.0/16)
# 3. 路由转发
# 4. NAT 转换
veth pair 连接:
宿主机:
┌─────────────────────────────────────┐
│ docker0 (172.17.0.1) │
│ │ │
│ veth1234567 │
│ │ │
└───────┼─────────────────────────────┘
│ veth pair
│
┌───────┼─────────────────────────────┐
│ │ 容器 Network Namespace │
│ eth0 (172.17.0.2) │
│ │ │
│ nginx 进程 │
└─────────────────────────────────────┘
3.2 完整的网络架构
3.3 IP 地址分配机制
IPAM(IP Address Management):
# 查看网络配置
docker network inspect bridge
# 输出:
# {
# "Name": "bridge",
# "Driver": "bridge",
# "IPAM": {
# "Driver": "default",
# "Config": [
# {
# "Subnet": "172.17.0.0/16",
# "Gateway": "172.17.0.1"
# }
# ]
# }
# }
IP 分配流程:
4. 容器访问外网的完整流程
4.1 数据包路径详解
容器访问外网(例如访问 8.8.8.8:53):
4.2 逐步详解
步骤 1:容器内发送数据包
# 在容器内执行
docker exec nginx curl -I https://8.8.8.8
# 数据包信息:
# 源 IP: 172.17.0.2
# 源端口:随机(例如 50000)
# 目标 IP: 8.8.8.8
# 目标端口:443
步骤 2:查找路由表
# 容器内路由表
docker exec nginx ip route show
# 输出:
# default via 172.17.0.1 dev eth0
# 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
# 127.0.0.0/8 dev lo scope link
# 匹配默认路由:via 172.17.0.1
步骤 3:ARP 解析网关 MAC 地址
# 查看 ARP 缓存
docker exec nginx arp -a
# 输出:
# ? (172.17.0.1) at 02:42:ac:11:00:01 [ether] on eth0
# 如果没有缓存,发送 ARP 请求:
# "Who has 172.17.0.1? Tell 172.17.0.2"
# docker0 回复:"172.17.0.1 is at 02:42:ac:11:00:01"
步骤 4-5:通过 veth pair 到达 docker0
数据包到达 docker0 网桥:
┌─────────────────────────────────────┐
│ docker0 网桥 │
│ ┌─────────────────────────────┐ │
│ │ 端口 1: veth1234567 │ │ ← 来自容器
│ │ 端口 2: veth7654321 │ │
│ │ 端口 3: eth0 (物理网卡) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
网桥根据 MAC 地址表转发到物理接口
步骤 6-8:iptables NAT 转换
# 查看 NAT 规则
iptables -t nat -L POSTROUTING -n -v
# 输出:
# Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
# pkts bytes target prot opt in out source destination
# 1000 80000 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
# MASQUERADE 规则:
# - 源地址:172.17.0.2 → 192.168.1.100
# - 源端口:50000 → 随机端口(例如 60000)
# - 目标地址:8.8.8.8(不变)
# - 目标端口:443(不变)
步骤 9:发送到外部网络
# 物理网卡发送数据包
tcpdump -i eth0 -n host 8.8.8.8
# 输出:
# 192.168.1.100.60000 > 8.8.8.8.443: Flags [S], seq 1234567890
4.3 完整的数据包变化
数据包在传输过程中的变化:
容器内:
┌─────────────────────────────────────┐
│ 源 IP: 172.17.0.2 │
│ 源端口:50000 │
│ 目标 IP: 8.8.8.8 │
│ 目标端口:443 │
└─────────────────────────────────────┘
│
│ 经过 MASQUERADE
▼
宿主机外网:
┌─────────────────────────────────────┐
│ 源 IP: 192.168.1.100 │ ← 变化
│ 源端口:60000 │ ← 变化
│ 目标 IP: 8.8.8.8 │ ← 不变
│ 目标端口:443 │ ← 不变
└─────────────────────────────────────┘
5. 外网访问容器的完整流程
5.1 端口映射配置
Docker 端口映射:
docker run -d -p 8080:80 --name nginx nginx:alpine
# 参数说明:
# -p 8080:80
# 宿主机端口:8080
# 容器端口:80
查看端口映射:
# 查看端口映射
docker port nginx
# 输出:
# 80/tcp -> 0.0.0.0:8080
# 查看 iptables 规则
iptables -t nat -L DOCKER -n -v
# 输出:
# Chain DOCKER (1 references)
# pkts bytes target prot opt in out source destination
# 100 6000 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
5.2 外网访问容器的数据包路径
5.3 逐步详解
步骤 1:外部用户发送请求
# 外部用户执行
curl http://192.168.1.100:8080
# 数据包信息:
# 源 IP: 192.168.1.50
# 源端口:45000
# 目标 IP: 192.168.1.100
# 目标端口:8080
步骤 2-3:PREROUTING 链 DNAT 转换
# 查看 DNAT 规则
iptables -t nat -L PREROUTING -n -v
# 输出:
# Chain PREROUTING (policy ACCEPT)
# pkts bytes target prot opt in out source destination
# 1000 80000 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
# DOCKER 链规则:
iptables -t nat -L DOCKER -n -v
# 输出:
# Chain DOCKER (1 references)
# pkts bytes target prot opt in out source destination
# 100 6000 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
# DNAT 转换:
# - 目标 IP: 192.168.1.100 → 172.17.0.2
# - 目标端口:8080 → 80
# - 源 IP: 192.168.1.50(不变)
# - 源端口:45000(不变)
步骤 4-5:转发到容器
数据包到达 docker0 网桥:
┌─────────────────────────────────────┐
│ docker0 网桥 │
│ ┌─────────────────────────────┐ │
│ │ 端口 1: veth1234567 │ │ → 到容器
│ │ 端口 2: veth7654321 │ │
│ │ 端口 3: eth0 (物理网卡) │ │ ← 来自外部
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
网桥根据目标 IP(172.17.0.2)转发到对应端口
步骤 6:容器内 Nginx 处理请求
# 容器内 Nginx 接收请求
docker exec nginx tail -f /var/log/nginx/access.log
# 输出:
# 192.168.1.50 - - [11/Mar/2026:10:00:00 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.68.0"
# 注意:Nginx 看到的是真实客户端 IP(192.168.1.50)
步骤 7-10:响应数据包返回
# 容器发送响应
# 源 IP: 172.17.0.2
# 源端口:80
# 目标 IP: 192.168.1.50
# 目标端口:45000
# 经过 docker0 转发到 POSTROUTING 链
# SNAT 转换(反向 NAT):
# - 源 IP: 172.17.0.2 → 192.168.1.100
# - 源端口:80 → 8080
# 返回外部用户
5.4 完整的数据包变化
入站数据包变化:
外部网络:
┌─────────────────────────────────────┐
│ 源 IP: 192.168.1.50 │
│ 源端口:45000 │
│ 目标 IP: 192.168.1.100 │ ← 宿主机 IP
│ 目标端口:8080 │ ← 映射端口
└─────────────────────────────────────┘
│
│ 经过 DNAT
▼
容器内:
┌─────────────────────────────────────┐
│ 源 IP: 192.168.1.50 │ ← 不变
│ 源端口:45000 │ ← 不变
│ 目标 IP: 172.17.0.2 │ ← 变化
│ 目标端口:80 │ ← 变化
└─────────────────────────────────────┘
6. iptables 规则详解
6.1 Docker 创建的 iptables 链
完整的 iptables 结构:
# 查看 NAT 表
iptables -t nat -L -n -v
# 输出:
# Chain PREROUTING (policy ACCEPT)
# target prot opt source destination
# DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
# Chain INPUT (policy ACCEPT)
# target prot opt source destination
# Chain OUTPUT (policy ACCEPT)
# target prot opt source destination
# DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
# Chain POSTROUTING (policy ACCEPT)
# target prot opt source destination
# MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
# MASQUERADE all -- * !br-xxx 172.18.0.0/16 0.0.0.0/0
# Chain DOCKER (2 references)
# target prot opt source destination
# DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
# DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.3:3306
6.2 NAT 规则详解
PREROUTING 链:
# PREROUTING 链规则
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
# 说明:
# -m addrtype: 匹配地址类型
# --dst-type LOCAL: 目标地址是本地地址
# -j DOCKER: 跳转到 DOCKER 链
DOCKER 链:
# DOCKER 链规则(端口映射)
-A DOCKER -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
# 说明:
# -p tcp: TCP 协议
# -m tcp --dport 8080: 目标端口 8080
# -j DNAT: 目标 NAT
# --to-destination 172.17.0.2:80: 转发到容器
POSTROUTING 链:
# POSTROUTING 链规则(容器访问外网)
-A POSTROUTING -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE
# 说明:
# -s 172.17.0.0/16: 源地址是容器网段
# ! -d 172.17.0.0/16: 目标地址不是容器网段
# -j MASQUERADE: 源地址伪装(动态 NAT)
6.3 规则匹配流程
容器访问外网的规则匹配:
数据包:172.17.0.2:50000 → 8.8.8.8:443
1. PREROUTING 链
- 不匹配(目标不是本地地址)
- 跳过
2. FORWARD 链
- 匹配:-s 172.17.0.0/16
- 允许转发
3. POSTROUTING 链
- 匹配:-s 172.17.0.0/16 ! -d 172.17.0.0/16
- 执行 MASQUERADE
- 源地址变为 192.168.1.100
外网访问容器的规则匹配:
数据包:192.168.1.50:45000 → 192.168.1.100:8080
1. PREROUTING 链
- 匹配:--dst-type LOCAL
- 跳转到 DOCKER 链
2. DOCKER 链
- 匹配:--dport 8080
- 执行 DNAT
- 目标地址变为 172.17.0.2:80
3. FORWARD 链
- 匹配:-d 172.17.0.2
- 允许转发
4. 容器接收数据包
7. Docker 四种网络模型
7.1 Bridge 模式(默认)
架构:
┌─────────────────────────────────────────────────────┐
│ Bridge 网络模型 │
├─────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Container1 │ │ Container2 │ │ Container3 │ │
│ │ 172.17.0.2 │ │ 172.17.0.3 │ │ 172.17.0.4 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ docker0 Bridge │ │
│ │ 172.17.0.1 │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ NAT (iptables) │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ 物理网卡 eth0 │ │
│ │ 192.168.1.100 │ │
│ └───────────────────────┘ │
└─────────────────────────────────────────────────────┘
特点:
- 使用网桥连接容器
- NAT 转换访问外网
- 端口映射访问容器
- 容器间直接通信
使用场景:
- 单机部署
- 开发环境
- 测试环境
7.2 Host 模式
架构:
┌─────────────────────────────────────────────────────┐
│ Host 网络模型 │
├─────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Container1 │ │ Container2 │ │ Container3 │ │
│ │ 直接使用 │ │ 直接使用 │ │ 直接使用 │ │
│ │ 宿主机网络 │ │ 宿主机网络 │ │ 宿主机网络 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ 物理网卡 eth0 │ │
│ │ 192.168.1.100 │ │
│ └───────────────────────┘ │
└─────────────────────────────────────────────────────┘
注意:容器共享宿主机网络栈,无隔离
配置:
docker run -d --network host nginx:alpine
特点:
- 无 Network Namespace
- 直接使用宿主机网络
- 无 NAT 转换
- 性能最好
使用场景:
- 高性能需求
- 需要绑定低端口
- 信任的容器
7.3 None 模式
架构:
┌─────────────────────────────────────────────────────┐
│ None 网络模型 │
├─────────────────────────────────────────────────────┤
│ ┌─────────────┐ │
│ │ Container │ │
│ │ 仅 lo 接口 │ │
│ │ 127.0.0.1 │ │
│ └─────────────┘ │
│ │
│ 无外部网络连接 │
└─────────────────────────────────────────────────────┘
配置:
docker run -d --network none nginx:alpine
特点:
- 仅 loopback 接口
- 完全隔离
- 最安全
使用场景:
- 完全隔离的容器
- 批量处理任务
- 安全敏感应用
7.4 Container 模式
架构:
┌─────────────────────────────────────────────────────┐
│ Container 网络模型 │
├─────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Container1 │ │ Container2 │ │
│ │ (主容器) │◄──┤ (共享) │ │
│ │ eth0 │ │ 使用 C1 网络 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
配置:
# 创建主容器
docker run -d --name container1 nginx:alpine
# 创建共享容器
docker run -d --name container2 --network container:container1 busybox
特点:
- 共享 Network Namespace
- 相同的 IP、端口、路由表
- 通过 localhost 通信
使用场景:
- Sidecar 模式
- 服务网格(Service Mesh)
- 日志收集
8. 容器间通信机制
8.1 同一网桥下的容器通信
直接通信(无需 NAT):
# 容器 1: 172.17.0.2
# 容器 2: 172.17.0.3
# 容器 1 访问容器 2
docker exec container1 curl http://172.17.0.3:80
数据包路径:
容器 1 (172.17.0.2)
│
│ veth1234567
│
▼
docker0 网桥
│
│ veth7654321
│
▼
容器 2 (172.17.0.3)
不经过 NAT,直接转发
性能:
- 延迟:<0.1ms
- 吞吐量:接近线速
- CPU 占用:低
8.2 使用容器名通信
Docker 内置 DNS:
# 创建自定义网络
docker network create my-network
# 运行容器
docker run -d --name web --network my-network nginx
docker run -d --name db --network my-network mysql
# 通过容器名访问
docker exec web curl http://db:3306
DNS 解析过程:
8.3 跨主机容器通信
Overlay 网络:
# 初始化 Swarm
docker swarm init
# 创建 Overlay 网络
docker network create \
--driver overlay \
--subnet 10.0.0.0/24 \
my-overlay
# 在不同节点上运行容器
# Node1: docker run --network my-overlay nginx
# Node2: docker run --network my-overlay nginx
# 跨主机通信
docker exec node1_nginx ping node2_nginx
VXLAN 隧道:
Host1 (192.168.1.10) Host2 (192.168.1.20)
│ │
│ Container1 (10.0.0.2) │ Container2 (10.0.0.3)
│ │ │ │
│ │ 1. 发送数据包 │ │
│ │────────────────────────────────►│ │
│ │ 目标:10.0.0.3 │ │
│ │ │ │
│ ┌────▼────┐ │ │
│ │ VXLAN0 │ │ │
│ │ VNI:123 │ │ │
│ └────┬────┘ │ │
│ │ 2. VXLAN 封装 │ │
│ │ 外层 IP: 192.168.1.20 │ │
│ │ 外层 UDP: 4789 │ │
│ │────────────────────────────────►│ │
│ │ │ ┌────▼────┐
│ │ │ │ VXLAN0 │
│ │ │ │ VNI:123 │
│ │ │ └────┬────┘
│ │ │ │
│ │ │ │ 3. 解封装
│ │ │ │▼
│ │ │ │Container2
9. 网络性能优化
9.1 MTU 优化
MTU 问题:
# 查看 MTU
ip link show docker0
# 输出:
# 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
# link/ether 02:42:ac:11:00:01
# mtu 1500
# 问题:
# 如果物理网络 MTU < 1500
# 数据包需要分片,性能下降
优化方案:
# 创建网络时指定 MTU
docker network create \
--opt com.docker.network.driver.mtu=1450 \
my-network
# 或者修改 daemon.json
{
"mtu": 1450
}
9.2 使用 Host 网络提升性能
性能对比:
Bridge 模式:
- 延迟:0.3ms
- 吞吐量:9.5 Gbps
- CPU 占用:15%
Host 模式:
- 延迟:0.1ms
- 吞吐量:10 Gbps
- CPU 占用:8%
性能提升:
- 延迟:减少 67%
- 吞吐量:提升 5%
- CPU:减少 47%
9.3 使用 IPvlan
IPvlan 配置:
# 创建 IPvlan 网络
docker network create -d ipvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
ipvlan-net
# 运行容器
docker run -d --network ipvlan-net --ip 192.168.1.100 nginx
优势:
- 直接连接物理网络
- 无 NAT 转换
- 性能接近原生
10. 故障排查实战
10.1 容器无法访问外网
排查步骤:
# 1. 检查容器网络配置
docker exec container ip addr show
docker exec container ip route show
# 2. 测试连通性
docker exec container ping 8.8.8.8
# 3. 检查 DNS
docker exec container nslookup google.com
# 4. 查看 iptables 规则
iptables -t nat -L POSTROUTING -n -v
# 5. 抓包分析
docker exec container tcpdump -i eth0 -n icmp
常见问题:
# 问题 1:iptables 规则丢失
# 解决:重启 Docker
systemctl restart docker
# 问题 2:DNS 配置错误
# 解决:修改 daemon.json
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
# 问题 3:路由问题
# 解决:检查路由表
ip route show
10.2 端口映射无法访问
排查步骤:
# 1. 检查端口映射
docker port container
# 2. 查看 iptables 规则
iptables -t nat -L DOCKER -n -v
# 3. 检查防火墙
firewall-cmd --list-all
# 4. 查看端口占用
netstat -tlnp | grep 8080
# 5. 测试本地访问
curl http://localhost:8080
常见问题:
# 问题 1:防火墙阻止
# 解决:开放端口
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
# 问题 2:端口被占用
# 解决:更换端口
docker run -d -p 8081:80 nginx
# 问题 3:iptables 规则错误
# 解决:重启 Docker
systemctl restart docker
11. 生产环境最佳实践
11.1 网络隔离
多网络隔离:
# docker-compose.yml
services:
web:
networks:
- frontend
- backend
api:
networks:
- backend
- database
db:
networks:
- database
networks:
frontend:
backend:
database:
网络访问控制:
┌─────────────────────────────────────────────────────┐
│ 网络隔离策略 │
├─────────────────────────────────────────────────────┤
│ Frontend Network │
│ - Web 容器 │
│ - 可访问:Internet, Backend │
│ │
│ Backend Network │
│ - API 容器 │
│ - 可访问:Frontend, Database │
│ │
│ Database Network │
│ - DB 容器 │
│ - 可访问:Backend only │
└─────────────────────────────────────────────────────┘
11.2 网络监控
Prometheus 监控:
# 监控容器网络指标
- container_network_receive_bytes_total
- container_network_transmit_bytes_total
- container_network_receive_errors_total
- container_network_transmit_errors_total
Grafana 仪表盘:
网络监控仪表盘:
- 接收带宽(bps)
- 发送带宽(bps)
- 接收错误包数
- 发送错误包数
- 网络延迟
12. 总结与前沿技术
12.1 核心技术要点
-
Network Namespace:
- 网络隔离的基础
- 独立的设备、IP、路由表
-
veth pair:
- 连接不同命名空间
- 点对点通信
-
docker0 网桥:
- 连接所有容器
- 转发数据包
-
iptables NAT:
- PREROUTING:DNAT(入站)
- POSTROUTING:MASQUERADE(出站)
12.2 前沿技术
-
eBPF 网络加速:
- 内核级数据包处理
- 性能提升 10 倍
-
Cilium:
- 基于 eBPF
- 服务网格
- 网络安全策略
-
Macvlan/IPvlan:
- 直接连接物理网络
- 更好的性能
版权声明:本文原创,转载请注明出处
参考资料:
- Docker 官方文档
- Linux Kernel 网络文档
- iptables 官方文档
- CNCF 云原生网络报告
如果本文对您有帮助,欢迎点赞、收藏、转发!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)