Volcano 是基于 Kubernetes 的批处理系统,方便HPC、 AI、大数据、基因等诸多行业通用计算框架接入,提供高性能任务调度引擎,高性能异构芯片管理,高性能任务运行管理等能力。本文通过介绍Volcano提供的GPU Share调度功能来助力HPC作业在Kubernetes集群中落地。
GPU 共享问题
HPC是一个跨学科的多元化市场,包括化学研究,结构分析,地球物理学,可视化图像处理等领域,并且在大多数HPC应用领域都存在GPU加速的应用程序。据市场研究公司Intersect 360对HPC市场的调查数据,50个最受欢迎的HPC应用软件包中有34个提供GPU支持。
目前,Kubernetes已经成为容器编排的事实标准,容器集群服务商的Kubernetes平台都提供了GPU的调度能力,但通常是将整块GPU卡分配给容器。GPU在集群中属于稀缺资源,在某些场景下,这种独享的GPU资源的分配策略往往会导致GPU资源利用率偏低。Volcano提供调度层面的GPU资源共享,可以使多个Pod运行在同一块GPU卡上,从而提升集群GPU资源整体利用率。
Volcano GPU共享设计
Volcano通过Kubernetes自定义扩展资源机制定义了GPU相关的“volcano.sh/gpu-memory”和“volcano.sh/gpu-number”两种资源,其中“volcano.sh/gpu-memory”用来描述节点GPU显存信息;“volcano.sh/gpu-number”用来描述节点GPU卡的数量。
Volcano通过Kubernetes提供的Device plugin实现如下功能:
用户可以从Volcano device plugin for Kubernetes获取如何安装、使用volcano GPU插件的详细信息。
在集群部署GPU device plugin后,可以查看节点状态来查看节点上GPU显存与GPU卡数量信息:
$ kubectl get node {node name} -oyaml
...
status:
addresses:
- address: 172.17.0.3
type: InternalIP
- address: volcano-control-plane
type: Hostname
allocatable:
cpu: "4"
ephemeral-storage: 123722704Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 8174332Ki
pods: "110"
volcano.sh/gpu-memory: "89424"
volcano.sh/gpu-number: "8" # GPU resource
capacity:
cpu: "4"
ephemeral-storage: 123722704Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 8174332Ki
pods: "110"
volcano.sh/gpu-memory: "89424"
volcano.sh/gpu-number: "8" # GPU resource
工作流程
1)GPU device plugin收集并上报GPU资源:
Device plugin通过nvml库可以查询节点上GPU卡的数量和显存信息。通过Kubernetes提供的ListAndWatch功能将以上收集到的扩展资源信息通过kubelet报告给API Server。同时,device plugin提供GPU健康状态检查功能,当某块GPU卡出现异常的情况下,可以及时更新集群资源信息。
2)用户提交申请8000MB GPU显存的Pod到Kube-APIServer。
3)Volcano GPU调度插件:
kubectl edit cm -n volcano-system volcano-scheduler-configmap
kind: ConfigMap
apiVersion: v1
metadata:
name: volcano-scheduler-configmap
namespace: volcano-system
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: priority
- name: gang
- name: conformance
- plugins:
- name: drf
- name: predicates
arguments:
predicate.GPUSharingEnable: true # enable GPU sharing
- name: proportion
- name: nodeorder
- name: binpack
4)启动容器:
节点上的Kubelet在收到Pod和节点绑定时间后,会创建Pod实体,Kubelet调用GPU plugin中实现的Allocate方法。该方法首先在节点所有pending状态的pod中选取出“volcano.sh/gpu-assigned”为false且predicate时间最早的pod进行创建,并更新该pod的“volcano.sh/gpu-assigned”为true。
使用GPU Share功能
提交gpu-pod1和gpu-pod2两个pod,分别请求1024MB GPU显存。利用Volcano GPU share调度功能,将两个pod调度到同一个GPU卡上。
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod1
spec:
schedulerName: volcano
containers:
- name: cuda-container
image: nvidia/cuda:10.1-base-ubuntu18.04
command: ["sleep"]
args: ["100000"]
resources:
limits:
volcano.sh/gpu-memory: 1024 # requesting 1024MB GPU memory
---
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod2
spec:
schedulerName: volcano
containers:
- name: cuda-container
image: nvidia/cuda:10.1-base-ubuntu18.04
command: ["sleep"]
args: ["100000"]
resources:
limits:
volcano.sh/gpu-memory: 1024 # requesting 1024MB GPU memory
查看pod运行情况:
查看gpu-pod1环境变量,该pod被分配到GPU0卡上运行:
查看gpu-pod2环境变量,该pod被分配到GPU0卡上运行:
查看节点GPU显存分配情况:
通过上述结果可以看出,Volcano GPU共享功能可以把多个Pod调度到相同的GPU卡上,达到GPU显存share的目的,从而提升集群GPU资源整体利用率。
如果想要在Volcano中使用GPU Share功能运行HPC作业,只需要将https://github.com/volcano-sh/volcano/blob/master/example/integrations/mpi/mpi-example.yaml 例子中的image替换为支持GPU的image,同时为worker任务指定“volcano.sh/gpu-memory”就可以使用了。
【参考文献】
1.https://github.com/volcano-sh/volcano/blob/master/docs/user-guide/how_to_use_gpu_sharing.md
2. https://github.com/volcano-sh/devices
3. https://github.com/volcano-sh/volcano
深入了解Volcano