☰
ax调度从入门到实践:Kubernetes自动扩缩容配置与避坑指南
2026/9/26 19:04:10 网站建设 项目流程

1. 先搞清楚“ax调度”到底在调什么

1.1 从网络热词到技术概念的对应关系

最近“ax调度”这个词在运维和技术社区里出现的频率明显变高了。很多人第一次看到这个缩写时都有点懵,ax是什么?其实结合云原生和基础架构的语境来看,ax对应的是autoscaling的简写,也就是自动扩缩容。而“调度”两个字,则点出了这门技术的核心——不是简单的“资源不够就加机器”,而是有一套完整的调度逻辑在背后运作。

前两年大家讨论自动扩缩容,重心基本在“要不要做”“能不能做”上。现在容器、微服务、云基础设施已经大面积落地,问题的焦点已经转向“怎么做才不翻车”。ax调度的热度上升,本质上是因为它从一项锦上添花的能力,变成了线上稳定性体系的刚需。

我个人的理解是,ax调度可以拆成两个层面。第一层是资源层的伸缩,比如Pod副本数、容器规格、节点的增减。第二层是流量调度层的联动,比如新扩容出的实例要多久才能接到流量、流量分发策略要不要跟着实例状态动态调整。这两层缺一个,系统都会出问题。只看副本数不看启动状态,扩容等于白扩;只看流量不看水位,缩容容易把老实的服务砍到裸奔。

1.2 三层目标:容量、时序、成本

ax调度虽然名字听着技术感很强,但落到实际业务场景里,它真正做的事就三件:匹配容量、匹配时序、匹配成本。

匹配容量是最基础的目标。无论业务是突然被热点带起来,还是因为活动运营的流量蓄水池提前打开,系统都得有办法在分钟级别把服务实例的数量补上来,同时保证不把集群的资源打爆。匹配时序则更进一步,要求系统能预判流量峰值什么时候来、什么时候退潮,提前扩、延后缩,而不是永远在被动追赶。匹配成本更直白,缩容缩不到位,闲置资源就是白花的钱。我曾经见过一个团队,HPA配了之后就没再管过,凌晨两点的流量只有白天的十分之一,但副本数还扛在峰值水位,一个月多烧了大几千的容器费用——这就是典型的只会扩不会缩。

这三个目标之间其实是互相拉扯的。容量保障要求你有富余,成本要求你控制富余,时序要求你在正确的时间点做正确的动作。ax调度要做的事情,就是在这三者之间找平衡点。所以我一直跟别人说,别把它当成一个纯配置层面的东西,它更像是一套运营策略,只不过用代码和策略表达出来了。

1.3 为什么现在才成为大家讨论的焦点

有人可能会问,自动扩缩容不是Kubernetes里早就有的能力吗,怎么现在才火?原因主要有两个。

第一个原因是业务复杂度上来了。以前一个服务拆成几个大的单体,扩缩容的粒度粗,看几个核心指标就能做判断。现在一个服务拆成十几个甚至几十个微服务,每个服务的流量特征不一样、资源需求不一样、冷启动时间不一样,统一用一套策略去扩缩容,根本跑不起来。大家不得不去细挖调度细节,就挖出经验了。

第二个原因是可观测性开始跟上来了。早些年HPA配置开起来之后,指标数据链路断断续续,Metrics Server的数据延迟高、准确度低,扩缩容决策经常基于“脏数据”,出了问题也不知道该信谁。近几年监控、链路追踪和日志体系越来越完善,指标采集的实时性和准确度都上了一个台阶,ax调度才真正有了“敢自动决策”的数据基础。

说白了,ax调度能成为热词,不是因为技术本身多新,而是它走到台前需要的基础设施已经齐了,讨论度自然就上来了。

2. 拆解ax调度的核心设计思路:先想清楚再动手

2.1 伸缩对象的选择:副本数还是资源规格

正式开始设计ax调度方案时,第一个要决定的事情就是:伸缩的对象到底是什么。这里有两类选择,一类是水平伸缩,也就是增减实例数量;另一类是垂直伸缩,也就是调整单个实例的CPU、内存规格。

水平伸缩的思路最直观:一台不够就启动两台,三台不够就四台。它适合无状态服务,因为新起的实例不需要关心旧实例的运行状态,流量可以均匀分摊。垂直伸缩则是在不改实例数量的前提下,把单个实例的资源规格上调,适合有状态服务、单实例吞吐瓶颈明显或者架构上不方便多副本的场景。

这两者在工程实践中的使用频率差距很大。水平伸缩是绝对的主流,因为Kubernetes的HPA、云平台的伸缩组都是围绕它设计的。垂直伸缩实际操作起来要麻烦得多,改规格通常意味着实例重启,瞬间的连接断开对在线服务的影响不小,所以除非场景逼着你这么做,我更倾向于优先考虑水平伸缩。

有意思的是,很多时候线上问题并不是水平伸缩解决不了,而是大家把这两个概念混在一起用。我见过有人抱怨说HPA不够灵敏,副本数加不上来,排查了一圈发现是单个副本的资源规格配得太高,节点上根本塞不下新实例,扩容请求直接Pend。这就是典型的没想清楚伸缩对象,水平扩容被垂直规格卡死的案例。

2.2 触发指标的门道:CPU不是万能的

确定伸缩对象之后,就要选触发扩缩容的指标。很多团队最开始都是从CPU使用率入手的,因为它好理解也容易拿数据。但实际用下来你会发现,CPU指标在不少场景下都有明显的滞后性。

一个典型的例子是突发性的流量尖峰。用户请求突然翻倍时,CPU使用率是随着请求被处理才逐步上升的,这个上升过程需要时间。等到CPU超过阈值触发扩容,新 Pod 再花几十秒甚至几分钟完成启动和注册,流量尖峰可能都已经过去了。更麻烦的是,如果流量尖峰持续时间不长,CPU使用率会迅速回落,HPA 又会把刚扩出来的副本缩掉,形成一次无效的扩缩循环。

所以从工程实践的角度来看,ax调度的指标设计应该分层。第一层是基础资源指标,CPU和内存使用率,适合做兜底和慢速趋势判断。第二层是业务指标,QPS、请求延迟、排队长度、错误率,这些指标更贴近用户体验,反应速度也更快。第三层是自定义指标,比如消息队列的积压数量、数据库连接池的占用率,适合特定业务场景下的精准调度。

举个例子,我之前处理过一个支付回调服务的扩容问题。这个服务平时CPU占用率不到10%,看起来非常清闲,但只要上游业务方批量重推消息,积压消息数会瞬间飙升,而CPU还是稳如泰山。后来我们把消息积压数作为主触发指标,CPU只作为兜底,扩容反应速度从分钟级提升到了秒级。这个方案并不复杂,但它需要对业务特征足够了解,知道这个服务真正会被什么压力打垮。

2.3 调度策略的组合:不只靠一个HPA

在实际的线上环境里,ax调度很少只靠一个HPA就搞定,通常需要多个层级联动。在容器编排平台内部,HPA负责调整工作负载的副本数。在更上层的集群维度,还有Cluster Autoscaler这类组件负责增减节点。而在边缘层往往还会有流量调度策略,把新副本的流量权重从小往大慢慢调。

这三层的调度节奏应该是错开的。HPA的决策周期短,按秒级或分钟级评估;节点伸缩的周期长,因为创建和销毁一台机器通常需要几分钟。如果HPA扩得很激进,节点池却没准备好资源,扩容出来的Pod会一直卡在Pending状态。反过来,如果节点池预留了太多机器,HPA又迟迟不缩容,成本就压不下来。

另外一个被很多人忽略的点是定时与预测。比如一个业务每天早上固定的时间点有访问高峰,晚上十点之后流量明显下降,这种规律性的波动完全可以配合周期性的伸缩策略来提前做资源准备。白天高峰期前二十分钟先把副本数抬到预期水位,高峰结束再缓缓降下来,比纯粹依赖指标触发的效果要稳定得多。

我在实际项目中采取的组合策略通常是:基础水位靠定时策略兜底,业务高峰期的弹性部分靠业务指标触发,最上层的突发流量靠响应速度快的自定义指标来兜住,同时配合就绪探针控制流量切换的节奏。

3. 实操落地的关键配置:可以直接抄作业的细节

3.1 一份可落地的水平伸缩配置

不聊虚的,直接给一份经过实践验证的HPA配置。假设我们有一个订单服务,部署在Kubernetes集群中,用Deployment管理副本,下面是它的伸缩策略配置:

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: order-service-hpa namespace: prod spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: order-service minReplicas: 3 maxReplicas: 20 behavior: scaleUp: stabilizationWindowSeconds: 0 selectPolicy: Max policies: - type: Percent value: 100 periodSeconds: 60 scaleDown: stabilizationWindowSeconds: 300 selectPolicy: Min policies: - type: Percent value: 10 periodSeconds: 120 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 70

这份配置里几个细节值得注意。minReplicas设为了3,保证基础冗余,即使流量全无也不会缩到只剩一个副本。maxReplicas设为20,给足爆发空间,又用上限防止意外死循环把集群资源掏空。scaleUp里的stabilizationWindowSeconds设成了0,意味着扩容决策不做冷却等待,只要指标超过阈值立即把副本数算出并执行。

scaleDown这边的stabilizationWindowSeconds设成了300秒,这是缩容冷却期,避免指标短暂下跌就触发缩容。同时缩容策略的Percent设成10%,意味着每一轮最多缩掉当前副本数的10%,让缩容过程平缓有序。如果你把缩容的冷却窗口改成0,策略又选Max,那你就等于主动欢迎扩缩容颠簸,线上不出问题才怪。

3.2 范围与步进控制:别小看这几个数字

很多人在配置HPA时只关注指标阈值,对minReplicas、maxReplicas和扩缩容步进策略不怎么上心。这几个参数看起来不起眼,但它们才是决定系统稳定性的关键。

先说minReplicas。这个值就是系统的最低水位,正常情况下不应该等于1。一个没有额外冗余的单副本服务,只要Pod出现异常重启,整个服务就直接断流。加上发布上线期间还要滚动更新,单副本连一次零停机发布都做不了。我通常建议核心在线服务的最低副本数不低于2,有条件的话可以给到3。

再说maxReplicas。这个值的设置需要结合下游依赖的容量来评估。如果服务扩容到20个副本,但下游数据库的连接池上限只够15个副本使用,那第16个副本启动之后不仅帮不上忙,还会把数据库拖垮。所以设置上限之前,最好先摸一遍上下游的容量拓扑,把链路里最容易先被打穿的环节找出来。

步进策略的细节也很有意思。scaleUp的periodSeconds设为60秒,配合Percent的100%,表示每60秒最多可以让副本数翻倍。这种激进策略适合请求量可能在短时间内翻几倍的活动场景。scaleDown的periodSeconds设为120秒,配合Percent的10%,表示每两分钟最多缩减现有副本的10%。这样即便指标降到零,系统也需要接近二十分钟才能把20个副本降到3个,给流量回升留出充分的反应时间。

3.3 新实例的优雅启停:启动不等于就绪

HPA扩容成功,Pod数量加上去了,流量也分过去了,但用户的请求反而超时了。这种问题我遇到太多次了,根子在于“新Pod启动完成”和“新Pod可以接流量”是两回事。

以Java服务为例,JVM的启动就需要几十秒,Spring容器加载、数据库连接池初始化、注册中心心跳上报,每一步都要时间。如果没有配置就绪探针,容器刚起来Kubernetes就会把Pod标记为Running,流量调度系统开始往里面打请求。这时候业务代码可能才执行到一半,数据源还没准备好,请求自然大量失败。

所以ax调度在实际落地时必须和就绪探针配合,这是没有商量余地的。配置方式如下:

readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3

这里的关键是探针的检查路径必须真实反映业务是否就绪,而不是只检查进程是否存活。如果服务里没有暴露合理的健康检查接口,建议先补一个,包含依赖组件的基本连通性检查。initialDelaySeconds给了一个缓冲期,避免Pod刚创建还没监听端口时探针就开始失败。failureThreshold设成3,允许少量抖动,同时避免误判时间过长导致新Pod一直被标记未就绪。

还有一个小细节,就是terminationGracePeriodSeconds。默认情况下这个值是30秒,如果服务处理一个请求需要较长时间,缩容时Pod被删掉,还没处理完的请求就会断掉。对于长连接或消息推送类的服务,建议把优雅停机时间适当调大,同时在应用层配合信号处理,让进程先停止接收新请求,再处理完存量请求后退出。

4. 常见问题与排查技巧实录

4.1 颠簸扩缩容:高压锅式的一紧一松

ax调度上线初期最容易遇到的现象就是颠簸,也是网上被吐槽最多的“扩了缩、缩了扩”的循环。表现是副本数在短时间内跳来跳去,今天20个副本,半小时后降到4个,再过一会儿又升到15个。流量一抖,整个系统跟着坐过山车。

引发颠簸的原因基本上有两个。一是指标本身抖动剧烈,比如服务的CPU使用率在50%到80%之间反复横跳,导致阈值判断来回翻转。二是缩容的稳定窗口设置得太短,甚至被直接关掉了。指标高的时候扩容,指标刚往下掉一点点立刻触发缩容,结果扩容动作还没完全生效,流量重新涨回来又得再扩一遍,永远在追赶。

解决思路分两步走。第一,在指标侧做平滑处理,可以配合Prometheus等监控系统对原始指标做区间聚合,比如取最近5分钟的平均值再做决策,而不是用一分钟的瞬时值。第二,把缩容的稳定窗口调大一些,比如300秒以上,让系统在拉长的时间维度上确认流量真的降下来了再动手。扩缩容是异步动作,跟不上指标跳动的节奏才是正常情况,别指望它像CPU中断响应一样实时。

4.2 扩容来不及:尖峰流量下的手忙脚乱

另一个高频问题是扩容动作触发了,但远水解不了近渴。流量在30秒内翻了三倍,HPA评估周期加上指标采集延迟通常需要几十秒,新Pod需要调度、拉镜像、启动进程、通过探针检查,这一整套流程下来需要好几分钟。线上用户体验已经受损了,副本数才慢慢爬升。

这种情况下,依赖HPA的“事后反应”是不够的。我在实践中用的办法是组合拳。第一拳是预留buffer。核心服务的maxReplicas上限要留足空间,避免扩容被上限卡死。第二拳是缓冲池。集群节点池预留一定的空余资源,保证扩容时Pod能够立刻调度上,而不是排队等待新节点创建。第三拳是入口流量控制。在网关或接入层配置限流和降级策略,防止系统过载后发生雪崩。

如果业务流量规律性很强,还可以加一层定时扩容,在预判高峰来临前先把水位抬起来。比如电商平台的大促活动,明明知道晚上八点订单量会爆发,那就提前二十分钟把关键链路的副本数扩到位,让HPA只在突发增量阶段做补充,这样既稳又省。

4.3 缩容缩过头:省成本省出了故障

和扩容问题相反的,是缩容过于激进带来的风险。系统在低峰期把副本数收缩到太低的位置,一旦流量突然回升,系统就会因为缺乏基础冗余而无法快速恢复。缩容省下的钱,最后大概率会在故障赔偿和紧急扩容的工时里还回去。

缩容策略要遵循一个原则,就是慢。宁可缩得慢一点,也不要冒进。缩容的稳定窗口至少要给到5分钟以上,缩容步进控制在10%左右,让系统有足够的时间确认趋势。还有一点,缩容时优先缩启动速度最快的实例,因为这类实例在需要再次扩容时能更快响应。

我建议在配置里显式设置一个最低副本数的保护线,这一水位不仅承载真实业务流量,还为突发场景预留了快速应对的空间。把minReplicas设置到业务测算的常规峰值以上,必要时再加上按时间段的定时缩容逻辑,而不是单纯依赖指标判断。

4.4 排查思路速查表

日常运维中,如果ax调度出现问题,建议按下面的思路快速做个初步排查:

现象可能原因排查方向
副本数不增加,但延迟升高指标采集链路异常或阈值设置过高检查Metrics Server与监控组件数据,确认HPA读取到的指标值
扩容了但Pod一直Pending节点资源不足或资源请求配置过大查看集群节点水位,检查Pod调度事件日志
Pod新建成功但流量异常就绪探针配置不正确或业务启动未完成检查Pod状态,确认就绪探针的检查路径与业务实际状态一致
副本数反复波动指标抖动或稳定窗口设置不合理拉长指标聚合窗口,调整缩容冷却期
缩容速度过慢导致成本高缩容步进限制过严,minReplicas偏高结合业务低峰特征,调整缩容策略或加入定时缩容
扩容触发后流量还是超时新Pod需要较长启动时间优化应用启动流程,调整探针检查策略,考虑预热缓存支持

这六种情况基本覆盖了ax调度上线后常见的坑。遇到问题的时候,第一步永远是先确认数据链路是通的,搞清楚HPA看到的指标值是多少,而不是急着调整参数。指标不准,后面所有的调度决策都是空中楼阁。

说到参数调整,我自己踩过最大的坑是照搬网上的配置模板。不同业务的流量特征、启动时间、依赖关系差异巨大,同样的配置在A服务跑得好好的,搬到B服务就可能翻车。目前这套配置思路,我一般会在压测环境中做几轮流量模拟,确认扩缩容的节奏符合预期,再上生产。压测的目的不是验证功能可用,而是验证在极端流量下系统是否还能保持稳定。

另外还遇到过一种特殊情况,就是HPA扩容到maxReplicas之后继续报警,流量还在涨,系统撑不住了。这种时候靠自动扩缩容已经不够了,要结合人工介入。我会提前准备一套应急预案,包括上游限流、降级非核心功能、手动扩容额外的资源池。自动化是帮我们兜住常规情况的,极端情况还是需要人工兜底。

ax调度做得好,最直观的感受就是系统在流量上涨时像在自动呼吸,副本数平顺地起来,流量过去后又能慢慢地平复下去。但要说这个技术有什么特别的技巧,我觉得把基础打扎实比任何花哨的算法都重要。一个靠谱的指标采集链路,一组贴合业务的扩缩容参数,加上一套排障手段,就已经比大部分团队走得远了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询