开篇答案
Ingress负载均衡策略的核心是:通过Annotation配置和上游服务权重控制,在Kubernetes集群入口处实现流量分发,生产环境最常用的方案是Nginx Ingress Controller配合ingress-nginx注解,实现轮询、会话保持、灰度发布等多种策略。
nginx ingress 负载均衡策略对比:哪种方案最适合你的业务
轮询与加权轮询:默认策略的适用边界
Ingress Controller默认采用轮询算法,请求按顺序分发到后端Pod,这种策略在所有Pod资源配置相同、请求处理耗时相近的场景下表现良好,默认配置下,Nginx Ingress使用round-robin,每个后端Pod获得请求的概率均等。
但生产环境很少所有Pod完全同质,当某些Pod所在节点资源更充裕时,轮询策略无法感知这些差异,此时需要加权轮询,通过Pod的weight属性或Service的TargetPort配置调整流量比例。
# 示例:同一Service下不同Deployment的权重配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: weighted-ingress
annotations:
nginx.ingress.kubernetes.io/server-weight: "80"
加权轮询适合后端服务版本迭代期,比如新版本Pod分配20%流量、旧版本分配80%,渐进式放量。
最少连接策略:长耗时请求的救星
当后端服务处理时间差异明显,比如一个接口需要秒级响应、另一个接口毫秒级返回,轮询策略会导致请求堆积在慢Pod上,Ingress-Nginx支持least-conn算法,每次请求分发时优先选择当前活跃连接数最少的后端。
配置方式:
nginx.ingress.kubernetes.io/load-balance: "least_conn"
行业共识认为,API网关、流式推送、WebSocket长连接这三类业务场景,最少连接策略比轮询的吞吐量提升显著,但要注意,least_conn需要Controller统计每个后端的连接数,会额外消耗少量CPU,在每秒请求量低于1000的集群中,性能差异几乎无感。
一致性哈希:让同源请求永远落在同一个Pod
基于客户端IP或请求特征的一致性哈希,解决的是会话保持和缓存命中率问题,Ingress-Nginx通过nginx.ingress.kubernetes.io/upstream-hash-by注解实现:
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
这个配置将请求URI作为哈希键,相同URI的请求总是路由到同一Pod,典型场景是多副本的Redis缓存服务,如果缓存数据不共享,哈希策略能提高缓存命中率,减少回源压力。
业内专家指出,一致性哈希在Pod重启、扩缩容时只会影响少量哈希桶的映射关系,不会像普通取模哈希那样导致大量缓存失效,但它的弊端是
负载不均当某个URI的请求量特别大时,对应的Pod会成为热点。
会话保持策略对比:Cookie与IP的取舍
Ingress负载均衡策略中,会话保持是电商、支付类业务刚需,Ingress-Nginx提供两种方式:
| 策略类型 | 配置方式 | 优点 | 缺点 |
|---|---|---|---|
| Cookie亲和性 | nginx.ingress.kubernetes.io/affinity: "cookie" |
精确到用户会话,不受IP变化影响 | 需要Cookie支持,移动端可能禁用 |
| IP哈希 | nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr" |
无需客户端配合 | NAT环境下多用户共享IP,负载不均 |
Cookie亲和性适合需要跨请求保持登录状态的业务,比如购物车、订单流程,但要注意,如果后端Pod整体重启,所有会话都会失效,需要业务层做Session持久化兜底。
ingress 负载均衡算法怎么选:四个判断维度
按业务类型匹配策略
- 静态页面、图片资源:默认轮询足够,响应快、无状态
- 用户登录、支付接口:Cookie会话保持优先
- 流媒体、实时消息推送:最少连接策略更稳
- 数据缓存、搜索服务:URI一致性哈希最合适
按集群规模调整
集群规模在10个节点以内,任何策略的性能差异都微乎其微,优先选配置简单、易排查问题的方案。超过50个节点后,需要考虑Ingress Controller本身的性能瓶颈,此时建议:
- Controller副本数调整为至少2个,避免单点故障
- 开启
worker-processes自动调优 - 配合HPA自动扩缩容,应对流量洪峰
按流量特征决策
流量特征比业务类型更具参考价值,如果请求平均耗时在50ms以内,轮询和最少连接基本等价;如果存在超过500ms的慢请求,必须用最少连接,否则慢Pod会持续累积请求。
按故障域隔离需求
跨可用区部署时,需要拓扑感知路由,Ingress-Nginx在较新版本中支持nginx.ingress.kubernetes.io/service-locality注解,将请求优先路由到同可用区Pod,减少跨机房延迟和带宽费用。
kubernetes ingress 负载均衡配置:从零到生产的三步实操
第一步:确认Ingress Controller版本能力
不同版本的Ingress-Nginx支持的负载均衡注解差异较大,先执行:
kubectl get deployment -n ingress-nginx ingress-nginx-controller -o yaml | grep image
确认镜像版本。v1.5.0以上版本完整支持load-balance
、upstream-hash-by、affinity三大核心注解,旧版本可能只支持部分策略,升级前需要核对官方Changelog。
第二步:编写正确的Annotation配置
一个完整的生产级Ingress配置示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-gateway
annotations:
nginx.ingress.kubernetes.io/load-balance: "least_conn"
nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1/orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8080
这里proxy-next-upstream配置允许在后端503或超时时自动重试下一个Pod,配合least_conn策略,实际效果比单纯依赖负载均衡算法更可靠。
第三步:验证和监控策略生效
配置完成后,用以下命令验证:
kubectl exec -it ingress-nginx-controller-xxxx -- cat /etc/nginx/nginx.conf | grep "least_conn"
如果能搜到least_conn关键字,说明策略已注入Nginx配置。监控维度要关注三个指标:
- 每个Pod的请求数分布,确认是否均匀
- P99延迟,排除热点Pod拖慢整体
- 后端5xx错误率,快速发现故障节点
ingress 负载均衡策略排查:生产环境常见问题与解法
会话保持失效的真相
Cookie亲和性依赖Nginx生成的route Cookie,但Ingress-Nginx默认Cookie路径是,如果后端应用也设置了同名Cookie,会导致冲突,排查时先确认:
- 浏览器开发者工具中Cookie的Domain和Path是否匹配
- 后端服务是否重写了
Set-Cookie头 - Ingress中是否配置了
affinity-mode: persistent
轮询策略下请求不均衡
即使配置了默认轮询,实际请求分布也可能失衡,多数情况下是Pod的readinessProbe探针间隔过长,导致新Pod尚未就绪就已被加入Endpoints列表,调整periodSeconds为5秒以内,并确保failureThreshold不超过3次。
哈希策略下热点请求压垮单Pod
URI哈希策略遇到某个热点接口时,单Pod流量可能超过4倍均值,缓解方案:
- 在业务层拆细URI粒度,比如加入随机参数或用户ID维度
- 改用
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri$arg_userid"组合键 - 为热点服务单独部署Ingress,配置不同的负载均衡策略
Ingress负载均衡策略的软实力:优雅降级与故障转移
主动健康检查的配置细节
默认情况下Ingress-Nginx依赖Kubernetes的Pod就绪状态判断后端可用性,但这种方式有延迟,生产环境建议开启主动健康检查:
nginx.ingress.kubernetes.io/upstream-vhost: "internal-check.example.com"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "3"
主动检查能提前发现端口存活但业务逻辑异常的后端,比如内存泄漏导致响应缓慢的Pod,检查间隔建议设置10秒,超时2秒,连续失败3次标记为不可用。
多Ingress Controller的负载分担
单个Ingress Controller承载所有流量,本身就可能是瓶颈。较大规模的集群建议部署两套Controller,一套负责南北向流量,一套负责东西向内部调用,通过不同ingressClassName区分。
这样配置后,负载均衡策略可以独立调整,比如南北向用会话保持,东西向用轮询,互不干扰。
金丝雀发布时的策略联动
Ingress-Nginx的Canary注解与负载均衡策略配合使用,能实现精细化的流量灰度:
nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "10"
金丝雀权重控制的是Ingress层面的流量比例,而负载均衡策略控制的是同一Ingress下多个Pod间的分配,两者叠加后,新版本服务整体只承受约10%的流量,但这10%的流量在各Pod间的分配仍由load-balance注解决定。
Ingress负载均衡策略没有万金油方案,核心原则是先明确业务请求特征,再选择对应算法,最后通过监控数据持续调优,把轮询、加权、哈希、会话保持这几张牌用好,Kubernetes入口流量就能稳如磐石。
关于Ingress负载均衡策略的常见问题
Ingress-Nginx和Traefik的负载均衡策略有什么区别?
Ingress-Nginx原生支持加权轮询、最少连接、一致性哈希三种主要算法,配置灵活度高,适合复杂业务场景,Traefik默认支持轮询和加权轮询,但它的会话保持配置更简单,内置了更友好的Dashboard面板,如果团队熟悉Nginx语法,Ingress-Nginx上手更快;如果追求轻量和可视化运维,Traefik更合适。
会话保持配置了为什么仍然在多个Pod间跳变?
最常见原因是Ingress的affinity配置作用域是单个Ingress规则,如果前端请求经过了多个Ingress或Service,Cookic亲和性会被打断,Nginx的Cookie会话保持依赖浏览器保存Cookie,如果客户端禁用了Cookie,或者后端服务在响应中覆盖了Set-Cookie头,会话保持就会失效,排查时从浏览器开发者工具查看Cookie的Domain、Path和Expires字段,确认配置是否生效。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/562175.html



