CNI 插件
学习目标
- 理解 CNI(容器网络接口)的概念和作用
- 掌握常见 CNI 插件的特点和选择
- 了解 CNI 插件的工作原理
核心概念
一句话解释
CNI(Container Network Interface)是容器网络的标准接口规范,CNI 插件负责为 Pod 配置网络,实现 Kubernetes 网络模型。
为什么需要 CNI
Kubernetes 定义了网络模型,但不实现网络
Kubernetes 网络模型要求:
- 每个 Pod 有唯一 IP
- Pod 间可以直接通信(无 NAT)
- 节点可以与 Pod 通信
CNI 插件负责实现这些要求
┌─────────────────────────────────────────┐
│ Kubernetes │
│ ┌─────────────────────────────────────┐│
│ │ CNI 接口规范 ││
│ └─────────────────────────────────────┘│
│ ↓ │
│ ┌─────────────────────────────────────┐│
│ │ CNI 插件 ││
│ │ - Calico ││
│ │ - Flannel ││
│ │ - Cilium ││
│ │ - Weave Net ││
│ └─────────────────────────────────────┘│
└─────────────────────────────────────────┘
CNI 工作原理
Pod 创建时的网络配置流程:
1. Kubelet 创建 Pod
↓
2. 调用 CNI 插件
↓
3. CNI 插件执行:
- 创建网络命名空间
- 创建 veth pair
- 配置 IP 地址
- 配置路由
↓
4. Pod 网络就绪
┌─────────────────────────────────────────────────────┐
│ Node │
│ ┌─────────────────────────────────────────────────┐│
│ │ Kubelet ││
│ │ ↓ 调用 ││
│ │ ┌─────────────────────────────────────────────┐││
│ │ │ CNI 插件 │││
│ │ │ ↓ 执行 │││
│ │ │ ┌─────────────────────────────────────────┐│││
│ │ │ │ 1. 创建网络命名空间 ││││
│ │ │ │ 2. 创建 veth pair ││││
│ │ │ │ 3. 配置 IP 地址 ││││
│ │ │ │ 4. 配置路由 ││││
│ │ │ └─────────────────────────────────────────┘│││
│ │ └─────────────────────────────────────────────┘││
│ └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
常见 CNI 插件对比
| 插件 | 特点 | NetworkPolicy | 性能 | 适用场景 |
|---|---|---|---|---|
| Flannel | 简单、轻量 | 不支持 | 中等 | 开发测试、小规模 |
| Calico | 功能丰富、支持 BGP | 支持 | 高 | 生产环境、大规模 |
| Cilium | eBPF、高性能 | 支持 | 极高 | 高性能、安全要求高 |
| Weave Net | 简单、自动发现 | 支持 | 中等 | 小规模、简单部署 |
Flannel
Flannel 特点:
- 简单易用
- 轻量级
- 不支持 NetworkPolicy
- 使用 VXLAN 或 host-gw 后端
Flannel 架构:
┌─────────────────────────────────────────────────────┐
│ Node │
│ ┌─────────────────────────────────────────────────┐│
│ │ flanneld (DaemonSet) ││
│ │ ↓ ││
│ │ ┌─────────────────────────────────────────────┐││
│ │ │ cni0 (网桥) │││
│ │ │ ↓ │││
│ │ │ ┌───────┐ ┌───────┐ ┌───────┐ │││
│ │ │ │ Pod A │ │ Pod B │ │ Pod C │ │││
│ │ │ └───────┘ └───────┘ └───────┘ │││
│ │ └─────────────────────────────────────────────┘││
│ └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
跨节点通信:
- VXLAN:封装在 UDP 包中
- host-gw:直接路由(需要二层网络)
Calico
Calico 特点:
- 支持 BGP 路由
- 支持 NetworkPolicy
- 高性能
- 适合大规模部署
Calico 架构:
┌─────────────────────────────────────────────────────┐
│ Node │
│ ┌─────────────────────────────────────────────────┐│
│ │ Calico Node (DaemonSet) ││
│ │ ↓ ││
│ │ ┌─────────────────────────────────────────────┐││
│ │ │ BIRD (BGP 客户端) │││
│ │ │ ↓ │││
│ │ │ Felix (策略执行) │││
│ │ │ ↓ │││
│ │ │ ┌───────┐ ┌───────┐ ┌───────┐ │││
│ │ │ │ Pod A │ │ Pod B │ │ Pod C │ │││
│ │ │ └───────┘ └───────┘ └───────┘ │││
│ │ └─────────────────────────────────────────────┘││
│ └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
跨节点通信:
- BGP:直接路由(需要网络支持)
- VXLAN:封装(备选方案)
- IPIP:IP 封装(备选方案)
Cilium
Cilium 特点:
- 基于 eBPF
- 极高性能
- 支持 L7 策略
- 服务网格功能
Cilium 架构:
┌─────────────────────────────────────────────────────┐
│ Node │
│ ┌─────────────────────────────────────────────────┐│
│ │ Cilium Agent (DaemonSet) ││
│ │ ↓ ││
│ │ ┌─────────────────────────────────────────────┐││
│ │ │ eBPF 程序 │││
│ │ │ ↓ │││
│ │ │ ┌───────┐ ┌───────┐ ┌───────┐ │││
│ │ │ │ Pod A │ │ Pod B │ │ Pod C │ │││
│ │ │ └───────┘ └───────┘ └───────┘ │││
│ │ └─────────────────────────────────────────────┘││
│ └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
eBPF 优势:
- 内核级别执行,性能极高
- 动态加载,无需重启
- 丰富的网络策略
CNI 配置
// /etc/cni/net.d/ 目录下的配置文件
{
"cniVersion": "0.4.0",
"name": "my-network",
"type": "calico",
"datastore_type": "kubernetes",
"nodename": "node1",
"ipam": {
"type": "calico-ipam"
}
}
# 查看 CNI 配置
ls /etc/cni/net.d/
cat /etc/cni/net.d/10-calico.conflist
# 查看 CNI 插件二进制文件
ls /opt/cni/bin/
选择 CNI 插件
选择指南:
开发测试环境:
→ Flannel(简单、轻量)
生产环境(小规模):
→ Calico(功能丰富、稳定)
生产环境(大规模):
→ Calico 或 Cilium(高性能)
高性能/安全要求高:
→ Cilium(eBPF、L7 策略)
云环境:
→ 云厂商提供的 CNI(如 AWS VPC CNI、Azure CNI)
实践练习
练习 1:查看当前 CNI 配置
# 查看 CNI 配置目录
ls /etc/cni/net.d/
# 查看具体配置
cat /etc/cni/net.d/10-calico.conflist
# 查看 CNI 插件
ls /opt/cni/bin/
# 查看节点的 CNI 信息
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'
练习 2:查看 Pod 网络配置
# 创建测试 Pod
kubectl run test-pod --image=busybox --command -- sleep 3600
# 查看 Pod IP
kubectl get pod test-pod -o wide
# 进入 Pod 查看网络配置
kubectl exec -it test-pod -- ip addr
kubectl exec -it test-pod -- ip route
kubectl exec -it test-pod -- cat /etc/resolv.conf
练习 3:测试 Pod 间通信
# 创建两个 Pod
kubectl run pod-a --image=busybox --command -- sleep 3600
kubectl run pod-b --image=nginx
# 获取 Pod B 的 IP
POD_B_IP=$(kubectl get pod pod-b -o jsonpath='{.status.podIP}')
# 从 Pod A 访问 Pod B
kubectl exec pod-a -- wget -qO- http://$POD_B_IP
# 查看网络路径
kubectl exec pod-a -- traceroute $POD_B_IP
练习 4:查看 CNI 日志
# 查看 CNI 插件日志
journalctl -u kubelet | grep cni
# 查看 Calico 日志
kubectl logs -n kube-system -l k8s-app=calico-node
# 查看 Flannel 日志
kubectl logs -n kube-system -l app=flannel
常见误解
1. CNI 插件是 Kubernetes 内置的
错误理解:Kubernetes 自带 CNI 插件
正确理解:需要单独安装
Kubernetes 只定义了 CNI 接口规范
需要自己选择和安装 CNI 插件
2. 所有 CNI 插件都一样
错误理解:不同的 CNI 插件可以互换
正确理解:不同插件功能和性能差异很大
- Flannel:不支持 NetworkPolicy
- Calico:支持 BGP、NetworkPolicy
- Cilium:eBPF、L7 策略、服务网格
3. CNI 插件可以随时更换
错误理解:可以随时更换 CNI 插件
正确理解:更换 CNI 需要谨慎
更换 CNI 可能导致:
- 网络中断
- Pod IP 变化
- 需要重新配置
建议:在规划阶段就选好 CNI
小结
| 要点 | 说明 |
|---|---|
| CNI | 容器网络接口标准 |
| 作用 | 为 Pod 配置网络,实现 K8s 网络模型 |
| 常见插件 | Flannel、Calico、Cilium、Weave Net |
| 选择因素 | 功能需求、性能要求、规模大小 |
| 配置位置 | /etc/cni/net.d/(配置)、/opt/cni/bin/(二进制) |
| 注意事项 | 需要单独安装,更换需谨慎 |
练习编辑器
bash
Loading...