59·网络进阶

CNI 插件

kubernetesnetworkingcni

CNI 插件

学习目标

  1. 理解 CNI(容器网络接口)的概念和作用
  2. 掌握常见 CNI 插件的特点和选择
  3. 了解 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支持生产环境、大规模
CiliumeBPF、高性能支持极高高性能、安全要求高
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...

继续学习

完成本课后,建议继续学习下一课「DNS 配置」 以巩固所学知识。