kube-proxy、CNI 与 Gateway API:三者的关联与区别
这三者都属于 Kubernetes 网络体系,但处在不同的层次,解决不同的问题。先用一个类比快速建立直觉:
CNI = 修路和车辆登记系统 —— 给每个 Pod 发 IP、把 Pod 之间、节点之间的"路"修通(能不能到)
kube-proxy = 交通调度员 —— 把访问虚拟 IP(Service ClusterIP)的流量调度到真实的 Pod IP 上(找哪个 IP 去)
Gateway API = 城市大门和门卫规则 —— 定义外部流量如何进入集群、按什么规则路由到哪些服务(外面的人怎么进来)
一、逐一详解
1. CNI(Container Network Interface)—— 容器网络接口
是什么:
CNI 是一个规范/标准(类似插件接口协议),定义了容器运行时(kubelet)在创建/销毁 Pod 时,如何调用外部插件来完成网络配置。具体的功能由 CNI 插件实现,常见的有:Calico、Cilium、Flannel、Weave、以及云厂商的 Terway(阿里云)、AWS VPC CNI 等。
负责什么:
为每个 Pod 创建网络命名空间(netns)、分配 Pod IP
实现同一节点上 Pod 之间的通信(veth pair、网桥等)
实现跨节点 Pod 之间的通信(Overlay 隧道如 VXLAN,或 Underlay 路由如 BGP)
很多 CNI 插件还实现 NetworkPolicy(网络策略/防火墙规则)
高级插件(如 Cilium)还能基于 eBPF 提供可观测性、加密通信等
关键点: Kubernetes 本身只定义了网络模型("每个 Pod 有独立 IP,任意 Pod 之间可以直接通信"),具体怎么实现完全交给 CNI 插件。没有 CNI,集群里所有 Pod 都会卡在 ContainerCreating 状态。
2. kube-proxy —— Service 的虚拟 IP 转发器
是什么:
Kubernetes 自带的组件(以 DaemonSet 运行在每个节点上),负责实现 Service 抽象。
负责什么:
监听 API Server 中 Service 和 EndpointSlice 的变化
把 Service 的虚拟 IP(ClusterIP) 到真实 Pod IP 列表的映射,写入内核规则:
iptables 模式(目前默认):写 iptables DNAT 规则,随机选一个后端 Pod
IPVS 模式:用内核 IPVS 做负载均衡,支持 rr/lc/sh 等多种算法,大规模集群性能更好
nftables 模式:新一代默认方向,性能优于 iptables(K8s 1.29+ 引入)
实现 NodePort、LoadBalancer 类型 Service 的节点端口转发
关键点:
kube-proxy 本身不是代理服务器,它不转发任何数据包!它只是"写规则的",真正转发流量的是内核(iptables/IPVS/nftables)。
它解决的问题是:ClusterIP 是个虚拟 IP,没有任何网卡持有它,必须有人把访问它的流量 DNAT 成 Pod IP —— 这就是 kube-proxy 的职责。
3. Gateway API —— 新一代南北向流量入口标准
是什么:
由 Kubernetes SIG-Network 社区主导的下一代流量路由 API 标准,是 Ingress 的演进替代者。它不是 Kubernetes 内置资源,而是一组 CRD(需要单独安装),且需要具体的控制器实现,如 Envoy Gateway、Istio、Kong、Traefik、Nginx Gateway Fabric、以及各云厂商网关(阿里云 MSE、火山引擎 API 网关等)。
背景:Ingress NGINX 已于 2026 年 3 月退役,官方推动生态向 Gateway API 迁移,Ingress2Gateway 工具也已发布 1.0 版本。
核心资源模型(角色分离设计):
相比 Ingress 的优势:
多协议支持(Ingress 基本只有 HTTP/HTTPS)
精细路由(Header、Query 参数、方法匹配、流量分割/灰度)
标准化扩展(Ingress 靠各家私有的 annotation,Gateway API 用统一的 CRD + Policy 机制)
角色分离与跨命名空间引用(ReferenceGrant 实现安全的多团队协作)
二、三者的关联:一个请求的完整旅程
以"外部用户访问集群内的 Web 服务"为例:
外部用户
│ ① 请求到达 Gateway 的地址(如 443 端口)
▼
Gateway API 实现(Envoy Gateway / Istio 等控制器 + 数据面代理 Pod)
│ ② 按 HTTPRoute 规则匹配:域名 foo.com,路径 /api → 后端 Service "api-svc"
│ 代理拿到 api-svc 的 ClusterIP 和 Endpoint 列表,发起转发
▼
kube-proxy 写入的内核规则(iptables/IPVS/nftables)
│ ③ 若目标是 ClusterIP:内核 DNAT,把 ClusterIP:port 转换为某个 PodIP:port
│ (注:Envoy/Istio 等实现可直连 Endpoint,绕过 kube-proxy 这一跳)
▼
CNI 构建的 Pod 网络
│ ④ 数据包经 veth → 网桥/eBPF → (跨节点时)VXLAN 隧道或 BGP 路由
▼
目标 Pod 收到请求
依赖关系总结:
Gateway API 建立在 CNI 和 kube-proxy 之上:Gateway 的数据面本身是集群里的 Pod(靠 CNI 联网);它把流量转发给 Service 时依赖 kube-proxy 的转发规则(或直连 Endpoint)。
kube-proxy 依赖 CNI:kube-proxy 生成的规则最终指向 Pod IP,而这些 IP 和 IP 之间的可达性是 CNI 提供的。CNI 不通,kube-proxy 规则再对也没用。
CNI 不依赖另外两者:它是最底层,只关心 Pod IP 分配和 Pod 间连通性。
边界正在融合:
Cilium 等 eBPF CNI 提供 kube-proxy replacement 模式,直接用 eBPF 实现 Service 转发,此时 CNI 吞并了 kube-proxy 的职责。
一些 CNI/服务网格(Cilium、Istio)本身就是 Gateway API 的实现者,此时一个组件同时覆盖了三层。
三、三者的区别:对比表
四、实践建议
故障排查顺序:先看 CNI(Pod IP 之间能不能 ping 通)→ 再看 kube-proxy(访问 ClusterIP 通不通,
iptables-save | grep <svc>查规则)→ 最后看 Gateway/DNS(入口路由和域名解析)。大规模集群(>1000 Service):kube-proxy 建议从 iptables 切到 IPVS 或 nftables 模式,或直接用 Cilium eBPF 替代 kube-proxy。
新项目入口层:优先选 Gateway API 而非 Ingress(Ingress 生态已进入维护/退役周期),并选择与团队技术栈匹配的控制器(如用 Envoy Gateway 或云厂商托管网关)。
注意:很多 Gateway API 实现(Envoy、Istio)会直接读 EndpointSlice 把流量发给 Pod,绕过 ClusterIP 这一跳,此时 kube-proxy 只在集群内其他普通 Pod 访问 Service 时才起作用。
一句话总结:CNI 打地基(Pod 连通性),kube-proxy 建电梯(Service 负载均衡),Gateway API 设大门(南北向智能入口)——三者层次递进、互相依赖,共同构成 Kubernetes 完整的网络栈。