概述
Kubernetes 官方提供了 NodePort 类型的 Service,即给所有节点开通一个相同端口用于暴露该 Service。大多云上负载均衡 (Cloud Load Balancer,CLB) 类型 Service 的传统实现也都是基于 NodePort,即 CLB 后端绑定各节点的 NodePort,CLB 接收外界流量,转发到其中一个节点的 NodePort 上,再通过 Kubernetes 内部的负载均衡,使用 iptables 或 ipvs 转发到 Pod。示意图如下:
腾讯云容器服务 TKE 默认的 CLB 类型 Service 以及默认的 Ingress 实现方式与上述方法相同。然而,TKE 目前还支持 CLB 直通 Pod 的方式,即 CLB 后端直接绑定 Pod IP + Port,不绑定节点的 NodePort。示意图如下:
实现方式分析
传统 NodePort 方式问题分析
通常会使用 CLB 直接绑定 NodePort 此方式来创建云上 Ingress 或 LB 类型的 Service,但此传统 NodePort 实现方式会存在以下问题:
流量从 CLB 转发到 NodePort 后还需进行 SNAT 再转发到 Pod,造成额外的性能损耗。
如果流量过于集中到某几个 NodePort 时(例如,使用 nodeSelector 部署网关到固定几台节点上),可能导致源端口耗尽或 conntrack 插入冲突。
NodePort 本身也充当负载均衡器,CLB 绑定过多节点 NodePort 时可能导致负载均衡状态过于分散,导致全局负载不均。
CLB 直通 Pod 方式优势
使用 CLB 直通 Pod 的方式不但不会存在传统 NodePort 方式的问题,还具备以下优势:
由于没有 SNAT,获取源 IP 不再需要
externalTrafficPolicy: Local
。 实现会话保持更简单,仅需让 CLB 开启会话保持即可,不需要设置 Service 的
sessionAffinity
。操作场景
使用 CLB 直通 Pod 通常有以下场景:
需在四层获取客户端真实源 IP,但不期望使用
externalTrafficPolicy: Local
的方式。 需进一步提升网络性能。
需会话保持更容易。
解决全局连接调度的负载不均。
前提条件
Kubernetes 集群版本需高于1.12。CLB 直接绑定 Pod 时检查 Pod 是否 Ready,需查看 Pod 是否 Running、是否通过 readinessProbe,及是否通过 CLB 对 Pod 的健康监测,此项依赖于
ReadinessGate
特性,该特性在 Kubernetes 1.12 开始支持。