Kubernetes v1.8 开始增加了 Alpha 版的 Device 插件,用来支持 GPU、FPGA、高性能 NIC、InfiniBand 等各种设备。这样,设备厂商只需要根据 Device Plugin 的接口实现一个特定设备的插件,而不需要修改 Kubernetes 核心代码。
在 v1.10 中该特性升级为 Beta 版本。
注意: 从 Kubernetes v1.26 开始,引入了 Dynamic Resource Allocation (DRA) 作为 Device 插件的演进版本,提供了更灵活的资源分配机制。详见本文后面的 DRA 章节。
使用 Device 插件之前,首先要开启 DevicePlugins 功能,即配置 --feature-gates=DevicePlugins=true(默认是关闭的)。
Device 插件实际上是一个 gPRC 接口,需要实现 ListAndWatch() 和 Allocate() 等方法,并监听 gRPC Server 的 Unix Socket 在 /var/lib/kubelet/device-plugins/ 目录中,如 /var/lib/kubelet/device-plugins/nvidiaGPU.sock。在实现 Device 插件时需要注意
- 插件启动时,需要通过
/var/lib/kubelet/device-plugins/kubelet.sock向 Kubelet 注册,同时提供插件的 Unix Socket 名称、API 的版本号和插件名称(格式为vendor-domain/resource,如nvidia.com/gpu)。Kubelet 会将这些设备暴露到 Node 状态中,方便后续调度器使用 - 插件启动后向 Kubelet 发送插件列表、按需分配设备并持续监控设备的实时状态
- 插件启动后要持续监控 Kubelet 的状态,并在 Kubelet 重启后重新注册自己。比如,Kubelet 刚启动后会清空
/var/lib/kubelet/device-plugins/目录,所以插件作者可以监控自己监听的 unix socket 是否被删除了,并根据此事件重新注册自己
Device 插件一般推荐使用 DaemonSet 的方式部署,并将 /var/lib/kubelet/device-plugins 以 Volume 的形式挂载到容器中。当然,也可以手动运行的方式来部署,但这样就没有失败自动恢复的功能了。
NVIDIA 提供了一个基于 Device Plugins 接口的 GPU 设备插件 NVIDIA/k8s-device-plugin。
编译
git clone https://github.com/NVIDIA/k8s-device-plugin
cd k8s-device-plugin
docker build -t nvidia-device-plugin:1.0.0 .部署
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/master/nvidia-device-plugin.yml创建 Pod 时请求 GPU 资源
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
restartPolicy: OnFailure
containers:
- image: nvidia/cuda
name: pod1-ctr
command: ["sleep"]
args: ["100000"]
resources:
limits:
nvidia.com/gpu: 1注意:使用该插件时需要配置 nvidia-docker 2.0,并配置 nvidia 为默认运行时 (即配置 docker daemon 的选项 --default-runtime=nvidia)。nvidia-docker 2.0 的安装方法为(以 Ubuntu Xenial 为例,其他系统的安装方法可以参考 这里):
# Configure repository
curl -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
sudo tee /etc/apt/sources.list.d/nvidia-docker.list <<< \
"deb https://nvidia.github.io/libnvidia-container/ubuntu16.04/amd64 /
deb https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/amd64 /
deb https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64 /"
sudo apt-get update
# Install nvidia-docker 2.0
sudo apt-get install nvidia-docker2
sudo pkill -SIGHUP dockerd
# Check installation
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smiGCP 也提供了一个 GPU 设备的插件,仅适用于 Google Container Engine,可以访问 GoogleCloudPlatform/container-engine-accelerators 查看。
Dynamic Resource Allocation (DRA) 是 Kubernetes v1.26 引入的 Alpha 特性,是 Device 插件的下一代演进方案。DRA 提供了更灵活、更细粒度的设备资源分配机制。
在 Kubernetes v1.33 中,DRA 已经发生了重要的更新:
- Driver-owned Resource Claim Status (Beta): 允许驱动程序为已分配的设备报告特定于设备的状态数据
-
可分区设备 (Partitionable Devices)
- 允许驱动程序通告重叠的逻辑设备"分区"
- 支持物理设备的动态重新配置以提高利用率
-
设备污点与容忍度 (Device Taints and Tolerations)
- 允许将设备标记为不可用
- 支持基于污点阻止设备分配或 Pod 驱逐
-
优先级列表 (Prioritized List)
- 允许用户指定多个可接受的设备备选方案
- 调度器尝试按优先级顺序分配最佳可用设备
-
管理员访问控制 (Admin Access)
- 限制只有具有特定管理员访问标签的命名空间才能创建 ResourceClaim
- 防止非管理员用户误用设备管理功能
| 特性 | Device 插件 | DRA |
|---|---|---|
| 资源分配 | 静态,启动时分配 | 动态,按需分配 |
| 设备共享 | 有限支持 | 灵活的分区和共享 |
| 资源类型 | 固定类型 | 自定义资源类 |
| 配置灵活性 | 基本配置 | 丰富的配置选项 |
| 错误恢复 | 有限 | 更好的错误处理 |
- 资源类定义: 管理员定义 ResourceClass,描述可用的设备类型和配置
- 资源声明: 用户创建 ResourceClaim,请求特定类型的资源
- 调度决策: 调度器考虑资源可用性进行 Pod 调度
- 资源分配: DRA 驱动程序分配具体设备给 Pod
- 设备使用: Pod 使用分配的设备资源
- 资源释放: Pod 完成后自动释放资源
# ResourceClass 定义
apiVersion: resource.k8s.io/v1alpha2
kind: ResourceClass
metadata:
name: gpu-class
spec:
driverName: gpu.example.com
parameters:
memory: "8Gi"
compute: "high"
---
# ResourceClaim 声明
apiVersion: resource.k8s.io/v1alpha2
kind: ResourceClaim
metadata:
name: my-gpu-claim
spec:
resourceClassName: gpu-class
---
# Pod 使用资源
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: gpu-container
image: nvidia/cuda
resources:
claims:
- name: gpu-resource
request: my-gpu-claim
resourceClaims:
- name: gpu-resource
source:
resourceClaimName: my-gpu-claimDRA 计划在 Kubernetes v1.34 中升级为 GA(Generally Available)状态。未来的发展包括:
- 默认启用更多 DRA 特性
- v1.33 的 Alpha 特性将在 v1.34 中升级为 Beta
- 改进的用户体验和 API 简化
对于新项目,建议考虑使用 DRA 而不是传统的 Device 插件,特别是在以下场景:
- 需要动态设备分配
- 需要设备分区或共享
- 需要复杂的设备配置
- 需要更好的错误处理和恢复
