
# GPU虚拟化优先级抢占调度
任务优先级（通过[PriorityClass](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass)定义）用于标识任务相对于其他任务的重要性。启用GPU虚拟化任务优先级抢占功能后，Volcano调度器将优先保障高优先级GPU虚拟化任务的调度。即当集群虚拟化GPU资源不足时，调度器主动驱逐低优先级业务，保障高优先级业务可以正常调度。待资源充足后，再重新调度低优先级业务。此外，该功能支持两个维度的资源抢占：
- **单卡同类型资源抢占**（默认支持）：高优先级任务可以抢占同一GPU卡上相同类型任务的资源。例如，同一GPU卡中，高优先级的显存隔离任务可以抢占低优先级的显存隔离任务的资源。
- **跨** **卡不同类型资源抢占**（需要开启拓扑感知抢占开关）：高优先级任务可以在不同GPU卡上，抢占相同类型或不同类型任务的资源。例如，高优先级算显隔离任务可以跨卡抢占低优先级显存隔离任务的显存资源，从而实现更灵活、高效的GPU资源调度与分配。
GPU虚拟化优先级抢占调度会对待调度负载中的每个Pod执行以下操作：
1. 筛选候选节点：这些节点可通过驱逐一个或多个低优先级Pod，满足待调度Pod的资源需求。
2. 候选节点排序：基于节点空闲资源量、需驱逐Pod的优先级及数量等维度，对候选节点综合评分并排序。
3. 进行Pod调度：选择最优节点执行调度，即先驱逐低优先级Pod，再部署当前Pod。
若所有Pod均成功部署，则调度完成；若任一Pod调度失败，立即回滚所有操作至初始状态，确保集群一致性。
如[图1]所示，假设待调度负载F含3个Pod。Volcano调度器将依据上述逻辑依次调度负载内的Pod，直至所有Pod调度完成。
图1任务优先级抢占示例图   
![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002342421010.png "点击放大")
#### 前提条件
- 已有一个CCE Standard或CCE Turbo集群，且集群版本在v1.27及以上。
- 已安装CCE AI套件（NVIDIA GPU）插件，具体安装步骤请参见[CCE AI套件（NVIDIA GPU）](https://support.huaweicloud.com/usermanual-cce/cce_10_0141.html)。同时，插件版本需符合以下要求：
  - 集群版本为v1.27时：插件版本要求在2.1.41及以上。
  
  - 集群版本在v1.28及以上时：插件版本要求在2.7.57及以上。
   
- 集群中已有GPU节点，且已开启集群或节点池级别的GPU虚拟化，具体操作步骤请参见[准备GPU虚拟化资源](https://support.huaweicloud.com/usermanual-cce/cce_10_0645.html)。
- 已安装Volcano调度器插件，且插件版本在1.18.1及以上，具体安装步骤请参见[Volcano调度器](https://support.huaweicloud.com/usermanual-cce/cce_10_0193.html)。
 
#### 约束与限制
XGPU抢占场景只保证高优先级作业可以抢占资源调度，不保证结果最优，有可能导致集群出现资源碎片。
- [开启拓扑感知抢占开关]
  开启该开关后，Volcano调度器将支持跨卡不同类型资源抢占，即高优先级任务可以在不同GPU卡上，抢占相同类型或不同类型任务的资源。
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称，进入集群"概览页"。
  
  2. 在左侧导航栏单击"配置中心"，右侧选择"调度配置"页签。在"设置集群默认调度器 \> 默认调度器"中选择"Volcano调度器"，并在"专家模式"中单击"开始使用"。
  
  3. 在"专家模式（Volcano调度）"页面的YAML中，将配置项**enable_topology_aware_preemption** 的值设置为true，用于实现跨卡不同类型资源抢占。
     
     ```
     ...
     descheduler_enable: 'false'
     deschedulingInterval: 10m
     enable_scale_in_score: true
     enable_topology_aware_preemption: true  # 开启拓扑感知抢占开关
     enable_workload_balancer: false
     oversubscription_method: nodeResource
     ...
     ```
     
     
  
  4. 完成上述配置后，单击右下角"确认配置"。在"确认配置"弹窗中，确认修改信息，无误后单击"保存"。
   
- [XGPU任务优先级抢占功能使用示例]
  假设集群中有一个节点，拥有一张8GB显存的GPU卡。现有2个优先级的工作负载，分别为priority-low-gpu和priority-high-gpu，两者均申请8GB的显存。首先运行priority-low-gpu占满集群资源，然后提交priority-high-gpu。由于priority-high-gpu的优先级高于priority-low-gpu，因此集群会驱逐priority-low-gpu，优先调度priority-high-gpu。此时，priority-low-gpu将处于pending状态，待资源充足时，将重新进行调度。
  1. [使用kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
  
  2. 执行以下命令，创建低优先级工作负载的YAML文件，文件名支持自定义。**当未在工作负载中指定优先级时，其默认值为0** 。
     
     ```
     vim low-priority.yaml
     ```
     文件内容如下：
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: priority-low-gpu
       namespace: default
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: priority-low-gpu
       template:
         metadata:
           labels:
             app: priority-low-gpu
         spec:
           schedulerName: volcano
           containers:
           - image: <your_image_address>     # 请替换为您的镜像地址
             name: container-0
             resources:
               requests:
                 cpu: 250m
                 memory: 512Mi
                 volcano.sh/gpu-mem.128Mi: '64' # 申请8GB显存，需与limits.volcano.sh/gpu-mem.128Mi保持一致
               limits:
                 cpu: 250m
                 memory: 512Mi
                 volcano.sh/gpu-mem.128Mi: '64' # 申请8GB显存，该数值表示128Mi的倍数，即64*128/1024=8
           imagePullSecrets:
           - name: default-secret
     ```
     
     
  
  3. 执行以下命令，创建工作负载。 
     ```
     kubectl apply -f low-priority.yaml
     ```
     回显结果如下，则说明工作负载已创建。
     ```
     deployment.apps/priority-low-gpu created
     ```
     
     
  
  4. 执行以下命令，查看对应Pod是否创建成功。 
     ```
     kubectl get pod -n default
     ```
     回显结果如下，则说明Pod已创建成功，此时GPU节点中的显存已被耗尽。
     ```
     NAME                               READY   STATUS    RESTARTS   AGE
     priority-low-gpu-6bdb4d7cb-pmtc2   1/1     Running   0          21s
     ```
     
     
  
  5. 执行以下命令，创建高优先级工作负载的YAML文件。 
     ```
     vim high-priority.yaml
     ```
     文件内容如下：
     ```
     apiVersion: scheduling.k8s.io/v1  # 创建高优先级定义，其值为1000 
     description: high priority
     kind: PriorityClass
     metadata:
       name: high-priority
     preemptionPolicy: PreemptLowerPriority
     value: 1000        # 值越高，优先级越高
     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: priority-high-gpu
       namespace: default
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: priority-high-gpu
       template:
         metadata:
           labels:
             app: priority-high-gpu
         spec:
           priorityClassName: high-priority  # 使用高优先级定义
           schedulerName: volcano
           containers:
           - image: <your_image_address>     # 请替换为您的镜像地址
             name: container-0
             resources:
               requests:
                 cpu: 250m
                 memory: 512Mi
                 volcano.sh/gpu-mem.128Mi: '64' # 申请8GB显存
                 volcano.sh/gpu-core.percentage: '50' # 申请50%算力
               limits:
                 cpu: 250m
                 memory: 512Mi
                 volcano.sh/gpu-mem.128Mi: '64' # 申请8GB显存
                 volcano.sh/gpu-core.percentage: '50' # 申请50%算力
           imagePullSecrets:
           - name: default-secret
     ```
     
     
  
  6. 执行以下命令，创建高优先级工作负载。 
     ```
     kubectl apply -f high-priority.yaml
     ```
     回显结果如下，则说明工作负载已创建。由于显存资源已耗尽，现有资源无法支撑高优先级工作负载的调度，因此将发生资源抢占，即驱逐低优先级Pod，调度高优先级Pod。资源抢占大概需要30秒的时间，请耐心等候。
     ```
     deployment.apps/priority-high-gpu created
     ```
     
     
  
  7. 执行以下命令，检查资源是否抢占成功。 
     ```
     kubectl get pod -n default
     ```
     回显结果如下，则说明资源抢占成功，待资源充足后，priority-low-gpu-6bdb4d7cb-pmtc2将被重新调度。
     ```
     NAME                                READY   STATUS    RESTARTS   AGE
     priority-low-gpu-6bdb4d7cb-pmtc2    1/1     Pending   0          21s
     priority-high-gpu-8adb4d6bd-stka1   1/1     Running   0          21s
     ```
     
     
   
#### 相关文档
- [GPU弹性伸缩](https://support.huaweicloud.com/usermanual-cce/cce_10_1017.html)
- [GPU监控](https://support.huaweicloud.com/usermanual-cce/cce_10_1016.html)
- [GPU故障处理](https://support.huaweicloud.com/usermanual-cce/cce_10_0779.html)
- [创建使用GPU虚拟化多卡均分调度功能的工作负载之后，大量Pod执行失败](https://support.huaweicloud.com/cce_faq/cce_faq_00497.html)
 
