版本:v26.03

AI推理弹性伸缩

特性介绍

Elastic Scaler是一个通用的扩缩容决策框架,用于满足不同业务场景下的扩缩容决策需求。

  • 在架构上,Elastic Scaler采用插件化机制,支持用户自定义扩缩容决策算法及自定义资源管理逻辑的灵活扩展。
  • 在能力上,Elastic Scaler同时支持指标驱动与事件驱动两类扩缩语义,其中事件驱动主要服务于资源需求有显著波动或突发变化的业务场景。

应用场景

Elastic Scaler适用于在Kubernetes集群环境中部署各类业务服务并需要动态资源管理的场景,具体包括:

  • 动态负载场景:请求量随时间波动较大,需要根据实际负载动态调整服务实例数量。
  • 成本优化场景:在保证服务性能的前提下,通过智能伸缩降低资源成本,提高资源利用率。
  • 混合负载场景:长短请求混合、并发量变化的业务场景,需要根据请求特征和实例状态进行智能伸缩。
  • 多租户场景:多个租户共享资源,需要根据各租户的SLA要求动态分配资源。
  • PD分离架构:在Prefill-Decode分离架构下,需要独立调整P端和D端的资源配比。
  • Scale-to/from-zero场景:基于外部信号控制工作负载的启停,用于按需使用资源。
  • 明确副本数场景:基于外部状态直接指定目标副本数,用于潮汐流量或定时负载切换等需要明确容量目标的场景。

能力范围

  • 支持用户在K8s集群部署使用。
  • 支持指标驱动扩缩(MetricsTrigger)。
  • 支持事件驱动扩缩(StateTrigger)。
  • 支持自定义伸缩算法插件开发。
  • 支持自定义资源插件开发(通过ResourceScalingGroup)。
  • 兼容K8s原生HPA能力。

注意

  • 自定义算法可以成功注册,但实际扩缩容决策时当前版本不会被调用。
  • MetricsTrigger模式下的自定义算法和External/ExternalServer指标类型当前版本暂不可用。

亮点特征

  • 插件化架构:支持对扩缩容决策算法的插件化接入,使用户能够根据业务特性灵活定义和演进扩缩算法。
  • 多触发模式:同时支持指标驱动、事件驱动(信号、状态)三类扩缩语义。
  • 多指标体系:支持多种来源的指标(Resource、External、ExternalServer)作为扩缩决策输入。
  • 泛资源管理能力:不再局限于特性资源类型,通过Resource插件机制支持任意自定义资源接入扩缩体系。
  • K8s原生集成:基于K8s HPA(Horizontal Pod Autoscaler)和自定义资源扩展,完全兼容K8s生态。

实现原理

图1 组件架构图

组件图

图2 组件部署视图

组件图

Elastic Scaler通过统一的Trigger抽象管理不同类型的扩缩容触发源。根据配置的Trigger类型,框架会选择不同的执行路径:

  1. MetricsTrigger(指标驱动):Elastic Scaler从监控组件获取实时指标,根据配置的伸缩算法(HPA或自定义算法)计算目标副本数,然后更新目标资源。
  2. StateTrigger(状态驱动):Elastic Scaler侦听外部资源的状态变化,读取外部资源status.desiredReplicas字段,并将该值应用到目标资源。适用于潮汐流量、定时负载切换等场景。 具体流程如下:
    1. 外部控制器(如Tidal)计算期望副本数,并写入外部资源的status.desiredReplicas字段。
    2. 外部资源通过标签绑定到ElasticScaler(elasticscaler.io/namespaceelasticscaler.io/name)。
    3. Elastic Scaler侦听外部资源的状态变化,读取status.desiredReplicas字段。
    4. Elastic Scaler将期望副本数应用到目标资源。
  3. SignalTrigger(信号驱动):Elastic Scaler侦听外部信号端点,接收到ScaleUp/ScaleDown信号后,将目标资源副本数设置为maxReplicasminReplicas。适用于按需启停资源场景。

与相关特性的关系

  • EagleEye:兼容EagleEye提供的推理服务近实时监控指标,包括业务运行态、系统运行态、硬件健康等不同粒度的关键指标。当前版本尚未实现与EagleEye的集成。
  • Tidal:兼容Tidal组件,使用潮汐算法时Tidal通过status.desiredReplicas字段表达明确的容量目标,Elastic Scaler负责执行。
  • ResourceScalingGroup:兼容ResourceScalingGroup CRD,使用自定义资源插件接入决策框架,用于AI资源精细化管理。

安装

本章节分别介绍在已有集群中独立部署Elastic Scaler,以及通过InferNex套件集成部署Elastic Scaler的方法。

独立部署

本节介绍如何在已有推理服务和监控组件的K8s集群中,独立部署Elastic Scaler。

前提条件

在开始安装前,请确保满足以下条件:

  • 环境要求:

    • Kubernetes集群:v1.28.0及以上版本。
    • 集群管理员权限:用于安装CRD和集群级资源。
    • Helm工具:用于部署Elastic Scaler和相关组件。
  • 硬件要求:

    • Elastic Scaler本身对硬件环境无特殊要求,作为轻量级控制器组件,可运行在标准x86或ARM架构的节点上。

安装Elastic Scaler

执行如下命令,安装Elastic Scaler。

bash
helm install elastic-scaler oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
  --set elastic-scaler.namespace.create=true # 默认是false,如果集群中不包含scaling-system namespace,这里需要设置成true。

从OCI仓库安装pd-orchestrator chart。该chart默认会安装ElasticScaler、RSG和Tidal三个组件,并默认创建一份RSG CR和ElasticScaler CR实例配置。

如果当前仅需部署ElasticScaler Controller,建议显式关闭其他组件和默认示例实例:

bash
helm install elastic-scaler oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
  --set elastic-scaler.enabled=true \
  --set elastic-scaler.elasticScaler.enabled=false \
  --set resourcescalinggroup.enabled=false \
  --set resourcescalinggroup.instanceConfig.enabled=false \
  --set tidal.enabled=false

说明

  • 部署Elastic Scaler时需要正确配置监控数据源和伸缩目标。
  • ElasticScaler CR需要配置正确的目标资源(Deployment、StatefulSet等)和Trigger配置。
  • 伸缩策略的详细配置请参考配置伸缩策略章节。

InferNex集成部署

InferNex是一键集成的智能路由、监控与弹性伸缩部署套件, 内部包含elastic-scaler组件。

前提条件

  • Kubernetes v1.28.0及以上版本。
  • 每个推理节点至少一张推理芯片。
  • 每个推理节点至少16GB内存,4CPU核。
  • 在线安装能够访问镜像仓库:oci://cr.openfuyao.cn。
  • 用户具备创建RBAC资源的权限。

快速安装InferNex

InferNex有以下两种途径独立部署:

  • 从openFuyao官方制品仓库获取项目安装包。

    1. 从远端仓库安装。

      bash
      helm install infernex oci://cr.openfuyao.cn/charts/infernex --version xxx

      其中xxx需替换为具体项目安装包版本,如0.21.1infernex为release名称。

      执行安装前请确保:

      • 集群已创建命名空间istio-system(Istio Gateway资源必须部署在此命名空间)和scaling-system
  • 从openFuyao GitCode仓库获取。

    1. 从仓库拉取项目。

      bash
      git clone https://gitcode.com/openFuyao/InferNex.git
    2. 安装部署。

      以release名称infernex为例,在InferNex同级目录下执行如下命令:

      bash
      cd InferNex/charts/infernex
      helm dependency build
      helm install -n <namespace> infernex .

配置伸缩策略

本章节说明如何为不同业务场景配置Elastic Scaler的伸缩策略。

指标驱动扩缩(MetricsTrigger)

指标驱动扩缩基于实时指标变化自动调节副本数,适用于持续运行、负载平滑变化的业务场景。

使用HPA算法

HPA算法基于CPU/内存使用率进行伸缩,利用K8s原生HPA能力。

说明

  • Elastic Scaler在HPA算法模式下会自动创建并管理对应的Kubernetes HPA资源。
  • 若将伸缩算法从HPA切换至其他模式(如自定义算法),必须先删除Elastic Scaler实例或手动清理已生成的HPA资源,否则会导致资源管理冲突。
  • Elastic Scaler与被管理资源(Deployment、StatefulSet等)需保持一对一映射关系。
  • HPA模式下,Elastic Scaler与被管理资源必须部署在同一命名空间内。
yaml
apiVersion: elasticscaler.io/v1alpha1
kind: ElasticScaler
metadata:
  name: hpa-scaling-example
  namespace: ai-inference
spec:
  # 伸缩目标
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-inference

  # 最小/最大副本数
  minReplicas: 2
  maxReplicas: 10

  # 指标驱动触发配置
  trigger:
    type: MetricsTrigger
    metricsTrigger:
      # 使用HPA算法
      scalingAlgorithm: HPA

      # 指标配置
      metrics:
      - type: Resource
        resource:
          metricsName: cpu
          target:
            type: Utilization
            averageUtilization: 70

表1 HPA策略参数说明

参数类型说明缺省值
typestringTrigger类型,必须设置为MetricsTrigger-
scalingAlgorithmstring伸缩算法,设置为HPA使用K8s原生HPA。-
metrics[].typestring指标类型(Resource/External),当前版本仅支持Resource-
metrics[].resource.metricsNamestring资源指标名称(cpu/memory)。-
metrics[].resource.target.typestring目标类型(Utilization/Value/AverageValue)。-
metrics[].resource.target.averageUtilizationint目标平均使用率(百分比)。-

使用自定义算法

自定义算法功能在当前版本中仅支持算法注册。虽然算法接口和注册机制已定义,但算法调用路径(AlgorithmManager.CalculateDesiredReplicas())的核心逻辑尚未实现。建议当前版本使用HPA算法。

自定义算法允许用户根据特定业务需求开发自定义伸缩逻辑。

yaml
apiVersion: elasticscaler.io/v1alpha1
kind: ElasticScaler
metadata:
  name: custom-scaling-example
  namespace: ai-inference
spec:
  # 伸缩目标
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-inference

  # 最小/最大副本数
  minReplicas: 2
  maxReplicas: 10

  # 指标驱动触发配置
  trigger:
    type: MetricsTrigger
    metricsTrigger:
      # 使用自定义算法
      scalingAlgorithm: xpa

      # 算法配置
      algorithmConfig:
        threshold: 0.8
        cooldownSeconds: 60

      # 指标配置
      metrics:
      - type: External
        external:
          metric:
            name: qps
          target:
            type: AverageValue
            averageValue: "100"

表2 自定义算法策略参数说明

参数类型说明缺省值
scalingAlgorithmstring自定义算法名称(如xpa)。-
algorithmConfigmap算法配置参数,结构取决于算法实现。-
metrics[].typestring指标类型(Resource/External/ExternalServer),当前版本仅支持Resource-
metrics[].resource.metricsNamestring资源指标名称(cpu/memory)。-
metrics[].resource.target.typestring目标类型(Utilization/Value/AverageValue)。-
metrics[].resource.target.averageUtilizationint目标平均使用率(百分比)。-

事件驱动扩缩(StateTrigger)

状态驱动扩缩基于外部资源状态变化触发,适用于潮汐流量、定时负载切换等需要明确容量目标的场景。

yaml
apiVersion: tidal.io/v1alpha1
kind: Tidal
metadata:
  name: tidal-frequent-test
  namespace: ai-inference
  labels:
    elasticscaler.io/name: state-scaling-example
    elasticscaler.io/namespace: ai-inference
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: elastic-scaler-state-test   # 改成你要伸缩的 Deployment 名称
    namespace: ai-inference
  triggers:
    times:
      rules:
        - name: time1
          cron: "CRON_TZ=Asia/Shanghai 0 50 16 * * *"
          replicas: 3
          description: time1     
        - name: time2
          cron: "CRON_TZ=Asia/Shanghai 0 0 8 * * *"
          replicas: 5
          description: time2
yaml
apiVersion: elasticscaler.io/v1alpha1
kind: ElasticScaler
metadata:
  name: state-scaling-example
  namespace: ai-inference
spec:
  # 伸缩目标
  targetRef:
    apiVersion: tidal.io/v1alpha1
    kind: Tidal
    name: tidal-frequent-test

  # 状态驱动触发配置
  trigger:
    type: StateTrigger
    stateTrigger: {}

表3 StateTrigger参数说明

参数类型说明缺省值
typestringTrigger类型,必须设置为StateTrigger-
stateTriggerobject状态驱动配置,当前版本为空对象。-

事件驱动扩缩(SignalTrigger)

SignalTrigger信号驱动扩缩功能在当前版本中尚未实现。相关接口已定义(SignalTrigger.HandleSignalTrigger()),但核心侦听逻辑尚未完成。

信号驱动扩缩基于外部信号触发scale-to/from-zero,适用于按需启停资源的场景。

yaml
apiVersion: elasticscaler.io.io/v1alpha1
kind: ElasticScaler
metadata:
  name: signal-scaling-example
  namespace: ai-inference
spec:
  # 伸缩目标
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-inference

  # 最小/最大副本数
  minReplicas: 0
  maxReplicas: 10

  # 信号驱动触发配置
  trigger:
    type: SignalTrigger
    signalTrigger:
      endpoint: "https://webhook.example.com/scale-signal"
      protocol: https

表4 SignalTrigger参数说明

参数类型说明缺省值
typestringTrigger类型,必须设置为SignalTrigger-
signalTrigger.endpointstring信号端点地址。-
signalTrigger.protocolstring通信协议(http/https)。https

使用弹性伸缩

本章节演示如何在集群中查看、监控和管理Elastic Scaler的伸缩行为。

查看伸缩策略

bash
# 查看所有ElasticScaler资源
kubectl get elasticscalers -n <NAMESPACE>

# 查看特定ElasticScaler详情
kubectl describe elasticscalers <SCALER_NAME> -n <NAMESPACE>

查看伸缩事件

bash
# 查看伸缩事件
kubectl get events -n <NAMESPACE> --field-selector involvedObject.kind=ElasticScaler

# 查看控制器日志
kubectl logs -n <NAMESPACE> -l control-plane=<RELEASE-NAME>-elastic-scaler-controller-manager -f

禁用/启用伸缩策略

Elastic Scaler通过删除CR来禁用伸缩策略,创建CR来启用。

bash
# 禁用伸缩策略(删除CR)
kubectl delete elasticscalers <SCALER_NAME> -n <NAMESPACE>

# 启用伸缩策略(创建CR)
kubectl apply -f <elastic-scaler-config>.yaml

常见问题

  1. 支持哪些类型的指标?

Elastic Scaler当前仅支持Resource(Kubernetes原生资源指标, e.g CPU、内存)指标类型。

  1. 如何调测伸缩策略?

可以通过查看Elastic Scaler的Controller日志和K8s事件来调测伸缩策略。日志中会包含指标数据、决策过程和伸缩操作的详细信息。

  1. StateTrigger如何工作?

StateTrigger模式下,外部控制器(如Tidal)计算期望副本数并写入外部资源的status.desiredReplicas字段。Elastic Scaler侦听外部资源的状态变化,读取该字段并应用到目标资源。外部资源需要通过标签elasticscaler.io/namespaceelasticscaler.io/name绑定到ElasticScaler。

  1. 如何开发自定义伸缩算法?

自定义伸缩算法需要实现ScalingAlgorithm接口,并通过DefaultRegistry.Register()方法注册算法。详细开发指南请参考插件开发指南

注意
自定义算法调用路径在当前版本中尚未实现。算法可以成功注册,但实际扩缩容决策时不会被调用。建议当前版本使用HPA算法。

  1. 如何支持自定义资源类型?

通过实现ResourceHandler接口并使用RegisterResourceHandler()方法注册,可以支持任意自定义资源类型。自定义资源需要实现GetCurrentReplicas()UpdateReplicas()等方法。