Tip

云负载均衡(Cloud Load Balancer,简称 云LB)的核心工作原理是将客户端的并发访问流量,通过预设的转发策略和调度算法,均匀、合理地分发到后端的多个云服务器(ECS/实例)上,以此消除单点瓶颈,提升系统的整体并发处理能力与高可用性


核心组件

  • 虚拟IP(VIP):云LB对外暴露的统一访问入口。公网LB使用弹性公网IP,私网LB使用内网虚拟IP。
  • 监听器(Listener):负责监听特定端口上的网络请求(如 HTTP 80、HTTPS 443、TCP 8080),并根据规则分发流量。
  • 转发策略/路由规则:决定流量的去向。例如在七层负载均衡中,可以根据不同的域名(Host)或URL路径(Path)将请求发往不同的服务器组。
  • 后端服务器组(Backend Server Group):接收并处理请求的真实云服务器集群。

工作流程

[客户端请求] ──> [统一入口: VIP] ──> [监听器过滤] ──> [算法/策略筛选] ──> [健康的后端服务器]
  • 接收请求
    客户端通过域名解析(DNS)访问云LB绑定的虚拟IP(VIP)
  • 监听与匹配
    云LB的监听器截获该请求,检查其使用的协议和端口是否与配置匹配。如果不匹配则直接拒绝;如果匹配,则准备将请求投递给后端。
  • 策略评估与隔离
    监听器会结合健康检查机制,实时剔除那些已经发生故障的后端服务器,确保流量只会被分发到“健康”的资源上。
  • 算法调度与转发
    监听器根据预设的调度算法(如轮询、加权轮询、最小连接数、源IP Hash),选出一台最合适的后端服务器,并将请求包转发过去。服务器处理完后,再将结果返回给客户端。

四层/七层

特性四层负载均衡(例如:NLB / CLB)七层负载均衡(例如:ALB)
工作层级传输层(TCP/UDP 协议)应用层(HTTP/HTTPS/QUIC 协议)
工作原理不拆包。只分析IP和端口,通过修改数据包的源/目的IP和端口(NAT技术),直接将请求快速转发给后端服务器。拆包代理。LB先与客户端建立TCP连接,解析应用层内容后,再与后端服务器建立新的TCP连接(反向代理模式)。
转发依据源IP、目的IP、端口、协议URL路径、域名、Cookie、HTTP请求头等
适用场景适合超大流量、对延迟极度敏感、不需要识别业务内容的场景(如视频流媒体、游戏连接)。适合需要精细化路由的复杂 Web 应用、微服务架构、动静分离、灰度发布等场景。

常用调度算法

  • 轮询/加权轮询(Round Robin):按顺序挨个分发请求。如果性能不同的服务器混用,可设置“权重”,性能好的服务器接收更多流量。
  • 最少连接数(Least Connections):优先把新请求发送给当前并发连接数最少的服务器,适合处理请求耗时差异较大的业务(如长连接服务)。
  • 源IP哈希(Source IP Hash):根据客户端的 IP 地址计算哈希值,使来自同一个 IP 的请求始终分发到同一台后端服务器。常用于保持用户的登录状态(会话保持)。

架构流派

四层云 LB + 集群内 Ingress Controller(最经典、最通用)

  • 组合方式:购买云厂商的 四层 LB 挂在最前面,后端对准集群内的 Nginx Ingress Pod
  • 流量走法
    1. 外部流量打到云四层 LB。
    2. 四层 LB 像个纯粹的搬运工,只看 TCP 端口,闭着眼睛把流量甩给节点的 NodePort。
    3. 流量进入集群后,由集群内的 Nginx Ingress 承担七层路由的重任,拆开 HTTP 包,根据 URL(如 /order)分流给不同的业务 Pod。
  • 优点省钱且极其灵活。只需要买一个便宜的四层云 LB 守大门,集群内部的七层路由规则(如灰度、限流)全部用 Yaml 写在 K8s 里,不需要每次都去调云厂商的 API。

七层云 LB 直接当 Ingress(云原生直通模式)

  • 组合方式:在 K8s 里写一个标准的 Ingress Yaml,云厂商的控制器在外面自动为创建一个云七层 LB
  • 流量走法
    1. 外部流量直接打到云七层 LB。
    2. 云七层 LB 在云端直接解密 HTTPS 证书,直接读取 HTTP 的 Path(如 /api/v2)。
    3. 云七层 LB 绕过集群内所有的 Nginx 组件,直接把流量弹射到业务 Pod 的 IP 上
  • 优点链路最短,性能调优省心。集群内少了一层 Nginx Pod 的维护成本,证书管理、DDoS 防御全部托管给云厂商的硬件级七层 LB。
  • 缺点:贵。并且云七层 LB 的高级路由功能往往受限于云厂商的控制台功能,不如自建的 Nginx/Envoy 插件生态那么丰富。

优化

流量策略

背景

云LB会自动把集群里的每一个工作节点(Worker Node)都挂载到自己的后端服务器列表里。
外部流量打进来时,云 LB 会根据轮询(Round Robin)或最小连接数等算法,把流量均匀地甩给集群中的任意一个节点

问题产生

当流量落到一个节点上时,会面临两种命运(直连/转发)。假设 Ingress Pod(后端应用)只运行在 Node A 上,但云 LB 把流量甩给了 Node B

  1. 流量落地:外部流量到达 Node BNodePort 端口。
  2. 内核检查:Node B 的内核网络栈(kube-proxy 的 iptables/IPVS 规则)一看:“哦,这个包是来找 Ingress Pod 的。”
  3. 发现扑空:Node B 检查了一下自己本地,发现自己身上并没有运行 Ingress Pod。
  4. 内部倒手(跨节点转发):Node B 只能通过内部的 Calico 网络(BGP 或 IPIP 隧道),把这个数据包跨网络再次转发给 Node A
  5. 到达终点:Node A 收到 Node B 倒手过来的包,最终送进 Ingress Pod。

问题

  • 多跳损耗(Extra Hop):流量在集群内部无谓地多跨了一次网络,导致网络延迟(Latency)增加
  • 丢失真实客户端 IP:当 Node B 把包倒手给 Node A 时,为了让响应包能原路返回,Node B 会对数据包做一次 SNAT(源地址转换)。这导致 Ingress Pod 拿到的“客户端 IP”全都变成了 Node B 的内网 IP,你在应用日志里根本看不见真正用户的公网 IP。

解决

spec:
  externalTrafficPolicy: Local  # 默认为 Cluster

参数修改影响

1. 云 LB 的健康检查联动

当改为 Local 后,K8s 上的云厂商组件(CCM)会通知云 LB:“请开启特殊的端口健康检查!”

  • 云 LB 会去主动探测所有节点的特殊端口。
  • Node A 身上有 Ingress Pod,它回应:“我这里有货,健康!” -> 云 LB 保留 Node A
  • Node B 身上没有 Ingress Pod,它回应:“我这里没货,不健康!” -> 云 LB 立刻把 Node B 从后端列表中剔除(隔离)

2. 完美的流量路径

此时,云厂商的公网 LB 只会把流量甩给真正运行了 Ingress Pod 的节点(Node A)

  • 流量到达 Node A 后,内核直接直通本地的 Pod。
  • 零跨节点转发(没有多跳,延迟极低)。
  • 保留真实客户端 IP:因为不需要 Node 之间倒手,Node A 不会做 SNAT。你的 Ingress(Nginx)日志里可以清清楚楚地看到每一个外部用户的真实公网 IP。

策略对比

流量策略 (externalTrafficPolicy)Cluster(默认行为)Local(生产推荐优化)
云 LB 后端挂载哪些节点集群内的所有 Worker 节点只有当前运行了该 Pod 的节点
集群内部是否二次转发(如果流量砸中了没有 Pod 的节点)(直达目标节点,本地直接消费)
客户端真实 IP 保持丢失(变成宿主机内网 IP)完美保留(看到用户真实公网 IP)
负载均衡均衡度云 LB 级别绝对均衡,但由于内部转发,Pod 负载可能略有倾斜流量直接精准按 Pod 数量平摊,完全由云 LB 调度