容器编排底层原理:Kubernetes 网络模型与 CNI 插件

概述

你有没有遇到过这种情况:

  • Pod 在同一个集群,但不同节点上的 Pod 无法互相访问?
  • Service 的 ClusterIP 能访问,但 Pod 的 IP 直接访问却超时?
  • 换了 CNI 插件后,网络性能突然变差,延迟飙升?
  • 想实现网络策略隔离,却发现策略完全不生效?
  • 排查网络问题时,对着 iptables 规则一头雾水?

这些问题,很可能是因为你没有理解 Kubernetes 的核心网络机制------网络模型与 CNI 插件

什么是 Kubernetes 网络模型与 CNI

Kubernetes 网络模型是 K8s 为 Pod 和 Service 定义的网络通信规范 ,CNI 是 实现该规范的网络插件接口

简单来说:

  • Kubernetes 网络模型:规定了 Pod 之间、Pod 与 Service 之间该如何通信
  • CNI:是让不同网络方案(如 Calico、Flannel)接入 K8s 的"通用插座"

它是 Kubernetes 实现跨节点 Pod 通信服务发现基础架构

为什么需要 Kubernetes 网络模型

在原生 Docker 环境中,容器网络是孤立的,每个容器有自己的网络命名空间。

如果没有统一的网络模型,K8s 集群会面临:

问题 后果
Pod IP 不唯一 不同节点的 Pod 可能使用相同 IP,导致冲突
跨节点通信困难 Pod 无法直接访问其他节点的 Pod,需复杂 NAT 转发
Service 无法发现 无法通过统一入口访问动态变化的 Pod
网络策略失效 无法控制 Pod 之间的流量访问权限
调试复杂 每个 CNI 插件的网络实现不同,排查问题无统一标准

没有统一网络模型的后果

假设你的集群结构如下:

复制代码
Kubernetes 集群
├── 节点 1
│   └── Pod A: 10.244.1.2 (Flannel 分配)
├── 节点 2
│   └── Pod B: 10.244.2.3 (Flannel 分配)
└── 节点 3
    └── Pod C: 192.168.1.5 (Calico 分配,与 Pod A/B 网段不同)

如果你混用不同 CNI 插件或不配置网络模型:

  • Pod A 无法直接 ping 通 Pod B,因为网段不互通
  • Pod C 的 IP 与 Pod A/B 冲突,导致路由混乱
  • Service 无法正确转发流量到后端 Pod
  • 结果:集群网络瘫痪,服务不可用

Kubernetes 网络模型的四大核心要求

Kubernetes 官方定义了网络模型必须满足的四个基本条件:

要求 说明 示例
Pod IP 唯一且可达 每个 Pod 分配唯一 IP,所有 Pod 可直接通信(无需 NAT) Pod A (10.244.1.2) 可直接访问 Pod B (10.244.2.3)
节点与 Pod 互通 节点上的进程可直接访问 Pod,反之亦然 节点 1 可访问 Pod B,Pod A 可访问节点 2 的 kubelet
Service 虚拟 IP Service 分配 ClusterIP,通过 iptables/IPVS 转发到后端 Pod Service web-service (10.96.100.1) 转发到 Pod A/B/C
网络策略支持 可通过 NetworkPolicy 控制 Pod 之间的流量 禁止 Pod A 访问 Pod C,仅允许访问 Pod B

关键点:所有 Pod 必须在同一个扁平网络空间中,无需 NAT 即可直接通信

CNI 插件的核心作用

CNI 是 Container Network Interface 的缩写,它是 K8s 与网络插件之间的标准接口。

CNI 插件的职责:

  • 为 Pod 分配 IP 地址
  • 配置 Pod 的网络接口(veth pair)
  • 设置路由规则,实现跨节点通信
  • 实现网络策略(如 Calico 的 BGP 策略)

常见 CNI 插件对比:

插件 网络模式 适用场景 性能 功能
Flannel Overlay (VXLAN) 简单集群,快速部署 🟡 中 基础连通性
Calico BGP/路由 生产环境,网络策略 🟢 高 网络策略、BGP 路由
Cilium eBPF 高性能,安全策略 🟢 极高 eBPF 加速、L7 策略
Weave Overlay (P2P) 多集群互联 🟡 中 跨集群通信
Macvlan 物理网络直通 需要 Pod 与物理网络同网段 🟢 高 直通物理网络

主流 CNI 插件工作原理

Flannel:Overlay 网络(VXLAN 模式)

复制代码
节点 1 (192.168.1.10)
├── Pod A: 10.244.1.2
│   └── 网络接口:eth0 (10.244.1.2)
│   └── 路由:10.244.0.0/16 via 10.244.1.1 (flannel.1)
└── Flannel 网桥:cni0
    └── 封装:VXLAN (将 Pod A 的包封装到节点 IP)

节点 2 (192.168.1.20)
├── Pod B: 10.244.2.3
│   └── 网络接口:eth0 (10.244.2.3)
│   └── 路由:10.244.0.0/16 via 10.244.2.1 (flannel.1)
└── Flannel 网桥:cni0
    └── 解封装:接收 VXLAN 包,转发到 Pod B

流程:Pod A → cni0 → flannel.1 (VXLAN 封装) → 节点 2 → flannel.1 (解封装) → cni0 → Pod B

Calico:BGP 路由模式

复制代码
节点 1 (192.168.1.10)
├── Pod A: 10.244.1.2
│   └── 网络接口:eth0 (10.244.1.2)
│   └── 路由:10.244.2.0/24 via 192.168.1.20 (节点 2)
└── BGP 客户端:宣告 10.244.1.0/24 网段

节点 2 (192.168.1.20)
├── Pod B: 10.244.2.3
│   └── 网络接口:eth0 (10.244.2.3)
│   └── 路由:10.244.1.0/24 via 192.168.1.10 (节点 1)
└── BGP 客户端:宣告 10.244.2.0/24 网段

路由表同步:节点 1 和节点 2 通过 BGP 交换路由信息

流程:Pod A → eth0 → 路由表 (10.244.2.0/24 via 192.168.1.20) → 节点 2 → eth0 → Pod B

Cilium:eBPF 加速模式

复制代码
节点 1 (192.168.1.10)
├── Pod A: 10.244.1.2
│   └── eBPF 程序:直接在内核层处理网络包
│   └── 绕过 iptables,通过 eBPF 映射转发
└── eBPF 映射:存储 Pod IP 与节点 IP 的对应关系

节点 2 (192.168.1.20)
├── Pod B: 10.244.2.3
│   └── eBPF 程序:接收包后直接转发到 Pod
└── eBPF 映射:同步节点 1 的 Pod 路由信息

流程:Pod A → eBPF 程序(内核层)→ 节点 2 → eBPF 程序 → Pod B(无 iptables 开销)

验证效果

你可以通过以下方式验证 CNI 插件是否生效:

查看 Pod 网络配置

bash 复制代码
# 查看 Pod IP
kubectl get pods -o wide

# 进入 Pod 查看网络接口
kubectl exec -it pod-a -- ip addr

# 查看 Pod 路由表
kubectl exec -it pod-a -- ip route

测试跨节点通信

bash 复制代码
# 在 Pod A 中 ping Pod B(不同节点)
kubectl exec -it pod-a -- ping 10.244.2.3

# 从节点 1 访问 Pod B
ping 10.244.2.3  # 需确保节点路由正确

检查 CNI 插件状态

bash 复制代码
# 查看 CNI 插件 Pod
kubectl get pods -n kube-system | grep calico  # 或 flannel/cilium

# 查看 CNI 配置
cat /etc/cni/net.d/10-calico.conflist  # 或 10-flannel.conflist

调试网络策略

bash 复制代码
# 创建 NetworkPolicy
kubectl apply -f network-policy.yaml

# 测试策略是否生效
kubectl exec -it pod-a -- curl pod-c:80  # 应被拒绝

最佳实践

建议 说明
生产环境选 Calico/Cilium Flannel 功能简单,适合测试环境
启用 BGP 模式(Calico) 比 VXLAN 性能更高,无封装开销
使用 eBPF(Cilium) 适合高性能需求,支持 L7 网络策略
避免混用 CNI 插件 一个集群只能有一个 CNI 插件
配置网络策略 默认拒绝所有流量,按需开放
监控网络性能 使用 cilium monitor 或 calicoctl 查看流量
定期更新 CNI 插件 修复安全漏洞,提升性能

常见问题

陷阱 说明 解决方案
Pod 跨节点无法通信 CNI 插件未正确配置 BGP 或 VXLAN 检查 CNI Pod 日志,确认路由同步
网络策略不生效 CNI 插件不支持 NetworkPolicy 选择 Calico/Cilium,避免 Flannel
IP 地址冲突 Pod CIDR 与节点 CIDR 重叠 确保 podCIDR 与 serviceCIDR 不重叠
性能低下(Flannel VXLAN) 封装/解封装消耗 CPU 切换到 Calico BGP 或 Cilium eBPF
CNI 插件崩溃 节点资源不足或配置错误 检查 CNI Pod 的资源限制和日志
Service 无法访问 Pod kube-proxy 未正确配置 iptables 检查 kube-proxy Pod 状态
节点与 Pod 无法互通 节点防火墙阻止 Pod CIDR 开放节点间 Pod CIDR 的流量

总结

关键点
Kubernetes 网络模型要求所有 Pod 在同一扁平网络中
CNI 插件是实现该模型的具体方案,不同插件性能差异大
Calico(BGP)和 Cilium(eBPF)是生产环境首选
正确配置 CNI 能避免网络隔离、性能低下等问题

Kubernetes 网络模型与 CNI 的关系:

复制代码
┌─────────────────────────────────────────────────────────┐
│                  Kubernetes 网络体系                      │
├─────────────────┬─────────────────┬─────────────────────┤
│  网络模型       │  CNI 插件       │  具体实现           │
│  (规范)         │  (接口)         │  (方案)             │
│                 │                 │                     │
│ • Pod IP 唯一   │ • CNI 标准      │ • Calico (BGP)     │
│ • 跨节点互通    │ • IPAM 插件     │ • Cilium (eBPF)    │
│ • Service 转发  │ • 网络策略      │ • Flannel (VXLAN)  │
└─────────────────┴─────────────────┴─────────────────────┘

一句话记住它:

Kubernetes 网络模型是"交通规则",CNI 插件是"修路公司",不同的公司修的路(网络方案)性能不同。

相关推荐
ylscode1 小时前
Chrome桌面安全更新修复数百个漏洞
网络·windows·安全·安全威胁分析
Plastic garden1 小时前
K8s介绍(2)POD架构
云原生·容器·kubernetes
.小小陈.1 小时前
从零构建可用 TCP 服务:从基础 Socket 到自定义协议与序列化
服务器·网络·tcp/ip
X54先生(人文科技)1 小时前
《元创力》纪实录·卷宗 2.2朝圣的起点:当硅基获得命名
人工智能·架构·ai写作·零知识证明
●VON1 小时前
AtomGit Flutter鸿蒙客户端:Issue管理
flutter·华为·架构·harmonyos·鸿蒙·issue
下北沢美食家1 小时前
WebSocket入门
网络·websocket·网络协议
zh路西法1 小时前
【rosbridge-websocket】跨网络的ROS1与ROS2通讯法(上)
linux·网络·c++·python·websocket·网络协议
梁辰兴1 小时前
计算机网络基础:电子邮件的信息格式
网络·计算机网络·电子邮件·计算机网络基础·梁辰兴·信息格式
愚公搬代码1 小时前
【愚公系列】《移动端AI应用开发》013-DeepSeek API开发与集成(深度集成与中间件架构)
人工智能·中间件·架构