为多集群舰队开启库存感知的弹性调度

ACK One多集群舰队在多地域应用服务部署场景下,针对多地域资源调配的难题设计并实现了基于库存感知的智能调度器。本文介绍库存感知的工作原理以及如何开启和使用库存感知调度能力。

能力介绍

GPU推理服务场景中,用户普遍面临两大挑战:

  • 各地域GPU供给在动态变化,难以保证实时可用。

  • GPU价格昂贵,预先创建会导致高昂的成本。

库存感知调度机制配合即时弹性可以很好地解决这两大难题,当舰队管理的多个集群现有资源不足时,会将应用服务调度到有库存的集群中,该集群的即时弹性会进行扩容所需节点来承接相关的应用服务。通过这个能力,最大化保证了需要GPU等稀缺资源的应用的成功调度以及显著降低了GPU使用成本。

重要

此能力目前处于邀测阶段。如需体验,请提交工单申请。

工作原理

当某个集群资源不足时,在舰队中创建应用触发的整体工作流程如下:

  1. 创建应用和分发策略。

  2. 调度器感知子集群资源不足,无法进行调度。

  3. 调度器触发子集群ACK GOATScaler对于库存的检查,然后获取检查结果。

  4. 根据库存结果,调度器进行重新调度,然后进行应用分发。

  5. 应用分发到子集群之后,集群开始扩容节点,应用正常运行。

image

前提条件

重要

若子集群已经开启了节点自动伸缩,请根据开启节点即时弹性功能切换为节点即时弹性

GPU实例规格和成本预估

在推理阶段主要占用显存的是模型参数,可以通过以下公式计算。

以一个默认精度为FP167B模型为例,模型参数量为:7B(即70亿),精度数据类型字节数为:默认精度16位浮点数 / 8位每字节 = 2字节。

除了加载模型占用的显存之外,还需要考虑运算时所需的KV Cache大小和GPU使用率,通常会预留一部分buffer,因此推荐使用24GiB显存的GPU实例ecs.gn7i-c8g1.2xlargeecs.gn7i-c16g1.4xlarge更多内容,请参见推荐实例规格表关于GPU实例规格和计费的详情,请参见GPU计算型实例规格族GPU云服务器计费

准备工作

本步骤将准备qwen3-8b推理服务的模型文件并分别在子集群中创建对应的OSS存储卷。

  1. 下载模型。

    说明

    请确认是否已安装git-lfs插件,如未安装可执行yum install git-lfs或者apt-get install git-lfs安装。更多的安装方式,请参见安装git-lfs

    git lfs install
    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/Qwen3-8B.git
    cd Qwen3-8B
    git lfs pull
  2. OSS中创建目录,将模型上传至OSS。

    说明

    关于ossutil工具的安装和使用方法,请参见安装ossutil

    ossutil mkdir oss://<your-bucket-name>/models/Qwen3-8B
    ossutil cp -r ./Qwen3-8B oss://<your-bucket-name>/models/Qwen3-8B
  3. 分别在子集群中创建PVPVC。具体操作,请参见使用ossfs 1.0静态存储卷

    展开查看YAML内容

    apiVersion: v1
    kind: Secret
    metadata:
      name: oss-secret
    stringData:
      akId: <your-oss-ak> # 配置用于访问OSSAccessKey ID
      akSecret: <your-oss-sk> # 配置用于访问OSSAccessKey Secret
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: qwen3-8b
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 20Gi
      selector:
        matchLabels:
          alicloud-pvname: qwen3-8b
      storageClassName: oss
      volumeMode: Filesystem
      volumeName: qwen3-8b
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      labels:
        alicloud-pvname: qwen3-8b
      name: qwen3-8b
    spec:
      accessModes:
        - ReadWriteMany
      capacity:
        storage: 20Gi
      csi:
        driver: ossplugin.csi.alibabacloud.com
        nodePublishSecretRef:
          name: oss-secret
          namespace: default
        volumeAttributes:
          bucket: <your-bucket-name> # bucket名称
          otherOpts: '-o allow_other -o umask=000'
          path: <your-model-path> # 本示例中为/models/Qwen3-8B/
          url: <your-bucket-endpoint> # Endpoint信息,如oss-cn-hangzhou-internal.aliyuncs.com
        volumeHandle: qwen3-8b
      persistentVolumeReclaimPolicy: Retain
      storageClassName: oss
      volumeMode: Filesystem

步骤一:为子集群配置节点池

创建或编辑节点池,设置实例规格为ecs.gn7i-c8g1.2xlarge扩缩容模式选择自动,节点池期望节点数为0。具体操作和配置参数,请参见创建和管理节点池

调整节点伸缩配置时,您可以调整缩容触发时延来缩短后续步骤的等待时间。

步骤二:在舰队集群创建应用和分发策略

  1. 创建deploy.yaml。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: qwen3-8b
      name: qwen3-8b
      namespace: default
    spec:
      replicas: 4
      selector:
        matchLabels:
          app: qwen3-8b
      template:
        metadata:
          labels:
            app: qwen3-8b
        spec:
          volumes:
            - name: qwen3-8b
              persistentVolumeClaim:
                claimName: qwen3-8b
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 20Gi
          containers:
          - command:
            - sh
            - -c
            - vllm serve /models/qwen3-8b --port 8000 --trust-remote-code --served-model-name qwen3-8b --tensor-parallel=1 --max-model-len 8192 --gpu-memory-utilization 0.95 --enforce-eager
            image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm-openai:v0.9.1
            name: vllm
            ports:
            - containerPort: 8000
            readinessProbe:
              tcpSocket:
                port: 8000
              initialDelaySeconds: 30
              periodSeconds: 30
            resources:
              limits:
                nvidia.com/gpu: "1"
            volumeMounts:
              - mountPath: /models/qwen3-8b
                name: qwen3-8b
              - mountPath: /dev/shm
                name: dshm
  2. 创建PropagationPolicy.yaml。

    apiVersion: policy.one.alibabacloud.com/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: demo-policy
    spec:
      # 此字段表示开启库存感知的弹性调度
      autoScaling:
        ecsProvision: true
      preserveResourcesOnDeletion: false
      conflictResolution: Overwrite
      resourceSelectors:
      - apiVersion: apps/v1
        kind: Deployment
        name: qwen3-8b
        namespace: default
      placement:
        replicaScheduling:
          replicaSchedulingType: Divided
          weightPreference:
            dynamicWeight: AvailableReplicas
        clusterAffinity:
          clusterNames:
          - ${cluster1-id} # 请替换为实际的子集群ID
          - ${cluster2-id} # 请替换为实际的子集群ID
  3. 使用舰队的kubeconfig部署应用和分发策略。

    kubectl apply -f deploy.yaml
    kubectl apply -f PropagationPolicy.yaml

    一段时间后,您会发现cluster1cluster2GPU节点池开始自行扩容。

步骤三:验证弹性扩缩容

  1. 查看工作负载调度情况。

    kubectl get resourcebinding

    预期输出:

    NAME                  SCHEDULED   FULLYAPPLIED   OVERRIDDEN   ALLAVAILABLE   AGE
    qwen3-8b-deployment   True        True           True         False          7m47s

    可以看到,SCHEDULEDTRUE,说明工作负载已成功调度。

  2. 等待Pod状态处于Running后,查看Pod分布情况。

    kubectl amc get deploy qwen3-8b -M

    预期输出:

    NAME       CLUSTER           READY   UP-TO-DATE   AVAILABLE   AGE     ADOPTION
    qwen3-8b   cxxxxxxxxxxxxxx   2/2     2            2           3m22s   Y
    qwen3-8b   cxxxxxxxxxxxxxx   2/2     2            2           3m22s   Y

    可以看到,子集群在没有可用的GPU节点的情况下,工作负载的所有副本都成功调度并且正常运行。

  3. 修改qwen3-8b的副本数为2,更新工作负载。

    您也可以选择直接删除工作负载,模拟副本数缩容到0的情况。
    kubectl apply -f deploy.yaml
  4. 等待十分钟,可以看到子集群的GPU节点池缩容到一个节点。

    若您选择删除工作负载,则节点数量会缩容到0。

从完整流程可以看到,舰队的库存感知调度能力确保在子集群现有资源不足时通过感知库存成功调度分发应用,随后进行节点扩容来承载应用,在应用缩容、删除后,自动缩容空闲节点,释放资源以降低成本。