容器网络原理
Docker 网络模型
网络模式
| 模式 |
说明 |
使用场景 |
| bridge |
默认模式,通过网桥实现容器间通信 |
单机多容器通信 |
| host |
容器直接使用宿主机网络栈 |
性能敏感场景 |
| none |
无网络 |
安全隔离 |
| overlay |
跨主机容器网络 |
Docker Swarm 集群 |
| macvlan |
容器分配 MAC 地址 |
需要直接接入物理网络 |
Bridge 模式工作原理
宿主机
┌─────────────────────────────────────┐
│ docker0 (虚拟网桥, 172.17.0.1/16) │
│ ┌──────────┐ ┌──────────┐ │
│ │ 容器 A │ │ 容器 B │ │
│ │ eth0 │ │ eth0 │ │
│ │ 172.17. │ │ 172.17. │ │
│ │ 0.2 │ │ 0.3 │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ └─────┬───────┘ │
│ │ veth pair │
│ iptables MASQUERADE │
│ (容器 → 外网) │
└─────────────────────────────────────┘
网络通信
# 容器间通信(同一 bridge)
# 通过 IP 或 --link/自定义网络名称
# 容器访问外网
# 通过 iptables MASQUERADE(SNAT)
# 外网访问容器
# 通过 -p 端口映射(DNAT)
CNI 插件架构
CNI (Container Network Interface) 是 Kubernetes 的网络接口标准。
CNI 配置
{
"cniVersion": "1.0.0",
"name": "my-network",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{ "subnet": "10.22.0.0/16" }]
],
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}
常见 CNI 插件
| 插件 |
特点 |
适用场景 |
| Flannel |
简单 Overlay 网络 |
小型集群 |
| Calico |
BGP 路由,支持 NetworkPolicy |
大规模生产集群 |
| Cilium |
eBPF 技术,高性能 |
云原生网络 |
| Weave |
加密通信 |
跨区域集群 |
| Canal |
Flannel + Calico 组合 |
需要 NetworkPolicy |
Kubernetes 网络模型
核心要求
- 所有 Pod 可以不使用 NAT 直接通信
- 所有 Node 可以不使用 NAT 直接与 Pod 通信
- Pod 看到的 IP 地址与其他组件看到的完全相同
Pod 网络
# 每个 Pod 拥有独立 IP
# Pod 内容器共享网络命名空间
apiVersion: v1
kind: Pod
metadata:
name: multi-container
spec:
containers:
- name: app
image: nginx
- name: sidecar
image: fluentd
# 与 app 容器共享 localhost
Service 网络
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 8080
# kube-proxy 维护 iptables/IPVS 规则
# ClusterIP 是虚拟 IP,仅在集群内可达
网络策略
# 默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
# 允许特定来源访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- port: 8080
容器网络隔离
网络命名空间
# 创建独立的网络命名空间
ip netns add test-ns
# 创建 veth pair
ip link add veth0 type veth peer name veth1
# 将一端移入命名空间
ip link set veth1 netns test-ns
# 配置命名空间内的网络
ip netns exec test-ns ip addr add 10.0.0.2/24 dev veth1
ip netns exec test-ns ip link set veth1 up
iptables 规则
# Docker 创建的 NAT 规则
# 容器出站 SNAT
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
# 端口映射 DNAT
iptables -t nat -A DOCKER ! -i docker0 -p tcp --dport 8080 \
-j DNAT --to-destination 172.17.0.2:80
# 容器间隔离
iptables -I FORWARD -s 172.17.0.2 -d 172.17.0.3 -j DROP
性能调优
网络性能对比
| 模式 |
延迟 |
吞吐量 |
CPU 开销 |
| Host |
低 |
高 |
低 |
| Bridge |
中 |
中高 |
中 |
| Overlay (VXLAN) |
高 |
中 |
高 |
| Macvlan |
低 |
高 |
低 |
| SR-IOV |
最低 |
最高 |
最低 |
优化建议
- 调整内核参数
# sysctl 优化
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
- 使用性能更优的网络插件
# Calico 使用 BGP 直接路由,性能优于 VXLAN
# Cilium 使用 eBPF,数据路径更短
- CPU 亲和性
# 将网络中断绑定到特定 CPU
echo 2 > /proc/irq/<IRQ>/smp_affinity
总结
容器网络涉及网络命名空间、虚拟网桥、CNI 插件等多个层次。理解 Docker 的 bridge/host/overlay 模式以及 Kubernetes 的 Pod 网络模型,有助于在生产环境中做出合理的网络架构选择。对于性能敏感场景,优先考虑 host 模式或 macvlan/SR-IOV;对于多租户场景,合理配置 NetworkPolicy 实现网络隔离。