Add advanced networking

This commit is contained in:
baohua
2026-03-05 19:39:42 -08:00
parent 9fcaff6673
commit 17517e26b7
3 changed files with 710 additions and 11 deletions

View File

@@ -0,0 +1,709 @@
## 9.7 容器网络高级特性
深入探讨容器网络的核心机制Overlay 网络CNI 插件生态容器 DNS 解析网络策略等高级特性为生产级别的网络架构打下坚实基础
### 9.7.1 Overlay 网络原理与配置
Overlay 网络在现有网络基础上建立虚拟网络允许容器跨宿主机通信它是 Kubernetes Swarm 模式的基础
#### Overlay 网络工作原理
Overlay 网络通过隧道封装技术通常是 VXLAN将容器网络流量封装在宿主机物理网络的 UDP 数据包中传输
```
容器 A (192.168.0.2)
veth 对
br-net (网桥)
Docker 引擎 (VXLAN 封装)
物理网络 (172.16.0.0/24)
Docker 引擎 (VXLAN 解封装)
br-net (网桥)
veth 对
容器 B (192.168.0.3,不同宿主机)
```
#### 创建和使用 Overlay 网络
**Docker Swarm 模式下的 Overlay 网络**
```bash
# 初始化 Swarm创建集群
docker swarm init
# 创建 overlay 网络
docker network create --driver overlay \
--subnet 192.168.0.0/24 \
--opt com.docker.network.driver.mtu=1450 \
my-overlay-net
# 验证网络创建
docker network ls
docker network inspect my-overlay-net
# 在 Swarm 服务中使用 overlay 网络
docker service create --name web \
--network my-overlay-net \
--replicas 3 \
nginx:latest
# 验证服务跨节点通信
docker service ps web
```
**单机 Overlay 网络模拟Linux 容器**
```bash
# 创建自定义 overlay 网络
docker network create --driver overlay custom-overlay
# 创建两个容器
docker run -d --name container1 --network custom-overlay nginx:latest
docker run -d --name container2 --network custom-overlay nginx:latest
# 测试跨容器通信
docker exec container1 ping container2
docker exec container1 curl http://container2
# 检查网络配置
docker network inspect custom-overlay
```
#### Overlay 网络性能优化
```bash
# 调整 MTUMaximum Transmission Unit避免分片
# VXLAN 开销 50 字节,物理 MTU 1500建议设置为 1450
docker network create --driver overlay \
--opt com.docker.network.driver.mtu=1450 \
optimized-overlay
# 启用 IP 地址管理IPAM自定义
docker network create --driver overlay \
--subnet 10.0.9.0/24 \
--aux-address "my-router=10.0.9.2" \
my-custom-overlay
# 在 Compose 中使用 overlay 网络
version: '3.9'
services:
web:
image: nginx
networks:
- backend
db:
image: postgres
networks:
- backend
networks:
backend:
driver: overlay
driver_opts:
com.docker.network.driver.mtu: 1450
```
### 9.7.2 CNI 插件生态概览
容器网络接口CNI是容器编排平台尤其是 Kubernetes的标准化网络接口不同的 CNI 插件提供不同的网络能力
#### 主流 CNI 插件对比
**Calico - 基于 BGP 的网络**
Calico 使用 BGP 协议进行路由支持网络策略和 eBPF 加速
```yaml
# Kubernetes 中安装 Calico
apiVersion: v1
kind: ConfigMap
metadata:
name: calico-config
namespace: kube-system
data:
cni_network_config: |
{
"name": "k8s-pod-network",
"cniVersion": "0.4.0",
"plugins": [
{
"type": "calico",
"datastore_type": "kubernetes",
"mtu": 1450,
"ipam": {
"type": "calico-ipam"
}
},
{
"type": "portmap",
"snat": true,
"capabilities": {"portMappings": true}
}
]
}
```
**Flannel - 简单可靠的 Overlay**
Flannel 提供简单的 overlay 网络实现适合小到中等规模的集群
```bash
# 安装 Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 配置 Flannel 后端VXLAN、UDP、AWS VPC 等)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
EOF
```
**Cilium - eBPF 驱动的先进网络**
Cilium 使用 eBPF 在内核级别实现网络策略和可观测性性能优异
```bash
# 安装 Cilium
helm repo add cilium https://helm.cilium.io
helm install cilium cilium/cilium \
--namespace kube-system \
--set image.tag=v1.14.0 \
--set operator.replicas=1
# 启用 Hubble可观测性
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set hubble.enabled=true \
--set hubble.ui.enabled=true
```
**Weave - 跨主机网络通信**
Weave 提供简单的跨主机通信支持加密和多播
```bash
# Docker 中使用 Weave 网络
docker run -d --name weave \
--net=host \
--cap-add=NET_ADMIN \
--cap-add=SYS_PTRACE \
ghcr.io/weaveworks/weave:latest
# 连接到 Weave 网络
docker run -d --network weave --name web nginx:latest
```
**CNI 插件对比表**
| 特性 | Calico | Flannel | Cilium | Weave |
|------|--------|---------|--------|-------|
| 路由方式 | BGP | VXLAN/UDP | eBPF | VxLAN |
| 网络策略 | | | (L3-L7) | |
| 性能 | | | | |
| 可观测性 | | | | |
| 学习曲线 | | | | |
| 生产就绪 | | | | |
### 9.7.3 容器 DNS 解析机制
Docker 内置 DNS 服务器 DNS 解析涉及多个层面的配置
#### DNS 解析流程
```
容器应用 (dig www.example.com)
容器内 /etc/resolv.conf (127.0.0.11:53)
Docker 内嵌 DNS 服务器 (127.0.0.11)
用户自定义 DNS 或宿主机 /etc/resolv.conf
外部 DNS 服务器 (8.8.8.8 等)
DNS 响应 → 容器缓存 → 应用
```
#### 配置容器 DNS
**在运行时指定 DNS**
```bash
# 单个容器
docker run -d \
--dns 8.8.8.8 \
--dns 1.1.1.1 \
--dns-search example.com \
nginx:latest
# DNS 选项
docker run -d \
--dns-option ndots:2 \
--dns-option timeout:1 \
--dns-option attempts:3 \
nginx:latest
# 查看容器 DNS 配置
docker exec <container_id> cat /etc/resolv.conf
```
**Docker Compose DNS 配置**
```yaml
version: '3.9'
services:
web:
image: nginx
dns:
- 8.8.8.8
- 1.1.1.1
dns_search:
- example.com
- local
db:
image: postgres
networks:
- backend
hostname: postgres-db
networks:
backend:
driver: bridge
# 容器内 /etc/resolv.conf 将被自动配置
# search example.com local
# nameserver 8.8.8.8
# nameserver 1.1.1.1
```
**Docker 守护进程级别配置**
```json
{
"dns": ["8.8.8.8", "1.1.1.1"],
"dns-search": ["example.com"],
"insecure-registries": [],
"registry-mirrors": ["https://mirror.example.com"]
}
```
#### 自定义服务发现Service Discovery
**使用 Docker 内建 DNS 的服务发现**
```bash
# 创建自定义网络
docker network create mynet
# 运行服务
docker run -d --name web --network mynet nginx:latest
docker run -d --name db --network mynet postgres:latest
# 在其他容器中通过服务名访问
docker run -it --network mynet busybox sh
# ping web # 自动解析到 web 容器 IP
# ping db # 自动解析到 db 容器 IP
```
**Compose 服务名自动发现**
```yaml
version: '3.9'
services:
frontend:
image: nginx
depends_on:
- backend
environment:
BACKEND_URL: http://backend:8080
backend:
image: myapp
depends_on:
- database
database:
image: postgres
environment:
POSTGRES_DB: mydb
# frontend 容器可以直接访问 http://backend:8080
# backend 容器可以直接访问 postgres://database:5432
```
#### DNS 性能优化
```bash
# 检查 DNS 延迟
time docker exec <container> nslookup www.example.com
# 优化 DNS 解析
docker run -d \
--dns 127.0.0.1 \ # 使用本地缓存 DNS (Dnsmasq)
nginx:latest
# 在 Kubernetes 中优化
kubectl patch deployment -n kube-system coredns --patch '{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "coredns",
"resources": {
"limits": {
"memory": "512Mi",
"cpu": "500m"
}
}
}
]
}
}
}
}'
```
### 9.7.4 网络策略NetworkPolicy实践
网络策略定义了容器间的流量控制规则是微服务架构中的安全基础
#### 基本网络策略
**默认拒绝所有入站流量的策略**
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
# 不指定 ingress 规则,表示拒绝所有入站流量
```
**允许特定来源的入站流量**
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
```
**允许出站流量到数据库**
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Egress
egress:
# 允许到数据库的流量
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
# 允许 DNS 查询
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
# 允许到外部 API 的流量
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # 阻止元数据服务
ports:
- protocol: TCP
port: 443
```
#### 微服务网络策略示例
```yaml
---
# 拒绝所有默认
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Frontend 容器策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress
ingress:
# 允许来自 Ingress Controller 的流量
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: ingress-controller
ports:
- protocol: TCP
port: 3000
egress:
# 允许到 API 的流量
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
# 允许 DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# API 容器策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
# 允许到数据库的流量
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
# 允许 DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 数据库容器策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-postgres
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432
```
#### 使用 Calico/Cilium 的高级网络策略
**L7 应用层策略 Cilium 支持**
```yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "api-gateway-policy"
spec:
description: "L7 policy for API gateway"
endpointSelector:
matchLabels:
app: api
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
# 允许 GET /api/users
- method: "GET"
path: "/api/users/.*"
# 允许 POST /api/users 仅从管理员来源
- method: "POST"
path: "/api/users"
sourceIPs:
- "10.0.0.0/8"
```
### 9.7.5 跨主机容器通信方案对比
#### 方案对比表
| 方案 | 隔离性 | 性能 | 复杂度 | 适用场景 |
|------|--------|------|--------|---------|
| 主机网络 | | | | 高性能单主机 |
| Bridge + Host Port | | | | 小规模集群 |
| Overlay (VXLAN) | | | | 跨域通信 |
| BGP (Calico) | | | | 大规模集群 |
| eBPF (Cilium) | | | | 高性能大集群 |
#### 选择建议
```bash
# 1. 开发环境:使用 Bridge 网络
docker network create my-app
docker-compose up # 默认使用 bridge
# 2. 小规模生产(< 50 节点):使用 Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 3. 中等规模50-500 节点):使用 Calico
kubeadm init --pod-network-cidr=192.168.0.0/16
kubectl apply -f https://docs.projectcalico.org/v3.24/manifests/tigera-operator.yaml
# 4. 大规模(> 500 节点)或需要 L7 策略:使用 Cilium
helm install cilium cilium/cilium --namespace kube-system
# 5. 需要多云/跨域:使用 Weave
```
### 9.7.6 网络故障排查
**常见网络问题诊断**
```bash
# 1. 容器无法访问外部网络
docker exec <container> ping 8.8.8.8
docker exec <container> cat /etc/resolv.conf
docker logs <container> | grep -i network
# 2. 容器间无法通信
docker network inspect <network>
docker exec <container1> ping <container2>
# 3. 端口映射失效
docker port <container>
netstat -tlnp | grep <port>
# 4. DNS 解析失败
docker exec <container> nslookup example.com
docker exec <container> cat /etc/hosts
# 5. 网络延迟
docker run --rm --network host iperf3:latest -c <target>
docker exec <container> mtr -r example.com
# 使用 tcpdump 抓包分析
docker run --rm --cap-add NET_ADMIN --network host \
corfr/tcpdump -i eth0 -n "port 80"
```

View File

@@ -39,3 +39,4 @@ graph TD
* [容器互联](9.4_container_linking.md) * [容器互联](9.4_container_linking.md)
* [外部访问容器](9.5_port_mapping.md) * [外部访问容器](9.5_port_mapping.md)
* [网络隔离](9.6_network_isolation.md) * [网络隔离](9.6_network_isolation.md)
* [高级网络配置](9.7_advanced_networking.md)

View File

@@ -1,11 +0,0 @@
DOCKER_VERSION=20.10.0
DOCKER_COMPOSE_VERSION=1.27.4
ETCD_VERSION=3.4.0
KUBERNETES_VERSION=1.14.3
KUBERNETES_DASHBOARD=2.0.0
UBUNTU=18.04
DEBIAN=9
NGINX_VERSION=1.18.x
NODE_VERSION=14.x
PHP_VERSION=7.x
REDIS_VERSION=6.x