ClusterPolicy、RuntimeClass、资源上报
一句话总结
GPU PAD要弹出,必须通过彼此没有任何关系的两个门户。 Scheduler看到的nvidia.com/gpu资源和节点的运行时间RuntimeClass是手柄。只要有一个就够了,帕德也不会告诉你哪一个是两个中哪个卡住了。
为什么需要这种区分呢?
收到“GPU板不亮”的报告时,症状正好是两种中的一种。
- 帕德
Pending在不移动。→ 是资源方面。任何节点都nvidia.com/gpu没有宣传或座位满了。 - 帕德粘在了节点上
ContainerCreating死于。→ 运行时方面。那个节点的containerd上没有注册处理器。
如果教不了这两个人,就会花几个小时翻阅device plugin日志,发现其实是containerd的问题。相反的情况也是一样的。如果知道两个门户为什么分开,就可以在前3分钟决定路线。
怎么行动
资源方面。GPU不是像cpu·memory一样kubelet自己计算的资源。device plugin在节点上打开设备并把列表传递给kubelet时,kubelet将该数量作为节点对象的status.capacity哇status.allocatable用扩展资源写入。调度器看到的不是设备,而是那个数字。所以即使只有数字,没有设备,调度也会成立(这就是这个课程实训所在的位置),相反,即使设备完好无损,但plugin死了,调度器会判断那个节点没有GPU。
扩展资源还有一个规则。requests哇limits不能单独给。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服务器不会验证这个名称。RuntimeClass是kubectl 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还是资源。如果在这里能准确地分叉,后面出现的事故故事就会读得更快。