3. Kubernetes Service 与流量分发:ClusterIP / NodePort / LoadBalancer 工作原理、iptables 与 IPVS 模式对比

Kubernetes Service 是集群内部流量分发与外部访问的核心抽象层。它为一组动态变化的 Pod 提供稳定的虚拟 IP(ClusterIP)和 DNS 名称,并承担客户端请求的负载均衡。理解 Service 的四种类型(ClusterIP、NodePort、LoadBalancer、ExternalName)以及后端代理模式(iptables 与 IPVS),是排查蓝绿发布过程中流量异常、连接中断、灰度比例失效等问题的前提。

3.1 Service 类型与流量分发路径

Kubernetes 提供四种 Service 类型,分别对应不同的网络暴露层级和流量入口。下表总结了它们的核心差异与典型使用场景:

Service 类型 虚拟 IP 范围 外部可达性 典型场景 蓝绿发布中的关键作用
ClusterIP 集群内部虚拟 IP(默认) 仅集群内部可达 微服务间内部 RPC、API 调用 蓝绿两组 Pod 通过同一个 ClusterIP 实现内部流量切换
NodePort 每个节点上的静态端口(30000-32767) 通过 <NodeIP>:<NodePort> 从集群外部访问 开发测试环境、小型集群对外暴露 蓝绿发布期间可通过不同 NodePort 临时验证新版本
LoadBalancer 云厂商负载均衡器分配的公共 IP 通过负载均衡器公网 IP 访问 生产环境对外暴露服务(AWS ELB、GCP LB、阿里云 SLB) 蓝绿发布时通过负载均衡器权重或后端组切换实现平滑迁移
ExternalName 无虚拟 IP,返回 CNAME 记录 通过 DNS 解析到外部域名 将集群外服务映射为集群内 Service 名称 蓝绿发布中不直接参与流量切换,但可用于外部依赖的优雅降级
排查要点: 蓝绿发布过程中,如果流量未按预期切换到新版本 Pod,首先检查 Service 的 selector 标签是否同时匹配了蓝绿两组 Pod。若标签重叠,流量会按比例分发到两组 Pod,导致“部分切换”现象。

3.2 ClusterIP 与 NodePort 工作原理

ClusterIP 是 Kubernetes Service 的默认类型。kube-proxy 组件在集群每个节点上监听 API Server 的 Service 与 Endpoint 变化,并维护一套转发规则。当客户端 Pod 通过 ClusterIP 发起请求时,数据包经过以下路径:

  1. DNS 解析: 客户端通过 CoreDNS 将 Service 名称解析为 ClusterIP。
  2. 节点内核转发: 数据包到达节点网络栈,匹配 kube-proxy 写入的 iptables 或 IPVS 规则。
  3. 负载均衡选择: 规则将请求 DNAT(目标网络地址转换)为选中的后端 Pod IP 与端口。
  4. Pod 响应: 响应包经过 conntrack 记录,自动还原源地址为 ClusterIP,客户端无感知。

NodePort 在 ClusterIP 基础上,额外在每个节点的指定端口上监听入站流量。数据包到达节点 <NodePort> 后,内核将其 DNAT 到 ClusterIP,后续路径与 ClusterIP 一致。

关键指标:
  • ClusterIP 范围: 默认 10.96.0.0/12,可通过 --service-cluster-ip-range 配置。
  • NodePort 范围: 默认 30000-32767,可通过 --service-node-port-range 配置。
  • 端口冲突: 多个 Service 不能共享同一个 NodePort,但不同节点上的相同 NodePort 可以指向不同 Service。

3.3 LoadBalancer 工作原理与云厂商集成

LoadBalancer 类型是 NodePort 的云原生扩展。当 Service 类型设置为 LoadBalancer 时,Kubernetes 会调用云厂商的 API 创建一个外部负载均衡器(如 AWS NLB、GCP TCP/UDP LB、阿里云 SLB),并将所有节点的 NodePort 注册为后端目标。

流量路径如下:

  1. 外部请求 到达云负载均衡器的公网 IP。
  2. 负载均衡器 将请求转发到集群任意节点的 <NodePort>。
  3. 节点内核 通过 iptables/IPVS 将请求 DNAT 到目标 Pod。
蓝绿发布陷阱: 云负载均衡器通常有健康检查机制。如果新版本 Pod 的健康检查路径(readinessProbe)配置错误,负载均衡器会认为后端不可用,导致流量全部留在旧版本。排查时务必检查云控制台的后端组健康状态。

3.4 iptables 与 IPVS 模式对比

kube-proxy 支持两种代理模式:iptables(默认)和 IPVS(推荐用于大规模集群)。两者都工作在节点的网络栈中,但实现原理和性能特征差异显著。

下图展示了两种模式下数据包从客户端 Pod 到目标 Pod 的转发路径对比:

iptables 模式 vs IPVS 模式 数据包转发路径对比 iptables 模式 客户端 Pod 请求 PREROUTING 链 KUBE-SERVICES DNAT 到 Pod IPVS 模式 客户端 Pod 请求 IPVS 虚拟服务 调度算法选择 DNAT 到 Pod iptables 模式:规则链线性匹配,规则数量随 Service 增长呈 O(n) 性能下降 IPVS 模式:哈希表查找,规则数量随 Service 增长呈 O(1) 性能稳定,支持更多调度算法

下表从多个维度对比两种模式,帮助你在蓝绿发布场景中选择合适的代理模式:

对比维度 iptables 模式 IPVS 模式
数据面实现 Linux 内核 Netfilter 框架,规则链线性匹配 LVS(Linux Virtual Server)内核模块,哈希表查找
规则数量影响 规则数增加时性能线性下降(O(n)) 规则数增加时性能基本恒定(O(1))
调度算法 仅支持随机(random) 支持 rr、wrr、lc、wlc、sh、dh 等多种算法
连接跟踪 依赖 conntrack,高并发下可能丢包 支持更高效的连接跟踪,减少 conntrack 压力
大规模集群(>1000 Service) 规则更新延迟高,CPU 开销大 规则更新快,CPU 开销低
蓝绿发布场景优势 简单稳定,适合中小规模集群 支持权重调度,可精确控制蓝绿流量比例
启用方式 默认模式,无需额外配置 kube-proxy 启动参数 --proxy-mode=ipvs
蓝绿发布最佳实践:
  • 中小规模集群(< 500 Service): 使用 iptables 模式,简单可靠,排查时可直接查看 iptables 规则链。
  • 大规模集群(> 500 Service)或需要精细流量控制: 切换为 IPVS 模式,利用加权轮询(wrr)算法实现蓝绿流量按比例分发。
  • 切换 IPVS 后验证: 执行 ipvsadm -Ln 查看虚拟服务与后端 Pod 的映射关系,确认调度算法生效。

3.5 蓝绿发布中的 Service 流量切换策略

在蓝绿发布过程中,Service 的 selector 标签是流量切换的“开关”。以下两种策略分别对应不同的切换粒度:

策略一:标签全量切换(粗暴切换)

  • 蓝组 Pod 标签:app: myapp, version: blue
  • 绿组 Pod 标签:app: myapp, version: green
  • Service selector:初始为 app: myapp, version: blue,切换时更新为 app: myapp, version: green
  • 特点: 瞬间切换,所有流量立即指向新版本,适合无状态服务。

策略二:标签交集切换(灰度切换)

  • 蓝组 Pod 标签:app: myapp, version: blue
  • 绿组 Pod 标签:app: myapp, version: green
  • Service selector:app: myapp(同时匹配蓝绿两组)
  • 通过调整两组 Pod 的副本数比例(如蓝 10 副本、绿 1 副本)实现 10:1 的流量分发。
  • 特点: 流量按 Pod 数量比例分发,适合需要逐步验证新版本的场景。
排查案例: 某团队在蓝绿发布时使用标签交集策略,但新版本 Pod 始终未收到流量。排查发现新版本 Pod 的 readinessProbe 失败,导致 Endpoint 控制器未将其加入 Service 的后端列表。执行 kubectl get endpoints <service-name> 确认后端 Pod IP 列表,发现缺少新版本 Pod 的 IP。

3.6 故障排查常用命令速查

以下命令在蓝绿发布网络故障排查中高频使用,建议熟记:

排查目标 命令 预期输出
查看 Service 详情 kubectl describe svc <service-name> ClusterIP、Port、Selector、Endpoints 列表
查看 Endpoint 列表 kubectl get endpoints <service-name> 后端 Pod IP 与端口列表
查看 Pod 标签 kubectl get pods --show-labels Pod 名称、状态、标签键值对
查看 iptables 规则 iptables -t nat -L KUBE-SERVICES -n Service 对应的 DNAT 规则链
查看 IPVS 虚拟服务 ipvsadm -Ln 虚拟 IP、端口、调度算法、后端 Pod 权重
查看 kube-proxy 日志 kubectl logs -n kube-system <kube-proxy-pod> 规则同步错误、Service 变更事件
快速定位技巧: 当蓝绿发布后流量未切换,优先执行 kubectl get endpoints <service-name> 确认后端 Pod IP 是否包含新版本 Pod。如果新版本 Pod IP 不在列表中,说明 Service 的 selector 未匹配或 Pod 未通过 readinessProbe。