在K8S中,kube-proxy iptables原理是什么?

好的,我们来深入解析 Kubernetes 中 kube-proxyiptables 模式 的工作原理。这是 kube-proxy 最经典和稳定的模式,虽然在新版本中 IPVS 因其性能成为默认,但理解 iptables 模式对掌握 Kubernetes 网络至关重要。

核心思想

kube-proxy iptables 模式的核心思想是:使用 Linux 内核的 iptables 规则,来实现对 Service 的虚拟 IP(VIP)的访问请求的自动负载均衡和地址转换(NAT),将其转发到后端真实的 Pod IP 上。

kube-proxy 的角色是一个控制器,它监听 API Server 中 Service 和 Endpoint 的变化,然后动态地、智能地生成和维护本机上的 iptables 规则集。数据包的实际转发工作完全由内核中的 netfilter/iptables 来完成,kube-proxy 本身不转发任何数据包。

下图展示了这一核心流程,包括控制平面与数据平面的分工:

flowchart TD subgraph ControlPlane[kube-proxy 控制平面] A[Watch API Server] --> B[Service/Endpoint Change?] B -- Yes --> C[Calculate & Update iptables Rules] C --> D[Rules installed in Kernel] end subgraph DataPlane[netfilter/iptables 数据平面] E[Packet to Service IP:Port] --> F{nat.PREROUTING<br>All incoming packets} F --> G{nat.KUBE-SERVICES<br>Chain: Jump to Service Port} G --> H{nat.KUBE-SVC-XXX<br>Chain: Load Balancing} H --> I{Randomly/Equally<br>choose a Pod} I --> J{nat.KUBE-SEP-YYY<br>Chain: DNAT to Pod IP:Port} J --> K[Routing & Forwarding] K --> L[Packet goes to Pod] end ControlPlane -- Manages --> DataPlane

工作原理详细步骤

第 1 步:监听与规则生成 (控制平面)

  1. 监听 API Serverkube-proxy 启动后,会通过 List-Watch 机制监听 Kubernetes API Server,获取所有 Service 和 Endpoint(或 EndpointSlice)的变更事件。
  2. 计算规则:当有 Service 或它的后端 Pod(Endpoints)发生变化时(如创建、删除、扩缩容),kube-proxy 会根据最新的状态,在内存中计算出一套所需的 iptables 规则。
  3. 应用规则kube-proxy 调用 iptables-restore 等命令,将计算好的规则批量、原子性地应用到本机内核中,确保规则与集群状态一致。

第 2 步:数据包流转 (数据平面)

当一个数据包目标是 Service 的 ClusterIP:Port 时,它在节点上的旅程如下(以 ClusterIP 为例):

  1. 入口:PREROUTING

    • 所有进入本机的数据包(包括来自本机进程和外部的)都会先经过 nat 表的 PREROUTING 链。
    • 这里有一条关键规则:“所有数据包都跳转到自定义链 KUBE-SERVICES
      -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
  2. 服务匹配:KUBE-SERVICES

    • 这个链是 kube-proxy 维护的所有 Service 规则的入口。
    • 链中包含了许多规则,每条规则匹配一个 Service 的 IP 和端口。例如:
      -A KUBE-SERVICES -d 10.96.0.1/32 -p tcp --dport 443 -j KUBE-SVC-XXXXX (API Server Service)
      -A KUBE-SERVICES -d 10.96.0.10/32 -p udp --dport 53 -j KUBE-SVC-YYYYY (CoreDNS Service)
    • 如果数据包的目标地址是 10.96.0.10:53 (UDP),它就会匹配上第二条规则,并跳转到链 KUBE-SVC-YYYYY
  3. 负载均衡:KUBE-SVC-XXXX

    • 每个 Service 都有自己对应的 KUBE-SVC-XXX 链,该链负责实现负载均衡
    • 这个链中的规则会按概率随机地将流量分发到更后端的链(代表一个具体的 Pod)。规则的数量等于后端 Pod 的数量,每条规则的概率权重相同(实现简单的随机负载均衡)。
      -A KUBE-SVC-YYYYY -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-AAAAA
      -A KUBE-SVC-YYYYY -j KUBE-SEP-BBBBB
      
    • 上面的例子表示:有 50% 的概率跳转到 KUBE-SEP-AAAAA,剩下的 50% 概率跳转到 KUBE-SEP-BBBBB(如果有两个 Pod)。
  4. 目标地址转换 (DNAT):KUBE-SEP-XXXX

    • 每个 Pod Endpoint 都有自己对应的 KUBE-SEP-XXX 链(SEP 代表 Service EndPoint)。
    • 这个链的核心作用是执行 DNAT(Destination Network Address Translation)
      -A KUBE-SEP-AAAAA -p udp -j DNAT --to-destination 172.17.0.3:53
    • 这条规则的意思是:将数据包的目标 IP 和端口从 Service 的 10.96.0.10:53 修改为 Pod 的 172.17.0.3:53
  5. 路由与出口

    • 完成 DNAT 后,数据包会继续经过 FORWARD 链(如果目标是其他节点的 Pod)或 POSTROUTING 链(如果目标是本机 Pod)。
    • POSTROUTING 链中,会再次经过一个 KUBE-POSTROUTING 链,这里主要负责MASQUERADE(源地址伪装)。这是为了确保响应包在返回客户端时,源地址是 Service IP 而不是 Pod IP,否则客户端会因为收到来自未知 Pod IP 的响应而丢弃它。

关键特点与优劣分析

特性 说明
工作原理 依靠内核 iptables 规则链进行匹配和 NAT。
负载均衡算法 随机均衡:基于 statistic 模块的随机概率,不是轮询。它不支持更高级的算法(如最小连接数)。
性能 规则遍历是 O(n)。当 Service 和 Pod 数量极大时,iptables 规则列表会非常庞大,线性查找匹配规则会带来延迟和性能下降。规则同步也会变慢。
可靠性 极其成熟和稳定。作为 Linux 内核的标准功能,经受了长期考验。
调试 规则非常复杂,对人类不友好。使用 `iptables-save
连接状态 依赖 conntrack 模块跟踪连接。在高并发短连接场景(如 HTTP 1.1 Keep-Alive)下,容易导致 conntrack 表满,引发丢包。

与 IPVS 模式的简单对比

方面 iptables 模式 IPVS 模式
实现机制 长长的顺序规则链 内核哈希表
算法复杂度 O(n) O(1)
负载均衡算法 随机 丰富(rr, lc, dh, sh等)
大规模集群 性能下降明显 性能优异,扩展性好
操作复杂度 规则复杂难懂 规则简洁清晰 (ipvsadm)

总结

总而言之,kube-proxyiptables 模式是一个精巧的“控制器”。它通过监听集群状态,将复杂的服务发现和负载均衡逻辑,翻译成一套标准、高效的 iptables 规则集。而真正繁重的数据包处理工作,则交给了 Linux 内核的 netfilter 框架来完成。

这种设计非常符合 Kubernetes 的通用模式:声明式 API + 控制器。虽然在大规模场景下有其性能瓶颈,但对于大多数中小型集群而言,它仍然是一个简单、可靠且无需额外依赖的优秀解决方案。

posted @ 2025-08-23 16:17  天道酬勤zjh  阅读(17)  评论(0)    收藏  举报