欢迎光临
我们一直在努力

怎样设计和部署一个基于YARN/K8s的弹性AI计算资源调度策略?

概述:AI弹性计算的需求与挑战

AI工作负载,尤其是大规模模型训练和批处理推理,具有显著的突发性和可变性。在这些场景中,预先静态分配大量的GPU资源会导致极高的成本浪费。因此,设计一个能够根据待处理任务(Pending Pods)动态伸缩GPU节点池的弹性调度策略至关重要。

我们将聚焦于如何利用Kubernetes的核心组件——Cluster Autoscaler (CA),结合云服务商的自动伸缩组,实现对GPU资源的按需供给(Scale Up)和节约回收(Scale Down)。

弹性调度的核心组件

要实现GPU集群的弹性调度,我们需要关注以下三个关键点:

  1. 资源感知(Resource Awareness):Pod必须明确请求GPU资源 (
    1
    nvidia.com/gpu

    )。

  2. 节点伸缩器(Cluster Autoscaler, CA):负责监控集群中处于Pending状态,且等待特定资源(如GPU)的Pod,并根据需要启动新的节点。
  3. 调度优先级(Priority & Preemption):确保高优先级的训练任务可以抢占低优先级的推理或开发任务,保证核心业务的资源供给。

第一步:配置GPU资源感知和节点组

Cluster Autoscaler需要知道如何从哪个节点池中获取GPU资源。在配置CA时,你需要指定包含GPU节点的Auto Scaling Group (ASG) 或 Managed Instance Group (MIG)。

示例:CA的配置参数(AWS EKS为例)

CA通过分析Pending Pods的

1
nodeSelector

1
tolerations

和资源请求来决定是否需要伸缩。关键在于为GPU节点组设置特定的标签。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Cluster Autoscaler Deployment 配置片段
containers:
- name: cluster-autoscaler
  image: k8s.gcr.io/cluster-autoscaler:v1.24.0
  args:
    - --cloud-provider=aws
    - --nodes=1:10:arn:aws:autoscaling:region:account:autoScalingGroup/cpu-node-group
    # 关键:定义GPU节点池,注意Min/Max限制
    - --nodes=0:5:arn:aws:autoscaling:region:account:autoScalingGroup/gpu-training-group
    - --kubeconfig=/etc/kubernetes/kubeconfig
    # 确保CA识别GPU资源类型
    - --expander=most-pods
    - --gpu-total-count=nvidia.com/gpu:0-50 # 定义整个集群可以拥有的GPU总数范围
    - --skip-nodes-with-system-pods=false

GPU节点标签和污点设置

为了让Pod能够精确调度到GPU节点,GPU节点组应设置唯一的标签和污点。


1
2
3
4
5
6
7
# 节点标签示例
apiVersion: v1
kind: Node
metadata:
  labels:
    infra-type: gpu
    gpu.vendor: nvidia

第二步:定义触发伸缩的弹性AI任务

当AI训练任务提交时,它会请求特定的GPU资源,并使用节点选择器指向GPU节点组。如果当前集群中没有足够的GPU节点,这些Pod将进入Pending状态,从而触发CA。

示例:带有GPU请求的K8s Job

这个Job请求两个NVIDIA GPU,并要求调度到具有

1
infra-type: gpu

标签的节点上。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: batch/v1
kind: Job
metadata:
  name: elastic-gpu-training
spec:
  template:
    spec:
      nodeSelector:
        infra-type: gpu # 确保只调度到GPU节点
      containers:
      - name: trainer
        image: myregistry/tensorflow-trainer:latest
        resources:
          limits:
            nvidia.com/gpu: "2" # 关键:请求2个GPU
          requests:
            nvidia.com/gpu: "2"
      restartPolicy: OnFailure

工作流程:

  1. 用户提交
    1
    elastic-gpu-training

    Job。

  2. Kube Scheduler 发现需要2个GPU,且需要匹配
    1
    infra-type: gpu

    标签的节点。

  3. 如果没有足够的可用资源,Pod进入 Pending 状态。
  4. Cluster Autoscaler 检测到 Pending Pod,发现如果启动一个新节点(假设该节点提供4个GPU),该 Pod 就能被满足。
  5. CA 调用云 API 启动一个新的GPU节点(Scale Up)。
  6. 新节点加入集群,Kube Scheduler 将 Pod 调度到新节点上,任务开始执行。

第三步:实现弹性回收策略(Scale Down)

弹性计算的关键在于节约。当任务完成后,GPU节点必须被及时回收。

Cluster Autoscaler 在默认情况下通过以下机制实现回收:

  1. 空闲时间阈值(
    1
    --scale-down-unneeded-time

    :如果一个节点在指定时间内(默认为10分钟)处于未被任何Pod请求资源的状态,则视为可以被回收。

  2. 排水机制(Draining):在回收节点前,CA会尝试将节点上的所有非系统Pod迁移到其他节点上(如果存在)。

对于AI训练节点,通常配置较短的空闲时间,以确保高昂的GPU资源能够尽快释放。


1
2
3
# CA Scale Down 优化参数示例
--scale-down-unneeded-time=5m # 节点空闲5分钟即可尝试回收
--scale-down-utilization-threshold=0.5 # 节点资源利用率低于50%时考虑回收

结合优先级抢占(Priority/Preemption)

为了防止低优先级任务占用资源,阻碍回收,建议为AI工作负载设置K8s优先级类别(PriorityClass)。


1
2
3
4
5
6
7
8
# 定义高优先级类别
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority-training
value: 1000000
globalDefault: false
description: "For critical AI training jobs."

将此PriorityClass应用于训练Job,确保训练Pod即使在资源紧张时也能通过抢占机制获得GPU,或优先触发CA进行伸缩,从而保证核心业务的弹性需求。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 怎样设计和部署一个基于YARN/K8s的弹性AI计算资源调度策略?
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址