后端扩容后负载均衡不一定要手动加节点,云负载均衡和Kubernetes Service都能自动感知节点变化,只有传统静态配置的Nginx upstream需要手动修改并重载。你手头用的是哪一种负载均衡,直接决定了扩容时要不要动手去“打招呼”。
自建Nginx负载均衡扩容后要手动加节点吗?
先聊最常见的自建Nginx场景,假设你的upstream配置长这样:
upstream backend_cluster {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
这里写死了后端的IP和端口,Nginx的worker进程在启动时读取这份通讯录,后续请求就在这两个地址之间分发,你在10.0.1.12上起了新服务实例,负载均衡器完全不知道新邻居的存在,因为通讯录里没有登记这号人,流量碰都不会碰新机器,这就是静态配置的天生限制:负载均衡器不主动感知后端实例的变化,扩容后要手动加节点,新服务才能接入流量。
手动加节点的方法有两条路,一是改配置后执行nginx -s reload,让主进程重新加载upstream定义;二是引入服务发现模块,让Nginx自己去查后端列表,下面分开说。
用reload让Nginx认识新节点,连接不会断
手动加节点的标准姿势是这样:
nginx -t nginx -s reload
nginx -t先验证配置语法,确认无误再执行reload,避免改错配置导致服务起不来,reload和restart有本质区别,restart会杀掉所有worker进程再重新启动,连接必然中断;reload则是启动新的worker进程,新连接走新配置,老worker在存量请求处理完后自动退出,实现平滑切换,对调用方几乎无感知。
只要你的新后端服务本身没问题,reload后新节点的权重就会参与调度,流量按轮询或权重策略分过去,多数中小团队几年的扩容操作就是这条命令走下来的,稳定可靠,成本为零,缺点是每次扩容都得人工介入。
引入OpenResty和Consul,Nginx自动发现后端节点
如果后端扩容频繁,天天改配置文件再reload终归是件重复劳动,行业里有套成熟做法是OpenResty的
balancer_by_lua模块对接Consul服务发现,让Nginx实时“刷通讯录”。
工作机制可以这样理解:后端服务启动时主动向Consul注册自己,Nginx通过Lua脚本定时拉取Consul里的节点列表,存进共享内存,请求到达时,Lua代码从这个列表里选一台健康的服务转发,后端扩容后,新节点注册进Consul,Nginx在下一个轮询周期就能感知到,全程不需要人工碰配置文件。
这个方案的优势是化被动为主动,后端扩容和缩容都自动同步,弹性伸缩的落地体验好得多,代价是架构里多了Consul组件,部署和运维的复杂度有所上升,适合后端服务数较多、扩容动作频繁的团队。
云负载均衡扩容后节点自动同步吗?
云厂商提供的负载均衡产品,像简米云SLB、酷番云CLB、华为云ELB,扩容后节点自动同步吗?答案是分场景的,取决于你用什么方式管理后端服务器。
手动添加实例的场景,需要在控制台点一下
如果你是在云控制台手工把ECS实例加进负载均衡的后端服务器组,那扩容新机器时,负载均衡当然不会自动认识它,你得去控制台把新实例勾选进服务器组,或者通过OpenAPI调接口完成挂载,本质上还是“手动加节点”,只不过操作门槛从改配置文件变成了点按钮,简单了不少,但自动化程度不高。
配合弹性伸缩组,扩容后自动挂载
如果负载均衡绑定了弹性伸缩组,情况就不一样了,伸缩组负责拉起和释放ECS实例,负载均衡和伸缩组之间有现成的同步机制,弹性伸缩组创建新实例时,会自动把实例挂载到负载均衡后端;缩容时也会自动卸载,整个流程无需人工干预,扩容后负载均衡会主动把新节点纳入流量调度。
据公开资料,主流云厂商都支持这种联动方式,前提是你在创建伸缩组时正确关联了负载均衡实例,用云产品的正确姿势是让负载均衡管转发,伸缩组管机器,二者自动配合,省去人工加节点的心力。
云容器服务上挂载的负载均衡
在云上跑K8s时,通常通过LoadBalancer类型的Service对外暴露服务,这一类型的负载均衡后端不由用户手工指定,而是云厂商的Controller监听集群里节点和Pod的变化,自动同步后端服务器列表,更新监听端口和后端权重,后端Pod扩容,负载均衡在几十秒内就会感知新节点并开始转发流量。
所以云环境下的答案很明确:只要你的负载均衡对接的是弹性伸缩组或容器服务,后端扩容后节点自动同步,不需要手动加。
K8s场景负载均衡节点不生效怎么办?
在Kubernetes里,负载均衡自动发现节点依赖Service、Endpoints和kube-proxy三者协作,如果遇到负载均衡节点不生效的情况,排查顺序比乱试配置重要。
先检查Pod和Endpoints是否同步
扩容的Pod有没有进入Ready状态?只要Pod没有通过ReadinessProbe探针,Service的Endpoints列表里就不会出现这个Pod的IP,负载均衡自然收不到新节点,这是最简单的环节,也最容易因探针配置问题翻车。
kubectl get pods -o wide kubectl get endpoints <service-name>
如果Pod已经Ready,但Endpoints里没有新地址,重点检查Service的selector是否匹配了新Pod的标签,或者新Pod的节点是否注入了正确的网段,Endpoints不更新,后面所有环节都白搭。
查看云负载均衡后端实例列表
云上的K8s集群如果用LoadBalancer类型的Service,云厂商Controller会在负载均衡后端维护节点列表,这里有个容易踩坑的细节:Service的externalTrafficPolicy字段,当策略为Local时,请求只会转发到当前节点上的Pod,如果新Pod没调度到期望的节点,流量就可能一直在旧节点上循环,看起来像新节点不生效,排查时先确认该字段的设置,再去云控制台核对负载均衡后端实际状态。
自建Ingress的同步机制
自建Nginx Ingress时,Ingress Controller会watch集群中Service和Endpoint的变化,自动生成Ngin
x配置并热加载,按理说也不需要手动加节点,但部分版本的Controller存在缓存同步延迟,扩容后新节点要过一阵子才进入upstream列表,遇到这种情况,查看Ingress Controller日志,确认是否收到Endpoint更新的事件,确认正常后可以放宽心等等看,不用急着去手动改Nginx配置。
行业共识认为,K8s的设计目标就是让负载均衡自动适配应用规模变化,手动加节点这件事,在K8s里反而是反常操作,除非你用了非常特殊的自定义负载均衡组件。
常见问题:后端扩容负载均衡要手动加节点吗?
后端扩容后流量没进新节点,是负载均衡不识别它吗?
不一定是负载均衡的问题,先确认新后端服务本身处于健康状态,端口在监听,健康检查返回正常,再确认负载均衡的后端列表里能看到新节点,如果是静态Nginx,配置里没有新节点,那就是真没接上;如果是云负载均衡,看一眼控制台后端服务器组;如果是K8s,查Endpoints有没有新Pod地址,多数情况下,按这个路径排查都能定位到原因,而不是盲目认为是负载均衡没自动识别。
自建Nginx新加后端节点后必须reload吗?
静态upstream配置下,必须要reload,Nginx的worker进程不会自动读配置文件,不reload等于新节点永远没法被调度,用nginx -s reload平滑重载,不影响存量连接,如果你不想每次扩容都reload,给Nginx接上Consul或etcd做动态upstream,扩容后自动生效,reload就不再必要了。
网关扩容后需要重启吗?
后端服务的扩容,和网关实例本身的扩容是两回事,新起的后端服务只要注册到了负载均衡的服务发现机制里,网关不需要重启,如果是给负载均衡手动添加了新的网关实例节点,那要看网关的方案类型:静态配置的网关集群中,新实例加入时需要同步配置并重启或重载;基于服务注册的网关集群里,新实例启动后自动注册,老节点无需任何动作,简而言之,网关不负责感知后端新增节点,它只需要保证自己的节点信息是最新的。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/633322.html





