Kubernetes 网络三部曲:CNI、kube-proxy 与 CoreDNS 是如何协作的?

引言

"Service 配好了,为什么调用还是失败?""Pod 明明在 Running,却收不到任何流量!""DNS 解析不了服务名,但 kubectl get svc 显示一切正常!"

如果你在 Kubernetes 中反复遭遇这类"玄学"问题,很可能是因为你只记住了命令,却没看清 K8s 网络与服务发现的底层协作机制。

Kubernetes 的网络模型看似简单------每个 Pod 有独立 IP,Service 提供稳定入口------但在这层抽象之下,CNI、kube-proxy、CoreDNS 三大组件环环相扣,任何一个环节出错,都会导致"不通"。今天这篇文章,就带你彻底搞懂这三者分别负责什么,以及它们是如何配合完成一次完整的访问请求的。


一、CNI(Calico / Flannel)

核心职责:分配 IP 地址,保证基本连通。

Kubernetes 本身并不实现网络,而是依赖 CNI(Container Network Interface)插件来为 Pod 分配 IP 并打通跨节点通信。

你可以这样理解:CNI 就像是给你的电脑插上网线,分配一个固定的内网 IP(比如 172.17.0.3),并且保证你能 ping 通隔壁工位同事的电脑(不同 Node 上的 Pod)

只要 CNI 正常工作,任意 Pod 都可以直接通过 IP 访问其他 Pod,无需 NAT 或端口映射。跨节点通信是 CNI 的核心能力之一:当 Pod 分布在不同节点时,数据需要跨越物理网络。Flannel 等插件通过 VXLAN 隧道封装数据包,使跨节点流量像在同一局域网内传输;而 Calico 则基于 BGP 路由协议,通过节点路由表直接转发,性能更高。

CNI 插件 工作模式 性能 网络策略 适用场景
Flannel VXLAN / Host-gw 中等 ❌ 不支持 快速上手、小规模集群
Calico BGP / IPIP / eBPF ✅ 支持 生产环境、需安全隔离

CNI 的局限在于:Pod 是"短命"的 ------今天这个 Pod 的 IP 是 172.17.0.3,明天它挂了重启后可能就变成了 172.17.0.5。你不能让前端写死这个 IP,否则一变就挂。


二、kube-proxy

核心职责:提供虚拟 IP(ClusterIP)和负载均衡。

kube-proxy 是 Kubernetes 集群的关键组件,负责 Service 和其后端 Pod 之间的负载均衡转发。每个 Kubernetes 节点上都运行着一个 kube-proxy。

你可以这样理解:kube-proxy 就像公司前台的总机号码(ClusterIP)。你不用记住每个员工的手机号(Pod IP),只需要打总机号码,前台(kube-proxy)会自动帮你转接到当前空闲的对应员工(Pod)上。

具体来说,kube-proxy 做了两件事:

  1. 给 Service 分配一个永不过期的虚拟 IP(ClusterIP)

  2. 当流量访问 ClusterIP 时,劫持该流量,并随机/轮询地转发给后端真正健康的 Pod IP

kube-proxy 本身不做实际的包转发,而是根据从 API Server 监听到的 Service 与 EndpointSlice 的变化,维护节点上的包处理规则(iptables 或 IPVS 规则),最终由 Linux 内核来完成真实流量的转发。

两种主流模式

  • iptables 模式(默认) :利用 Linux 内核的 iptables 规则链实现 DNAT(目标地址转换)。规则数量随 Service 数量线性增加,大规模集群下性能下降明显。

  • IPVS 模式(生产推荐) :基于 IP Virtual Server 内核模块,使用哈希表管理后端,负载均衡算法丰富(rr、lc、dh 等),性能 O(1),更适合高并发、大规模场景。

关键点 :kube-proxy 不负责连通性 (连通性是 CNI 干的),它只负责修改 Linux 内核的网络转发规则


三、CoreDNS

核心职责:域名解析(服务名 → ClusterIP)。

CoreDNS 是 Kubernetes 集群中默认内置的 DNS 服务器,用于提供动态服务发现和域名解析的能力。

你可以这样理解:CoreDNS 就像公司的通讯录/电话黄页 。你只需要喊一句"转接财务部"(DNS 查询),它告诉你财务部总机号码是 10.96.1.2(ClusterIP),然后你再去找 kube-proxy。

CoreDNS 监听 API Server,每当创建 Service,它就将 服务名 → ClusterIP 的映射记录存入 DNS。这样一来,Pod 就可以通过服务名称 (如 mysql.db-namespace.svc.cluster.local)来查找目标,而不是写死 IP 地址。


四、一次完整的访问流程(串联三者)

现在,让我们用一个完整的例子,把三个组件串起来。

假设前端 Pod(A)要访问后端 Pod(B,如 MySQL),完整流程如下:

步骤 负责组件 动作描述
① 服务发现 CoreDNS 前端代码写死域名 mysql.db.svc.cluster.local,发起 DNS 查询。CoreDNS 返回 Service 的固定虚拟 IP(ClusterIP)
② 流量拦截 kube-proxy 数据包发往 ClusterIP 后,宿主机内核检查到该 IP 是 Service 网段,立即触发 iptables/IPVS 规则。kube-proxy 负责维护这些规则,挑选一个健康的 Pod IP
③ DNAT 转换 内核 Netfilter 内核将数据包的目标 IP 和端口 (ClusterIP:3306)改写 为后端 Pod 的真实 IP(172.17.0.8:3306
④ 路由转发 CNI(Calico/Flannel) 内核根据目标 Pod IP 查询路由表。CNI 提供该路由表(BGP 路由或 VXLAN 隧道信息),决定数据包从哪张网卡发出
⑤ 响应返回 内核 SNAT 后端 Pod 处理后,响应包返回给前端。内核自动执行 SNAT,将源 IP(Pod IP)还原为 Service 的 ClusterIP,前端 Pod 感受不到后端真实 IP 的变化

用一句话概括

前端代码写域名 → CoreDNS 返回 ClusterIP → kube-proxy 的 iptables/IPVS 规则将 ClusterIP 转为 Pod IP → CNI 负责把包送到目标 Pod。


五、如果少了某一个,会怎样?

  • 如果你只有 CNI,没有 kube-proxy:Pod 间能互相 ping 通,但一旦 Pod 重启换 IP,你的程序就挂了,而且无法做多副本的负载均衡。

  • 如果你没有 CoreDNS :你得手动在程序里填写 ClusterIP(比如 10.96.100.1)。虽然这个 IP 通常不变,但如果 Service 被删掉重建,IP 变了,程序还得改配置重启,极不方便。

  • 如果 CNI 出问题:连最基本的 Pod 间 IP 互通都做不到,上层的一切都无从谈起。


六、选型建议

在实际生产环境中,如何选择这些组件?

  • CNI 选型

    • Flannel:配置简单,适合学习环境、小规模集群,但不支持 NetworkPolicy。

    • Calico:性能更优,支持细粒度网络策略,适合生产环境。

  • kube-proxy 模式

    • iptables:兼容性好,适合中小规模集群。

    • IPVS:性能更高,适合大规模、高并发场景。

  • DNS 优化 :在大规模集群中,可以考虑启用 NodeLocal DNSCache,将 DNS 缓存代理以 DaemonSet 形式跑在每台节点上,缩短 DNS 查询路径,降低 CoreDNS 压力。


总结

用一个形象的比喻来收尾:

  • CNI(Calico/Flannel)"路和车" ------解决"能不能到"(底层物理网络和路由)。

  • kube-proxy"交警和调度员" ------解决"找哪个 IP 去"(虚拟 IP 转换和负载均衡)。

  • CoreDNS"导航地图" ------解决"那个 IP 叫什么名字"(服务发现,方便代码不写死 IP)。

三者配合,Kubernetes 的网络才算真正可用。下次再遇到"网络不通"的问题,按这个思路逐层排查:先看 CNI(Pod IP 能不能通),再看 kube-proxy(Service 能不能通),最后看 CoreDNS(域名能不能解析)。

相关推荐
2301_815091011 小时前
TCP 并发服务器模型:4 种 IO 模型完整梳理
服务器·网络·tcp/ip
斑马1391 小时前
Linux软件编程学习笔记(十二)——TCP并发服务器模型
java·服务器·网络
DolitD1 小时前
实时云渲染多应用并发:CELL容器技术突破3D隔离瓶颈
云原生·容器·实时互动·图形渲染·数据可视化
鹤落晴春1 小时前
【K8s】Kustomize管理
云原生·容器·kubernetes
学着改变2752 小时前
2026便携式超声波流量计性能白皮书 户外巡检适用性横评
大数据·网络·人工智能·科技·产品运营·量子计算
rcms152702692182 小时前
Novellus Systems 02-033134-00晶圆底座加热器
网络
马立杰2 小时前
IE241210_路由安全技术(三层安全)
网络·安全
石小千2 小时前
Docker 笔记(九)--离线安装
docker·容器
马立杰2 小时前
IE241211_路由安全技术(三层安全)
网络·安全·智能路由器