LabHub
学习 学习路径 课程

GPU Operator 与时间片

ClusterPolicy、RuntimeClass、资源上报

在 LabHub 中继续学习

一句话总结

GPU PAD要弹出,必须通过彼此没有任何关系的两个门户。 Scheduler看到的nvidia.com/gpu资源和节点的运行时间RuntimeClass是手柄。只要有一个就够了,帕德也不会告诉你哪一个是两个中哪个卡住了。

概念图: 彼此没有任何关系的两个门户 · 是资源方面 · 运行时方面 · 资源方面。

为什么需要这种区分呢?

收到“GPU板不亮”的报告时,症状正好是两种中的一种。

如果教不了这两个人,就会花几个小时翻阅device plugin日志,发现其实是containerd的问题。相反的情况也是一样的。如果知道两个门户为什么分开,就可以在前3分钟决定路线。

怎么行动

资源方面。GPU不是像cpu·memory一样kubelet自己计算的资源。device plugin在节点上打开设备并把列表传递给kubelet时,kubelet将该数量作为节点对象的status.capacitystatus.allocatable用扩展资源写入。调度器看到的不是设备,而是那个数字。所以即使只有数字,没有设备,调度也会成立(这就是这个课程实训所在的位置),相反,即使设备完好无损,但plugin死了,调度器会判断那个节点没有GPU。

扩展资源还有一个规则。requestslimits不能单独给。limits写在上的价格就是requests可以,必须是正数。因为GPU不能减少0.5张。

运行时方面。RuntimeClass是选择“用哪个运行时处理器制作这个派德”的聚类范围对象。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia          # 이 문자열이 containerd 설정의 runtimes.<이름> 과 맞아야 한다

kubelet在创建派对时handler将字符串发送到CRI请求中,containerd是自己设置的runtimes在表中寻找相同的名称。如果没有,就会拒绝创建容器。这里重要的是API服务器不会验证这个名称RuntimeClasskubectl apply可以随时制作,即使指着不存在的处理器,也没有人警告。制作那个不和谐的板子的瞬间,也只有在那个节点才能显现出来。

把两个关门的关系用一行整理的话是这样的。

스케줄러  : nvidia.com/gpu 숫자를 보고 "어느 노드로 보낼까" 를 정한다
kubelet   : RuntimeClass handler 를 containerd 에 넘겨 "어떻게 만들까" 를 정한다

在现场相遇的样子

第一,runtimeClassName有很多不用用的群集。 toolkit包含container的default_runtime_name完全nvidia因为更换放置的配置很常见。虽然方便,但也有代价——即使不使用GPU的板也会运行nvidia时间,如果这个设置被破坏,不是GPU板,而是整个群集的所有板都无法启动。事故的范围会不同。

第二,正在转移到CDI中。 Container Device Interface是将“将设备放入容器的方法”标准化为与运行时类型无关的JSON/YAML规格。使用CDI的话,即使没有nvidia专用运行时二进制文件nvidia.com/gpu=all可以以相同的设备名称注入。但是,containerd方面对CDI的支持因版本而异,打开的方法也不同,所以现在现场混合了两种方式。

第三,Pending的原因不仅仅是资源。 GPU节点通常有nvidia.com/gpu=present:NoSchedule因为附着着相同的涂层,所以防止普通工作负载占用昂贵的节点。如果GPU板没有容差,即使有剩余资源也不会被调度。kubectl describe pod这就是为什么的最后一个活动总是要先读第一句话的原因。

下次实习要做的事情

接下来在实训中,在两个关口中资源方面从八个步骤走到最后。在node status上写上扩展资源,让scheduler判断,看到requests和limits规则在apiserver上被阻止,即使是相同的Pending,也会通过消息区分是原因是taint还是资源。如果在这里能准确地分叉,后面出现的事故故事就会读得更快。