一、 背景
在 kubernetes 中,节点被抽象成了一种资源(resource),目前官方为节点的可分配资源大小定义了5种属性:cpu、memory、ephemeral-storage、hugepages-1Gi、hugepages-2Mi 当我们创建一个 Pod,调度器会判断 Pod 的 requests(所需资源)是否满足当前节点的可分配资源,决定该 Pod 能否运行在这个节点上。 在很多业务场景下,仅仅依靠 CPU、内存、磁盘等基础资源无法完整描述一个节点具有的资源属性(如:GPU、网卡带宽、可分配IP数等资源)。因此,Kubernetes 为节点资源描述提供了一种扩展机制,可根据需求自定义节点的扩展资源(extended resource for node)
二、 节点扩展资源
Extended Resource For Node 本质上是通过调用 kube api 为节点新增自定义的资源属性:
PATCH /api/v1/nodes/<your-node-name>/status HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Host: k8s-master:8080
[
{
"op": "add",
"path": "/status/capacity/example.com~1dongle",
"value": "4"
}
]
上面的样例通过调用kube-api,为节点patch了一个名字为example.com/dongle
的资源属性,当我们用 kubectl get node <your-node-name> -oyaml
查看该节点的资源容量时,发现节点的资源多了example.com/dongle
这种类型
Capacity:
cpu: 2
memory: 2049008Ki
example.com/dongle: 4
这意味着当我们创建一个 Pod,且它的 requests 带有 example.com/dongle
这种资源需求时,调度器会考虑节点 example.com/dongle
这种扩展资源,当节点有足够的 example.com/dongle
时,Pod 才能够成功调度。
三、 Device Plugin
Device Plugin
是 Kubernetes 官方提供的动态检测节点可分配资源(GPU、网卡带宽、可分配IP数等自定义扩展资源)的一种自定义插件,该插件一般通过 Daemonset 部署在集群中的每个节点上。
自定义插件通过启动一个 gRPC 服务并实现标准的 Device Plugin 接口,插件可实时获取节点的可分配扩展资源并更新,Kubelet 通过 List/Watch 机制实时获取到 Device Plugin 返回的节点可分配资源的信息。
下图为 Kubelet 与 Device Plugin 交互的示意图:
图片来源
代码样例:AMD GPU device plugin
四、 应用场景
以上提到的两种方式都能够自定义扩展节点资源,直接通过 kube-api 创建、更新节点扩展资源的方式实现上较为简单,适用于节点静态的资源属性(如:网卡带宽、磁盘容量),这种资源的容量信息只需要在组件第一次启动时获取,节点的后续运行过程中资源容量不会再发生变化。 而 Device Plugin 主要解决节点的扩展资源动态变化的问题,需要 Device Plugin 机制监控节点的可分配扩展资源并让 Kubelet 实时感知到资源的变化(如:GPU、NUMA CPU拓扑关系)
本篇文章主要介绍了 Kubernetes 的自定义资源扩展机制,为后续分析更为复杂的扩展调度器插件(scheduler-plugin)做铺垫。