第六部分:CNI 与 eBPF 网络深度实践
从传统网络到 eBPF 革命性网络技术的完整实践
目录
- 第8章:Kubernetes 网络深度原理与 CNI 架构全解析
- Flannel VXLAN 原理与实验
- Calico BGP 路由实战
- Cilium eBPF 完整实战
- NetworkPolicy 深度实践
- 实验环境搭建
- 命令速查表
第8章:Kubernetes 网络深度原理与 CNI 架构全解析
8.1 为什么 Kubernetes 网络复杂?
Kubernetes 的网络模型需要同时满足:
| 目标 | 含义 | 实现机制 |
|---|---|---|
| Pod-to-Pod 通信 | 集群内部任何 Pod 能直接通信 | CNI 插件 + Overlay 网络 |
| Pod-to-Service 通信 | 通过虚拟 IP 访问服务 | kube-proxy + iptables/IPVS/eBPF |
| Pod-to-外部网络 | 能访问外网(NAT 转换) | iptables NAT 规则 |
| 外部访问 Pod | NodePort / Ingress / LoadBalancer | Service 类型 + Ingress 控制器 |
因此,K8s 网络是一个多层叠加体系:
Pod 内部网络
→ veth pair
→ Bridge / Overlay
→ Node 网络(eth0)
→ CNI 插件(Flannel/Calico/Cilium)
→ kube-proxy / iptables / IPVS
→ 外部世界
8.2 Linux 网络命名空间与 veth pair 原理
每个容器都有独立的网络命名空间(netns):
# 查看所有 netns
ip netns list
# 进入容器网络命名空间
ip netns exec <ns-name> bash
在容器与宿主机之间通过一对虚拟以太网接口(veth pair)连接:
Container eth0 ↔ vethxxxx ↔ cni0 ↔ eth0
- eth0:容器内部虚拟网卡
- vethXXXX:宿主机端对应网卡
- cni0(或 docker0):宿主机的网桥
- eth0:宿主机真实网卡,连接物理网络
8.3 Pod 网络地址的分配与路由
Pod 启动 → kubelet 调用 CNI → CNI 分配 IP。
以 Flannel 为例:
10.244.0.0/16 # 集群总网段
├── Node A: 10.244.1.0/24
├── Node B: 10.244.2.0/24
└── Node C: 10.244.3.0/24
路由表示例:
ip route show
default via 10.0.0.1 dev eth0
10.244.2.0/24 via 10.0.0.12 dev flannel.1
即:不同节点的 Pod 通过 Overlay 网络互通。
8.4 CNI(Container Network Interface)机制
CNI 是容器网络的标准接口规范,由 CNCF 维护。
8.4.1 工作流程
Pod 创建 →
kubelet 调用 CNI 插件 →
CNI 分配 IP + 创建 veth pair →
写入路由表 + /etc/resolv.conf →
返回 Pod 的网络配置
8.4.2 CNI 插件目录
/opt/cni/bin/
8.4.3 CNI 配置目录
/etc/cni/net.d/
8.4.4 典型配置文件
{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "bridge",
"bridge": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/16"
}
}
Flannel VXLAN 原理与实验
Flannel 工作机制(Overlay 模式)
Flannel 使用 VXLAN 封装实现跨节点通信:
Pod (10.244.1.5)
↓
veth0 → cni0 → flannel.1
↓ VXLAN 封装
eth0 → NodeB → 解封装 → cni0 → Pod (10.244.2.6)
实验1:Flannel VXLAN 部署与配置
#!/bin/bash
# Flannel VXLAN 部署与配置
echo "=== Flannel VXLAN 部署与配置 ==="
# 1. 创建实验集群
kind create cluster --name flannel-test --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
EOF
# 2. 等待集群就绪
kubectl wait --for=condition=Ready node --all --timeout=60s
# 3. 安装 Flannel
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 4. 等待 Flannel 就绪
kubectl wait --for=condition=Ready pod -l app=flannel -n kube-system --timeout=60s
# 5. 查看 Flannel 配置
echo "查看 Flannel 配置:"
kubectl get configmap kube-flannel-cfg -n kube-system -o yaml
# 6. 查看 VXLAN 接口
echo "查看 VXLAN 接口:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "ip link show flannel.1"
# 7. 查看路由表
echo "查看路由表:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "ip route | grep flannel"
# 8. 创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: flannel-test
spec:
replicas: 4
selector:
matchLabels:
app: flannel-test
template:
metadata:
labels:
app: flannel-test
spec:
containers:
- name: test
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 9. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=flannel-test --timeout=60s
# 10. 查看 Pod 分布
echo "查看 Pod 分布:"
kubectl get pods -o wide
echo "Flannel VXLAN 部署完成!"
实验2:VXLAN 封装解封过程详解
#!/bin/bash
# VXLAN 封装解封过程详解
echo "=== VXLAN 封装解封过程详解 ==="
# 1. 获取 Pod IP
POD1_IP=$(kubectl get pod -l app=flannel-test -o jsonpath='{.items[0].status.podIP}')
POD2_IP=$(kubectl get pod -l app=flannel-test -o jsonpath='{.items[1].status.podIP}')
NODE1=$(kubectl get pod -l app=flannel-test -o jsonpath='{.items[0].spec.nodeName}')
NODE2=$(kubectl get pod -l app=flannel-test -o jsonpath='{.items[1].spec.nodeName}')
echo "Pod 1: $POD1_IP on $NODE1"
echo "Pod 2: $POD2_IP on $NODE2"
# 2. 在源节点抓包
echo "在源节点抓包:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "tcpdump -i flannel.1 -n icmp" &
TCPDUMP_PID=$!
# 3. 测试 Pod 间通信
echo "测试 Pod 间通信:"
kubectl exec $(kubectl get pod -l app=flannel-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $POD2_IP
# 4. 停止抓包
kill $TCPDUMP_PID
# 5. 查看 VXLAN 接口统计
echo "查看 VXLAN 接口统计:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "ip -s link show flannel.1"
# 6. 查看 ARP 表
echo "查看 ARP 表:"
kubectl exec $(kubectl get pod -l app=flannel-test -o jsonpath='{.items[0].metadata.name}') -- arp -a
实验3:Flannel 性能测试
#!/bin/bash
# Flannel 性能测试
echo "=== Flannel 性能测试 ==="
# 1. 创建性能测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: iperf-server
spec:
replicas: 1
selector:
matchLabels:
app: iperf-server
template:
metadata:
labels:
app: iperf-server
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["iperf3", "-s"]
ports:
- containerPort: 5201
---
apiVersion: v1
kind: Service
metadata:
name: iperf-server
spec:
selector:
app: iperf-server
ports:
- port: 5201
targetPort: 5201
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: iperf-client
spec:
replicas: 1
selector:
matchLabels:
app: iperf-client
template:
metadata:
labels:
app: iperf-client
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["sh", "-c", "sleep 10 && iperf3 -c iperf-server -t 30"]
EOF
# 2. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=iperf-server --timeout=60s
kubectl wait --for=condition=Ready pod -l app=iperf-client --timeout=60s
# 3. 运行性能测试
echo "运行性能测试:"
kubectl logs -f $(kubectl get pod -l app=iperf-client -o jsonpath='{.items[0].metadata.name}')
# 4. 测试延迟
echo "测试延迟:"
kubectl exec $(kubectl get pod -l app=iperf-client -o jsonpath='{.items[0].metadata.name}') -- ping -c 10 iperf-server
# 5. 清理
kubectl delete deployment iperf-server iperf-client
kubectl delete service iperf-server
Calico BGP 路由实战
Calico 工作机制(BGP 模式)
Calico 不封装数据包,而是直接使用三层路由(L3 BGP)。
原理:
- 每个 Node 都运行 calico-node
- 通过 BGP 广播 Pod CIDR
- 每个 Node 建立路由表 → 直接路由通信
Pod (10.244.1.5)
→ eth0 → NodeA routing table
→ NodeB (10.244.2.6)
实验1:Calico BGP 部署与配置
#!/bin/bash
# Calico BGP 部署与配置
echo "=== Calico BGP 部署与配置 ==="
# 1. 删除 Flannel
kubectl delete -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 2. 安装 Calico
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# 3. 等待 Calico 就绪
kubectl wait --for=condition=Ready pod -l k8s-app=calico-node -n kube-system --timeout=60s
# 4. 查看 Calico 状态
echo "查看 Calico 状态:"
kubectl get pods -n kube-system | grep calico
# 5. 查看 BGP 状态
echo "查看 BGP 状态:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "calicoctl node status"
# 6. 查看路由表
echo "查看路由表:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "ip route | grep calico"
# 7. 创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-test
spec:
replicas: 4
selector:
matchLabels:
app: calico-test
template:
metadata:
labels:
app: calico-test
spec:
containers:
- name: test
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 8. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=calico-test --timeout=60s
# 9. 查看 Pod 分布
echo "查看 Pod 分布:"
kubectl get pods -o wide
echo "Calico BGP 部署完成!"
实验2:BGP Peer 配置与验证
#!/bin/bash
# BGP Peer 配置与验证
echo "=== BGP Peer 配置与验证 ==="
# 1. 查看 BGP 配置
echo "查看 BGP 配置:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "calicoctl node status"
# 2. 查看 BGP 对等体
echo "查看 BGP 对等体:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "calicoctl node status | grep BGP"
# 3. 查看路由表
echo "查看路由表:"
kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}' | xargs -I {} ssh {} "ip route | grep calico"
# 4. 测试 Pod 间通信
echo "测试 Pod 间通信:"
POD1_IP=$(kubectl get pod -l app=calico-test -o jsonpath='{.items[0].status.podIP}')
POD2_IP=$(kubectl get pod -l app=calico-test -o jsonpath='{.items[1].status.podIP}')
kubectl exec $(kubectl get pod -l app=calico-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $POD2_IP
# 5. 查看 ARP 表
echo "查看 ARP 表:"
kubectl exec $(kubectl get pod -l app=calico-test -o jsonpath='{.items[0].metadata.name}') -- arp -a
# 6. 查看网络接口
echo "查看网络接口:"
kubectl exec $(kubectl get pod -l app=calico-test -o jsonpath='{.items[0].metadata.name}') -- ip addr show
实验3:Calico 性能测试
#!/bin/bash
# Calico 性能测试
echo "=== Calico 性能测试 ==="
# 1. 创建性能测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-iperf-server
spec:
replicas: 1
selector:
matchLabels:
app: calico-iperf-server
template:
metadata:
labels:
app: calico-iperf-server
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["iperf3", "-s"]
ports:
- containerPort: 5201
---
apiVersion: v1
kind: Service
metadata:
name: calico-iperf-server
spec:
selector:
app: calico-iperf-server
ports:
- port: 5201
targetPort: 5201
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-iperf-client
spec:
replicas: 1
selector:
matchLabels:
app: calico-iperf-client
template:
metadata:
labels:
app: calico-iperf-client
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["sh", "-c", "sleep 10 && iperf3 -c calico-iperf-server -t 30"]
EOF
# 2. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=calico-iperf-server --timeout=60s
kubectl wait --for=condition=Ready pod -l app=calico-iperf-client --timeout=60s
# 3. 运行性能测试
echo "运行性能测试:"
kubectl logs -f $(kubectl get pod -l app=calico-iperf-client -o jsonpath='{.items[0].metadata.name}')
# 4. 测试延迟
echo "测试延迟:"
kubectl exec $(kubectl get pod -l app=calico-iperf-client -o jsonpath='{.items[0].metadata.name}') -- ping -c 10 calico-iperf-server
# 5. 清理
kubectl delete deployment calico-iperf-server calico-iperf-client
kubectl delete service calico-iperf-server
Cilium eBPF 完整实战
Cilium 工作机制(eBPF 模式)
Cilium 是新一代的 eBPF 网络 + 安全 + 可观测性框架。
它的本质是:不再通过 iptables、bridge、VXLAN,而直接在内核 eBPF 层编程处理包流。
| 特性 | 说明 | 优势 |
|---|---|---|
| 高性能 | 不走内核协议栈,直连传输 | 延迟降低 30%+ |
| 高安全 | 支持 L7 策略(HTTP、gRPC) | 细粒度控制 |
| 可观测 | 自带 Hubble 可视化包流 | 实时监控 |
| 可扩展 | 支持 Istio、Envoy 集成 | 生态丰富 |
实验1:Cilium 部署与配置
#!/bin/bash
# Cilium 部署与配置
echo "=== Cilium 部署与配置 ==="
# 1. 删除 Calico
kubectl delete -f https://docs.projectcalico.org/manifests/calico.yaml
# 2. 安装 Cilium CLI
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
# 3. 安装 Cilium
cilium install
# 4. 等待 Cilium 就绪
cilium status --wait
# 5. 查看 Cilium 状态
echo "查看 Cilium 状态:"
cilium status
# 6. 查看 eBPF 程序
echo "查看 eBPF 程序:"
cilium bpf programs list
# 7. 创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: cilium-test
spec:
replicas: 4
selector:
matchLabels:
app: cilium-test
template:
metadata:
labels:
app: cilium-test
spec:
containers:
- name: test
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 8. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=cilium-test --timeout=60s
# 9. 查看 Pod 分布
echo "查看 Pod 分布:"
kubectl get pods -o wide
echo "Cilium eBPF 部署完成!"
实验2:Hubble 可视化观测
#!/bin/bash
# Hubble 可视化观测
echo "=== Hubble 可视化观测 ==="
# 1. 启用 Hubble
cilium hubble enable
# 2. 等待 Hubble 就绪
kubectl wait --for=condition=Ready pod -l k8s-app=hubble-ui -n kube-system --timeout=60s
# 3. 查看 Hubble 状态
echo "查看 Hubble 状态:"
cilium hubble status
# 4. 查看网络流量
echo "查看网络流量:"
cilium hubble observe
# 5. 测试 Pod 间通信
echo "测试 Pod 间通信:"
POD1_IP=$(kubectl get pod -l app=cilium-test -o jsonpath='{.items[0].status.podIP}')
POD2_IP=$(kubectl get pod -l app=cilium-test -o jsonpath='{.items[1].status.podIP}')
kubectl exec $(kubectl get pod -l app=cilium-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $POD2_IP
# 6. 查看 Hubble 流量
echo "查看 Hubble 流量:"
cilium hubble observe --follow
# 7. 查看 Hubble UI
echo "查看 Hubble UI:"
kubectl port-forward -n kube-system svc/hubble-ui 8080:80 &
echo "Hubble UI: http://localhost:8080"
实验3:L7 策略配置实例
#!/bin/bash
# L7 策略配置实例
echo "=== L7 策略配置实例 ==="
# 1. 创建 HTTP 服务
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-server
spec:
replicas: 1
selector:
matchLabels:
app: http-server
template:
metadata:
labels:
app: http-server
spec:
containers:
- name: server
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: http-server
spec:
selector:
app: http-server
ports:
- port: 80
targetPort: 80
EOF
# 2. 创建 HTTP 客户端
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-client
spec:
replicas: 1
selector:
matchLabels:
app: http-client
template:
metadata:
labels:
app: http-client
spec:
containers:
- name: client
image: curlimages/curl
command: ["sleep", "3600"]
EOF
# 3. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=http-server --timeout=60s
kubectl wait --for=condition=Ready pod -l app=http-client --timeout=60s
# 4. 测试 HTTP 访问
echo "测试 HTTP 访问:"
kubectl exec $(kubectl get pod -l app=http-client -o jsonpath='{.items[0].metadata.name}') -- curl -s http://http-server
# 5. 创建 L7 网络策略
kubectl apply -f - <<EOF
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: http-policy
spec:
endpointSelector:
matchLabels:
app: http-server
ingress:
- fromEndpoints:
- matchLabels:
app: http-client
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "GET"
path: "/"
EOF
# 6. 测试策略生效
echo "测试策略生效:"
kubectl exec $(kubectl get pod -l app=http-client -o jsonpath='{.items[0].metadata.name}') -- curl -s http://http-server
# 7. 查看策略状态
echo "查看策略状态:"
cilium policy get
# 8. 清理
kubectl delete deployment http-server http-client
kubectl delete service http-server
kubectl delete ciliumnetworkpolicy http-policy
实验4:Cilium 性能测试
#!/bin/bash
# Cilium 性能测试
echo "=== Cilium 性能测试 ==="
# 1. 创建性能测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: cilium-iperf-server
spec:
replicas: 1
selector:
matchLabels:
app: cilium-iperf-server
template:
metadata:
labels:
app: cilium-iperf-server
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["iperf3", "-s"]
ports:
- containerPort: 5201
---
apiVersion: v1
kind: Service
metadata:
name: cilium-iperf-server
spec:
selector:
app: cilium-iperf-server
ports:
- port: 5201
targetPort: 5201
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cilium-iperf-client
spec:
replicas: 1
selector:
matchLabels:
app: cilium-iperf-client
template:
metadata:
labels:
app: cilium-iperf-client
spec:
containers:
- name: iperf
image: networkstatic/iperf3
command: ["sh", "-c", "sleep 10 && iperf3 -c cilium-iperf-server -t 30"]
EOF
# 2. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=cilium-iperf-server --timeout=60s
kubectl wait --for=condition=Ready pod -l app=cilium-iperf-client --timeout=60s
# 3. 运行性能测试
echo "运行性能测试:"
kubectl logs -f $(kubectl get pod -l app=cilium-iperf-client -o jsonpath='{.items[0].metadata.name}')
# 4. 测试延迟
echo "测试延迟:"
kubectl exec $(kubectl get pod -l app=cilium-iperf-client -o jsonpath='{.items[0].metadata.name}') -- ping -c 10 cilium-iperf-server
# 5. 查看 eBPF 统计
echo "查看 eBPF 统计:"
cilium metrics list | grep -E "(cilium|hubble)"
# 6. 清理
kubectl delete deployment cilium-iperf-server cilium-iperf-client
kubectl delete service cilium-iperf-server
NetworkPolicy 深度实践
NetworkPolicy 工作原理
NetworkPolicy 是 Kubernetes 的网络隔离机制,通过标签选择器控制 Pod 间的网络通信。
语义:默认全部允许;一旦某命名空间启用网络策略,未匹配到的流量将被拒绝。
实验1:基础 NetworkPolicy 配置
#!/bin/bash
# 基础 NetworkPolicy 配置
echo "=== 基础 NetworkPolicy 配置 ==="
# 1. 创建测试命名空间
kubectl create namespace network-test
# 2. 创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: network-test
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: network-test
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
namespace: network-test
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 3. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=web -n network-test --timeout=60s
kubectl wait --for=condition=Ready pod -l app=api -n network-test --timeout=60s
kubectl wait --for=condition=Ready pod -l app=db -n network-test --timeout=60s
# 4. 测试初始连通性
echo "测试初始连通性:"
kubectl exec -n network-test $(kubectl get pod -l app=web -n network-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=api -n network-test -o jsonpath='{.items[0].status.podIP}')
# 5. 创建 NetworkPolicy
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-to-api
namespace: network-test
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 80
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-to-db
namespace: network-test
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: db
ports:
- protocol: TCP
port: 80
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-ingress
namespace: network-test
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 80
EOF
# 6. 测试策略生效
echo "测试策略生效:"
kubectl exec -n network-test $(kubectl get pod -l app=web -n network-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=api -n network-test -o jsonpath='{.items[0].status.podIP}')
# 7. 测试策略限制
echo "测试策略限制:"
kubectl exec -n network-test $(kubectl get pod -l app=web -n network-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=db -n network-test -o jsonpath='{.items[0].status.podIP}')
# 8. 清理
kubectl delete namespace network-test
实验2:多命名空间隔离方案
#!/bin/bash
# 多命名空间隔离方案
echo "=== 多命名空间隔离方案 ==="
# 1. 创建多个命名空间
kubectl create namespace frontend
kubectl create namespace backend
kubectl create namespace database
# 2. 创建各层服务
kubectl apply -f - <<EOF
# Frontend 层
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
# Backend 层
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: api
image: nginx:alpine
ports:
- containerPort: 80
---
# Database 层
apiVersion: apps/v1
kind: Deployment
metadata:
name: database
namespace: database
spec:
replicas: 1
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
containers:
- name: db
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 3. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=frontend -n frontend --timeout=60s
kubectl wait --for=condition=Ready pod -l app=backend -n backend --timeout=60s
kubectl wait --for=condition=Ready pod -l app=database -n database --timeout=60s
# 4. 创建跨命名空间 NetworkPolicy
kubectl apply -f - <<EOF
# Frontend 到 Backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-to-backend
namespace: frontend
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: backend
ports:
- protocol: TCP
port: 80
---
# Backend 到 Database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-to-database
namespace: backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 80
---
# Database 入站策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-ingress
namespace: database
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: backend
ports:
- protocol: TCP
port: 80
EOF
# 5. 给命名空间打标签
kubectl label namespace frontend name=frontend
kubectl label namespace backend name=backend
kubectl label namespace database name=database
# 6. 测试跨命名空间通信
echo "测试跨命名空间通信:"
kubectl exec -n frontend $(kubectl get pod -l app=frontend -n frontend -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=backend -n backend -o jsonpath='{.items[0].status.podIP}')
# 7. 测试策略限制
echo "测试策略限制:"
kubectl exec -n frontend $(kubectl get pod -l app=frontend -n frontend -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=database -n database -o jsonpath='{.items[0].status.podIP}')
# 8. 清理
kubectl delete namespace frontend backend database
实验3:白名单/黑名单策略
#!/bin/bash
# 白名单/黑名单策略
echo "=== 白名单/黑名单策略 ==="
# 1. 创建测试命名空间
kubectl create namespace policy-test
# 2. 创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: allowed-client
namespace: policy-test
spec:
replicas: 1
selector:
matchLabels:
app: allowed-client
template:
metadata:
labels:
app: allowed-client
spec:
containers:
- name: client
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: blocked-client
namespace: policy-test
spec:
replicas: 1
selector:
matchLabels:
app: blocked-client
template:
metadata:
labels:
app: blocked-client
spec:
containers:
- name: client
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
namespace: policy-test
spec:
replicas: 1
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
- name: server
image: nginx:alpine
ports:
- containerPort: 80
EOF
# 3. 等待 Pod 就绪
kubectl wait --for=condition=Ready pod -l app=allowed-client -n policy-test --timeout=60s
kubectl wait --for=condition=Ready pod -l app=blocked-client -n policy-test --timeout=60s
kubectl wait --for=condition=Ready pod -l app=server -n policy-test --timeout=60s
# 4. 创建白名单策略
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: server-whitelist
namespace: policy-test
spec:
podSelector:
matchLabels:
app: server
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-client
ports:
- protocol: TCP
port: 80
EOF
# 5. 测试白名单策略
echo "测试白名单策略:"
kubectl exec -n policy-test $(kubectl get pod -l app=allowed-client -n policy-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=server -n policy-test -o jsonpath='{.items[0].status.podIP}')
# 6. 测试黑名单效果
echo "测试黑名单效果:"
kubectl exec -n policy-test $(kubectl get pod -l app=blocked-client -n policy-test -o jsonpath='{.items[0].metadata.name}') -- ping -c 3 $(kubectl get pod -l app=server -n policy-test -o jsonpath='{.items[0].status.podIP}')
# 7. 清理
kubectl delete namespace policy-test
实验环境搭建
快速搭建脚本
#!/bin/bash
# CNI 与 eBPF 网络实验环境搭建脚本
set -e
echo "开始搭建 CNI 与 eBPF 网络实验环境..."
# 1. 创建实验集群
kind create cluster --name cni-ebpf-test --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
EOF
# 2. 等待集群就绪
kubectl wait --for=condition=Ready node --all --timeout=60s
# 3. 安装测试工具
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: network-tools
spec:
replicas: 1
selector:
matchLabels:
app: network-tools
template:
metadata:
labels:
app: network-tools
spec:
containers:
- name: tools
image: nixery.dev/shell/iperf3
command: ["sleep", "3600"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-tools
spec:
replicas: 1
selector:
matchLabels:
app: http-tools
template:
metadata:
labels:
app: http-tools
spec:
containers:
- name: tools
image: curlimages/curl
command: ["sleep", "3600"]
EOF
# 4. 创建测试资源
kubectl apply -f - <<EOF
# 测试资源 1:基础网络测试
apiVersion: apps/v1
kind: Deployment
metadata:
name: network-test
spec:
replicas: 4
selector:
matchLabels:
app: network-test
template:
metadata:
labels:
app: network-test
spec:
containers:
- name: test
image: nginx:alpine
ports:
- containerPort: 80
---
# 测试资源 2:HTTP 服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-server
spec:
replicas: 1
selector:
matchLabels:
app: http-server
template:
metadata:
labels:
app: http-server
spec:
containers:
- name: server
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: http-server
spec:
selector:
app: http-server
ports:
- port: 80
targetPort: 80
EOF
echo "CNI 与 eBPF 网络实验环境搭建完成!"
echo "运行 'kubectl get nodes' 查看集群状态"
echo "运行 'kubectl get pods' 查看 Pod 状态"
命令速查表
CNI 管理命令
| 命令 | 功能 | 示例 |
|---|---|---|
kubectl get pods -o wide | 查看 Pod 网络信息 | kubectl get pods -o wide |
kubectl get svc | 查看 Service 信息 | kubectl get svc |
kubectl get endpoints | 查看 Service 端点 | kubectl get endpoints |
kubectl describe pod <pod> | 查看 Pod 详细信息 | kubectl describe pod my-pod |
kubectl logs <pod> | 查看 Pod 日志 | kubectl logs my-pod |
kubectl exec -it <pod> -- sh | 进入 Pod 执行命令 | kubectl exec -it my-pod -- sh |
网络测试命令
| 命令 | 功能 | 示例 |
|---|---|---|
ping <ip> | 测试连通性 | ping 10.244.1.2 |
traceroute <ip> | 查看网络路径 | traceroute 10.244.1.2 |
nslookup <hostname> | DNS 解析测试 | nslookup kubernetes.default |
dig <hostname> | DNS 详细查询 | dig kubernetes.default.svc.cluster.local |
telnet <ip> <port> | 端口连通性测试 | telnet 10.244.1.2 80 |
curl <url> | HTTP 请求测试 | curl http://web-service |
系统网络命令
| 命令 | 功能 | 示例 |
|---|---|---|
ip addr show | 查看网络接口 | ip addr show |
ip route show | 查看路由表 | ip route show |
ip link show | 查看链路状态 | ip link show |
ss -tnp | 查看 Socket 状态 | ss -tnp |
netstat -tulpn | 查看网络连接 | netstat -tulpn |
tcpdump -i any | 抓包分析 | tcpdump -i any port 80 |
CNI 特定命令
| CNI | 命令 | 功能 | 示例 |
|---|---|---|---|
| Flannel | ip link show flannel.1 | 查看 VXLAN 接口 | ip link show flannel.1 |
| Calico | calicoctl node status | 查看 BGP 状态 | calicoctl node status |
| Cilium | cilium status | 查看 Cilium 状态 | cilium status |
| Cilium | cilium hubble observe | 查看网络流量 | cilium hubble observe |
性能测试命令
| 命令 | 功能 | 示例 |
|---|---|---|
iperf3 -c <server> | 带宽测试 | iperf3 -c iperf3-server |
wrk -t4 -c100 -d30s <url> | HTTP 压力测试 | wrk -t4 -c100 -d30s http://web-service |
ab -n 1000 -c 10 <url> | Apache 压力测试 | ab -n 1000 -c 10 http://web-service |