具体流程:
-
资源上报
GPU Share Device Plugin利用nvml库查询到GPU卡的数量和每张GPU卡的显存, 通过ListAndWatch()将节点的GPU总显存(数量 显存)作为另外Extended Resource汇报给Kubelet; Kubelet进一步汇报给Kubernetes API Server。 举例说明,如果节点含有两块GPU卡,并且每块卡包含16276MiB,从用户的角度来看:该节点的GPU资源为16276 2 = 32552; 同时也会将节点上的GPU卡数量2作为另外一个Extended Resource上报。 -
扩展调度
GPU Share Scheduler Extender可以在分配gpu-mem给Pod的同时将分配信息以annotation的形式保留在Pod spec中,并且在过滤时刻根据此信息判断每张卡是否包含足够可用的gpu-mem分配。
2.1 Kubernetes默认调度器在进行完所有过滤(filter)行为后会通过http方式调用GPU Share Scheduler Extender的filter方法, 这是由于默认调度器计算Extended Resource时,只能判断资源总量是否有满足需求的空闲资源,无法具体判断单张卡上是否满足需求;所以就需要由GPU Share Scheduler Extender检查单张卡上是否含有可用资源。
- 节点上运行
当Pod和节点绑定的事件被Kubelet接收到后,Kubelet就会在节点上创建真正的Pod实体,在这个过程中, Kubelet会调用GPU Share Device Plugin的Allocate方法, Allocate方法的参数是Pod申请的gpu-mem。而在Allocate方法中,会根据GPU Share Scheduler Extender的调度决策运行对应的Pod
3.1 会列出该节点中所有状态为Pending并且ALIYUN_COM_GPU_MEM_ASSIGNED为false的GPU Share Pod
3.2 选择出其中Pod Annotation的ALIYUN_COM_GPU_MEM_POD的数量与Allocate申请数量一致的Pod。如果有多个符合这种条件的Pod,就会选择其中ALIYUN_COM_GPU_MEM_ASSUME_TIME最早的Pod。
3.3 将该Pod的annotation ALIYUN_COM_GPU_MEM_ASSIGNED设置为true,并且将Pod annotation中的GPU信息转化为环境变量返回给Kubelet用以真正的创建Pod。
4.其他
1)、基于aliyun.com/gpu-mem的调度.
2)、一张卡对应一个POD,一个POD对应30任务(现在是固定的)。
两种场景,一种是多主机一卡,一会总是一主机多卡。
3)、调度是先跑满1个POD,然后切换到另外一个POD。
4)、Task和POD的关联关系。
5)、POD跑了10个任务,挂掉了,如何处理?。
6)、如何指定pod分配到指定node上?(公有云上不需要指定,云边协同需要指定)
使用Pod中的nodeSelector属性来实现。Node Selector会指定key-value pairs,pod会被分配到特定node上,该node具有所有指定key-value pairs对应labels。通常只有一对key-value。
依赖gpu scheduler, 以及nvidia docker。
GPU Share Scheduler Extender: 利用Kubernetes的调度器扩展机制,负责在全局调度器Filter和Bind的时候判断节点上单个GPU卡是否能够提供足够的GPU Mem,并且在Bind的时刻将GPU的分配结果通过annotation记录到Pod Spec以供后续Filter检查分配结果。
GPU Share Device Plugin: 利用Device Plugin机制,在节点上被Kubelet调用负责GPU卡的分配,依赖scheduler Extender分配结果执行。
extended-resources
extended-resources在k8s1.9中是一个stable的特性。可以用一句话来概括这个特性:
通过向apiserver发送一个patch node 的请求,为这个node增加一个自定义的资源类型,用于以该资源的配额统计和相应的QoS的配置。
patch node 的请求:
举例:
curl --header “Content-Type: application/json-patch+json”
–request PATCH
–data ‘[{“op”: “add”, “path”: “/status/capacity/example.com~1dongle”, “value”: “4”}]’
http://localhost:8001/api/v1/nodes/10.123.123.123/status
如上,我们为10.123.123.123这个node增加了一个resource:example.com/dongle (命令中的 ~1 会转化为 / ) ,这个node的capicity/allocable中会展示其有4个example.com/dongle资源:
“capacity”: {
“alpha.kubernetes.io/nvidia-gpu”: “0”,
“cpu”: “2”,
“memory”: “2049008Ki”,
“example.com/dongle”: “4”,
如果我们要清除这个资源可以使用:
curl --header “Content-Type: application/json-patch+json”
–request PATCH
–data ‘[{“op”: “remove”, “path”: “/status/capacity/example.com~1dongle”}]’
http://localhost:8001/api/v1/nodes//status
device-plugin插件
设备插件从1.8版本开始加入,到1.9目前仍是alpha特性,设备插件的作用是在不更改k8s代码的情况下,向k8s提供各种资源的统计信息和使用预备工作。这里说的资源如GPU、高性能NIC、FPGA、infiniBand或其他。