1. 基于k8s的GPU调度方案
1.1. 调度解决方案概述
Kubernetes 原生调度器仅提供基于 GPU 数量的基础调度能力,无法充分利用 GPU 资源。
沐曦提供了多种基于 Kubernetes 的调度解决方案,旨在解决特定场景下的调度需求,提升系统的整体性能和用户体验。 调度解决方案说明及推荐场景参见下表。
调度解决方案 |
描述 |
推荐场景 |
|---|---|---|
gpu-scheduler
|
gpu-scheduler 实现了 GPU 资源的拓扑感知调度,确保 GPU 任务高效、均衡地部署到集群节点
|
|
HAMi
|
HAMi 支持 GPU 资源的共享以提高 GPU资源的利用率,同时也支持了 GPU 资源的拓扑感知调度
|
|
Volcano
|
Volcano 是基于 Kubernetes 的批任务调度器。
基于 Volcano 的调度扩展机制开发了调度插件以支持超节点任务调度及 GPU 资源的拓扑感知调度
|
|
上述调度解决方案所支持的调度功能特性参见下表。
调度解决方案 |
GPU 拓扑感知调度 |
GPU 共享 |
指定 GPU 调度 |
超节点调度 |
|---|---|---|---|---|
gpu-scheduler |
✔ |
× |
× |
× |
HAMi |
✔ |
✔ |
✔ |
× |
Volcano |
✔ |
× |
× |
✔ |
备注
启用 GPU VF 场景下,原生调度器与上述调度方案均可使用,但仅提供基于 GPU 数量的基础调度能力。
用户可根据使用场景及需要的调度功能特性选择对应的调度解决方案。后续章节描述对应的部署流程。
1.2. 准备 GPU Operator 所需的前置资源
无论选择何种调度解决方案,都需要安装 GPU Operator 组件,以下步骤为准备 GPU Operator 的前置资源。
备注
关于 GPU Operator 所依赖的前置资源,参见《曦云系列通用GPU云原生参考手册》中“安装与维护”章节。
获取安装包
以 0.13.0 版本为例,从 沐曦软件中心 下载离线安装包 metax-gpu-k8s-package.0.13.0.tar.gz,解压后获取以下文件:
metax-k8s-images.0.13.0.run:镜像资源包
metax-operator-0.13.0.tgz:Operator Helm Chart
metax-gpu-extensions-0.13.0.tgz:Extensions Helm Chart
准备内核驱动和 MXMACA® SDK 镜像
GPU Operator 会自动管理节点上的内核驱动及 MXMACA® SDK 的部署与更新,需确保所有工作节点均可正常拉取相关镜像资源。
内核驱动与 MXMACA® SDK 可从 沐曦软件中心 下载。
资源包格式:
内核驱动镜像包
metax-k8s-driver-image.<VERSION>-<ARCH>.run:包含内核态驱动和配套 mx-smi 工具的资源包
MXMACA® SDK 镜像包
随 MXMACA® 的发布包发布,例如 maca-c500-container-*.xz 或者 mxc500-maca-*-container.xz
推送镜像
# 假设容器仓库服务器域名为 DOMAIN ,用于存放沐曦Kubernetes组件镜像的项目名为 PROJECT。 # 默认使用docker进行镜像推送 metax-k8s-images.0.13.0.run push DOMAIN/PROJECT # 使用nerdctl进行镜像推送 metax-k8s-images.0.13.0.run nerdctl push DOMAIN/PROJECT
备注
自 0.13.0 起,该工具支持多种运行时:
docker、nerdctl、ctr。若未显式指定,默认使用
docker。若主机未安装docker,系统将自动检测可用运行时并执行镜像推送。
推送 Helm Charts
helm push ./k8s/metax-operator-0.13.0.tgz oci://DOMAIN/PROJECT
1.3. 部署 gpu-scheduler 方案
1.3.1. 安装 GPU Operator
安装 GPU Operator
以容器镜像仓库地址为
DOMAIN/PROJECT为例,在 Kubernetes 管理节点执行以下命令安装 GPU Operator 。helm install ./k8s/metax-operator-0.13.0.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait \ --set registry=DOMAIN/PROJECT \ --set gpuScheduler.deploy=true
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n metax-operator NAME READY STATUS RESTARTS AGE metax-container-runtime-4lsd7 1/1 Running 0 31s metax-gpu-device-7774b 1/1 Running 0 31s metax-gpu-label-l5tkf 1/1 Running 0 31s metax-gpu-scheduler-69b58895fd-gcgcz 2/2 Running 0 31s metax-operator-1755847288-77bfc94568-7wqlh 1/1 Running 0 31s ...
检查节点资源
以 sample-node1 节点为例,在 Kubernetes 管理节点执行以下命令检查节点资源。
kubectl get node sample-node1 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("metax-tech.com/gpu")))' # 示例输出 { "metax-tech.com/gpu": "8" }
1.3.2. 编写任务 YAML
创建 sample.yaml,用户可参考以下示例编写任务文件。
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: ubuntu
image: ubuntu:22.04
imagePullPolicy: IfNotPresent
command: ['bash', '-c']
args: ["sleep infinity"]
resources:
limits:
metax-tech.com/gpu: 2
1.3.3. 提交任务
在 Kubernetes 管理节点执行以下命令提交任务。
kubectl create -f sample.yaml
1.3.4. 检查调度结果
在 Kubernetes 管理节点执行以下命令检查任务的调度节点。
kubectl get pod -owide
NAME READY STATUS RESTARTS AGE NODE
sample-pod 1/1 Running 0 31s gpu-node
1.4. 部署 HAMi 方案
1.4.1. 安装 GPU Operator
1.4.1.1. 集群内所有沐曦 GPU 都需启用 GPU 共享功能
安装 GPU Operator
以容器镜像仓库地址为
DOMAIN/PROJECT为例,在 Kubernetes 管理节点执行以下命令安装 GPU Operator 。helm install ./k8s/metax-operator-0.13.0.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait \ --set registry=DOMAIN/PROJECT \ --set gpuDevice.sGPUHybridMode=true
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n metax-operator NAME READY STATUS RESTARTS AGE metax-container-runtime-4lsd7 1/1 Running 0 31s metax-gpu-device-7774b 1/1 Running 0 31s metax-gpu-label-l5tkf 1/1 Running 0 31s metax-operator-1755847288-77bfc94568-7wqlh 1/1 Running 0 31s ...
检查节点资源
以 sample-node1 节点为例,在 Kubernetes 管理节点执行以下命令检查节点资源。
kubectl get node sample-node1 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("metax-tech.com/sgpu")))' # 示例输出 { "metax-tech.com/sgpu": "16" }
1.4.1.2. 集群内仅部分节点的沐曦 GPU 需启用 GPU 共享功能
安装 GPU Operator
以容器镜像仓库地址为
DOMAIN/PROJECT为例,在 Kubernetes 管理节点执行以下命令安装 GPU Operator 。helm install ./k8s/metax-operator-0.13.0.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait \ --set registry=DOMAIN/PROJECT
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n metax-operator NAME READY STATUS RESTARTS AGE metax-container-runtime-4lsd7 1/1 Running 0 31s metax-gpu-device-7774b 1/1 Running 0 31s metax-gpu-label-l5tkf 1/1 Running 0 31s metax-operator-1755847288-77bfc94568-7wqlh 1/1 Running 0 31s ...
创建ConfigMap配置
在 Kubernetes 管理节点执行以下命令创建
ConfigMap配置集群级别和节点级别的 gpu-device 的运行模式。 配置为sgpu模式的节点将启用 GPU 共享功能。cat << "EOF" | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: metax-device-config namespace: metax-operator data: version: v1 cluster-config: | mode: "native" nodes-config: | - nodeName: "sample-node1" mode: "sgpu" EOF
检查节点资源
以 sample-node1 节点为例,在 Kubernetes 管理节点执行以下命令检查配置为
sgpu模式的节点资源。kubectl get node sample-node1 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("metax-tech.com/sgpu")))' # 示例输出 { "metax-tech.com/sgpu": "16" }
1.4.2. 安装 HAMi
备注
HAMi 版本需≥2.6.0。
安装 HAMi
在 Kubernetes 管理节点执行以下命令安装 HAMi 。
helm repo add hami-charts https://project-hami.github.io/HAMi/ helm install hami hami-charts/hami -n hami --create-namespace
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n hami NAME READY STATUS RESTARTS AGE hami-scheduler-5888f74b95-l8s6p 2/2 Running 0 31s
1.4.3. 编写任务 YAML
创建 sample.yaml,用户可参考以下示例编写任务文件。
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
schedulerName: hami-scheduler
containers:
- name: ubuntu
image: ubuntu:22.04
imagePullPolicy: IfNotPresent
command: ['bash', '-c']
args: ["sleep infinity"]
resources:
limits:
metax-tech.com/sgpu: 1 # requesting 1 GPU
metax-tech.com/vcore: 60 # requesting 60% compute of full GPU
metax-tech.com/vmemory: 4 # requesting 4 GiB device memory of full GPU
1.4.4. 提交任务
在 Kubernetes 管理节点执行以下命令提交任务。
kubectl create -f sample.yaml
1.4.5. 检查调度结果
在 Kubernetes 管理节点执行以下命令检查任务的调度节点。
kubectl get pod -owide
NAME READY STATUS RESTARTS AGE NODE
sample-pod 1/1 Running 0 31s sgpu-node
1.5. 部署 Volcano 方案
1.5.1. 安装 GPU Operator
1.5.1.1. 常规 GPU 集群
安装 GPU Operator
以容器镜像仓库地址为
DOMAIN/PROJECT为例,在 Kubernetes 管理节点执行以下命令安装 GPU Operator 。helm install ./k8s/metax-operator-0.13.0.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait \ --set registry=DOMAIN/PROJECT
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n metax-operator NAME READY STATUS RESTARTS AGE metax-container-runtime-4lsd7 1/1 Running 0 31s metax-gpu-device-7774b 1/1 Running 0 31s metax-gpu-label-l5tkf 1/1 Running 0 31s metax-operator-1755847288-77bfc94568-7wqlh 1/1 Running 0 31s ...
检查节点资源
以 sample-node1 节点为例,在 Kubernetes 管理节点执行以下命令检查节点资源。
kubectl get node sample-node1 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("metax-tech.com/gpu")))' # 示例输出 { "metax-tech.com/gpu": "8" }
1.5.1.2. 超节点集群( SwitchBox 拓扑形态集群)
获取cluster-manager组件信息
获取 cluster-manager 组件的服务地址和用户密码。这里以服务地址为
https://127.0.0.1,用户名为 metax ,密码为 test 为例。执行以下命令。export CLUSTER_ADDR=https://127.0.0.1 export CLUSTER_USER=$(echo metax | base64) export CLUSTER_PASSWORD=$(echo test | base64)
安装 GPU Operator
以容器镜像仓库地址为
DOMAIN/PROJECT为例,执行以下命令安装 GPU Operator 。helm install ./k8s/metax-operator-0.13.0.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait \ --set registry=DOMAIN/PROJECT \ --set topoDiscovery.deploy=true \ --set topoDiscovery.mode=switchbox \ --set topoDiscovery.master.env[0].name="CLIENT_GO_QPS" \ --set-string topoDiscovery.master.env[0].value="100" \ --set topoDiscovery.master.env[1].name="CLIENT_GO_BRUST" \ --set-string topoDiscovery.master.env[1].value="100" \ --set topoDiscovery.switchbox.clusterManagerAddress=$CLUSTER_ADDR \ --set topoDiscovery.switchbox.clusterManagerUser=$CLUSTER_USER \ --set topoDiscovery.switchbox.clusterManagerPassword=$CLUSTER_PASSWORD
验证安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于
Running状态。kubectl get pod -n metax-operator NAME READY STATUS RESTARTS AGE metax-container-runtime-4lsd7 1/1 Running 0 31s metax-gpu-device-7774b 1/1 Running 0 31s metax-gpu-label-l5tkf 1/1 Running 0 31s metax-operator-1755847288-77bfc94568-7wqlh 1/1 Running 0 31s metax-topo-master-6f6cdbf65-84lbc 1/1 Running 0 31s metax-topo-worker-57g2d 1/1 Running 0 31s ...
检查节点资源
以 sample-node1 节点为例,在 Kubernetes 管理节点执行以下命令检查节点资源。
kubectl get node sample-node1 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("metax-tech.com/gpu")))' # 示例输出 { "metax-tech.com/gpu": "8" }
检查超节点集群拓扑
在 Kubernetes 管理节点执行以下命令检查超节点集群拓扑是否和物理拓扑一致。
TOPO_MASTER_IP=`kubectl get pod -n metax-gpu -owide | grep topo-master | awk {'print $6'}` curl $TOPO_MASTER_IP:9001/node_group
例如在拓扑为两节点组成一个 dragonfly 组,两个 dragonfly 节点组成一个 switchbox 组的集群中,则可看到以下内容。
[ { "name": "switchbox-sample1", "kind": "switchbox", "child": [ { "name": "dragonfly-sample1", "kind": "dragonfly", "child": [ { "name": "node-sample1", "kind": "node", "status": "Ready" }, { "name": "node-sample2", "kind": "node", "status": "Ready" } ], "status": "Ready" }, { "name": "dragonfly-sample2", "kind": "dragonfly", "child": [ { "name": "node-sample3", "kind": "node", "status": "Ready" }, { "name": "node-sample4", "kind": "node", "status": "Ready" } ], "status": "Ready" } ], "status": "Ready" } ]
1.5.2. 安装 Volcano
1.5.2.1. 解压 Volcano 离线安装包
Volcano 相关的容器镜像及 Helm Chart 以离线形式发布。 以 0.13.0 版本为例,用户可从 沐曦软件中心 获取离线安装包 volcano-package-0.13.0.tar.gz,并进行解压缩。
mkdir k8s
tar -C k8s -xvzf volcano-package.0.13.0.tar.gz
volcano-images.0.13.0.run
volcano-0.13.0.tgz
1.5.2.2. 推送 Volcano 容器镜像
以容器镜像仓库地址为 DOMAIN/PROJECT 为例,用户可执行以下命令将 Volcano 镜像推送到镜像仓库。
./k8s/volcano-images.0.13.0.run push DOMAIN/PROJECT
备注
当前版本仅支持 Docker 作为容器镜像推送工具,需确保节点已预装 Docker。
1.5.2.3. 安装 Volcano
以容器镜像仓库地址为 DOMAIN/PROJECT 为例,在 Kubernetes 管理节点执行以下命令安装 Volcano 。
helm install volcano volcano-0.13.0.tgz --create-namespace -n volcano \
--set basic.controller_image_name=DOMAIN/PROJECT/vc-controller-manager \
--set basic.scheduler_image_name=DOMAIN/PROJECT/vc-scheduler \
--set basic.admission_image_name=DOMAIN/PROJECT/vc-webhook-manager \
--wait
1.5.2.4. 检查安装状态
在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于 Running 状态。
kubectl get pod -n volcano
NAME READY STATUS RESTARTS AGE
volcano-admission-67c4564c6-twzdj 1/1 Running 0 31s
volcano-admission-init-mbtnr 0/1 Completed 0 31s
volcano-controllers-568447f669-g844c 1/1 Running 0 31s
volcano-scheduler-76d6458568-sjbbl 1/1 Running 0 31s
1.5.3. 配置 Volcano 调度插件
在 Kubernetes 管理节点执行以下命令更新 Volcano 调度插件配置。
kubectl edit configmaps -n volcano volcano-scheduler-configmap
超节点集群( SwitchBox 拓扑形态集群):添加
gpu-podaffinity调度插件。1apiVersion: v1 2data: 3 volcano-scheduler.conf: | 4 actions: "enqueue, allocate, backfill" 5 tiers: 6 - plugins: 7 - name: priority 8 - name: gang 9 enablePreemptable: false 10 - name: conformance 11 - name: gpu-podaffinity # add it to enable gpu-podaffinity plugin 12 - plugins: 13 - name: overcommit 14 - name: drf 15 enablePreemptable: false 16 - name: predicates 17 - name: proportion 18 - name: nodeorder 19 - name: binpack
常规 GPU 集群:添加
gpu-aware调度插件。1apiVersion: v1 2data: 3 volcano-scheduler.conf: | 4 actions: "enqueue, allocate, backfill" 5 tiers: 6 - plugins: 7 - name: priority 8 - name: gang 9 enablePreemptable: false 10 - name: conformance 11 - plugins: 12 - name: overcommit 13 - name: drf 14 enablePreemptable: false 15 - name: predicates 16 - name: proportion 17 - name: nodeorder 18 - name: binpack 19 - name: gpu-aware # add it to enable gpu-ware plugin 20 arguments: # add it to enable gpu-ware plugin 21 weight: 1 # add it to enable gpu-ware plugin 22 loss.weight: 0.5 # add it to enable gpu-ware plugin
1.5.4. 编写任务 YAML
超节点集群( SwitchBox 拓扑形态集群):创建 sample.yaml,用户可参考以下示例编写任务文件。
1apiVersion: batch.volcano.sh/v1alpha1 2kind: Job 3metadata: 4 name: pytorch-demo 5spec: 6 schedulerName: volcano 7 plugins: 8 pytorch: ["--master=master","--worker=worker","--port=23456"] # Pytorch plugin register 9 tasks: 10 - replicas: 1 11 name: master 12 policies: 13 - event: TaskCompleted 14 action: CompleteJob 15 template: 16 metadata: 17 annotations: 18 metax-tech.com/gpu-group-size: "64" 19 spec: 20 containers: 21 - image: alpine:3.19 22 imagePullPolicy: IfNotPresent 23 name: master 24 command: ['sh', '-c'] 25 args: ["sleep infinity"] 26 resources: 27 limits: 28 metax-tech.com/gpu: 8 29 restartPolicy: Never 30 - replicas: 7 31 name: worker 32 template: 33 spec: 34 containers: 35 - image: alpine:3.19 36 imagePullPolicy: IfNotPresent 37 name: worker 38 command: ['sh', '-c'] 39 args: ["sleep infinity"] 40 resources: 41 limits: 42 metax-tech.com/gpu: 8
常规 GPU 集群:创建 sample.yaml,用户可参考以下示例编写任务文件。
apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: job-demo spec: minAvailable: 1 schedulerName: volcano policies: - event: PodEvicted action: RestartJob plugins: env: [] ssh: [] svc: [] maxRetry: 2 queue: default tasks: - replicas: 2 name: "gpu-vectoradd" template: spec: containers: - name: ubuntu image: ubuntu:22.04 imagePullPolicy: IfNotPresent command: ['bash', '-c'] args: ["sleep 10s"] resources: limits: metax-tech.com/gpu: 2 restartPolicy: Never
1.5.5. 提交任务
在Kubernetes管理节点执行以下命令提交任务。
kubectl create -f sample.yaml
1.5.6. 检查调度结果
在 Kubernetes 管理节点执行以下命令检查任务的调度节点。
kubectl get pod -owide
NAME READY STATUS RESTARTS AGE NODE
sample-pod1 1/1 Running 0 31s gpu-node1
sample-pod2 1/1 Running 0 31s gpu-node2
...