1 - 在集群中安装 DRA
Kubernetes v1.35 [stable](默认启用)本文介绍如何在 Kubernetes 集群中通过启用 API 组并配置设备类别来设置动态资源分配(DRA)。 这些指示说明适用于集群管理员。
关于 DRA
Kubernetes 提供的一项特性,允许你在多个 Pod 之间请求和共享资源。
这些资源通常是挂接的设备,例如硬件加速器。
借助 DRA,设备驱动和集群管理员可以定义设备的类别,这些类别可供工作负载中的 Pod 申领。 Kubernetes 会将匹配的设备分配给特定的申领,并将相应的 Pod 调度到能够访问这些已分配设备的节点上。
确保你已了解 DRA 的工作机制及其术语,例如 DeviceClasses、 ResourceClaims以及 ResourceClaimTemplates。 更多信息请参见动态资源分配(DRA)。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.34.要获知版本信息,请输入 kubectl version.
- 将设备直接或间接挂接到你的集群中。为避免驱动相关的问题,请在安装驱动之前先完成 DRA 特性的配置。
可选:启用额外的 DRA API 组
DRA 整体上已经是 Kubernetes 中的稳定特性;但其中的某些具体功能仍可能处于 Alpha 或 Beta 阶段。 如果你希望使用尚未稳定的 DRA 相关能力,并且该能力依赖于某个专用的 API 类别, 则你必须显式启用对应的 Alpha 或 Beta 级别的 API 组。 一些较旧的 DRA 驱动或工作负载可能仍需要 Kubernetes 1.30 的 v1beta1 API 或 Kubernetes 1.32 的 v1beta2 API。 当且仅当需要支持这些时,才启用以下 API 组:
resource.k8s.io/v1beta1resource.k8s.io/v1beta2
带有独立 API 类型的 Alpha 特性需要启用:
resource.k8s.io/v1alpha3
更多信息请参阅启用或禁用 API 组。
验证是否启用了 DRA
若要验证集群是否配置正确,可尝试列出 DeviceClass:
kubectl get deviceclasses
如果组件配置正确,输出类似如下:
No resources found
如果 DRA 未正确配置,则上述命令的输出可能如下:
error: the server doesn't have a resource type "deviceclasses"
例如,当 resource.k8s.io API 组被禁用时,就可能出现这种情况。 类似的检查同样适用于处于 Alpha 或 Beta 阶段的顶层 API 类型。
你可以尝试以下排查步骤:
-
重新配置并重启
kube-apiserver组件。 -
如果从 Pod 中完全删除了
.spec.resourceClaims字段, 或者 Pod 在不考虑 ResourceClaim 的情况下被调度, 那么请验证DynamicResourceAllocation特性门控在 kube-apiserver、kube-controller-manager、kube-schedule 或 kubelet 组件中是否被关闭。
安装设备驱动
你启用集群的 DRA 特性后,你可以安装所挂接设备的驱动。 安装方式请参见设备所有者或驱动维护方提供的文档。你安装的驱动必须与 DRA 兼容。
若要验证驱动是否正常工作,可列出集群中的 ResourceSlice:
kubectl get resourceslices
输出示例如下:
NAME NODE DRIVER POOL AGE
cluster-1-device-pool-1-driver.example.com-lqx8x cluster-1-node-1 driver.example.com cluster-1-device-pool-1-r1gc 7s
cluster-1-device-pool-2-driver.example.com-29t7b cluster-1-node-2 driver.example.com cluster-1-device-pool-2-446z 8s
尝试以下故障排查步骤:
- 检查 DRA 驱动的健康状况,并在其日志输出中查找关于发布 ResourceSlice 的错误消息。驱动的供应商可能有关于安装和故障排除的进一步指示。
创建 DeviceClass
你可以通过创建 DeviceClasses 定义设备的分类,供应用运维人员在工作负载中申领这些设备。 某些设备驱动提供方也可能在驱动安装过程中要求你创建 DeviceClass。
你的驱动所发布的 ResourceSlice 中包含了设备的相关信息,例如容量、元数据和属性。你可以使用 通用表达式语言(CEL) 表达式按 DeviceClass 中的属性进行筛选, 从而帮助工作负载运维人员更轻松地找到合适的设备。
-
若要查看可通过 CEL 表达式在 DeviceClass 中选择的设备属性,你可以查看某个 ResourceSlice 的规约:
kubectl get resourceslice <resourceslice-name> -o yaml输出类似如下:
apiVersion: resource.k8s.io/v1 kind: ResourceSlice # 为简洁省略部分内容 spec: devices: - attributes: type: string: gpu capacity: memory: value: 64Gi name: gpu-0 - attributes: type: string: gpu capacity: memory: value: 64Gi name: gpu-1 driver: driver.example.com nodeName: cluster-1-node-1 # 为简洁省略部分内容你也可以查阅驱动提供商的文档,了解可用的属性和对应值。
-
查看以下 DeviceClass 示例清单,它选择所有由
driver.example.com设备驱动管理的设备:apiVersion: resource.k8s.io/v1beta2 kind: DeviceClass metadata: name: example-device-class spec: selectors: - cel: expression: |- device.driver == "driver.example.com"
-
在集群中创建 DeviceClass:
kubectl apply -f https://k8s.io/examples/dra/deviceclass.yaml
清理
要删除本任务中创建的 DeviceClass,运行以下命令:
kubectl delete -f https://k8s.io/examples/dra/deviceclass.yaml
接下来
2 - 使用 DRA 为工作负载分配设备
Kubernetes v1.35 [stable](默认启用)本文介绍如何使用动态资源分配(DRA) 为 Pod 分配设备。 这些指示说明面向工作负载运维人员。在阅读本文之前,请先了解 DRA 的工作原理以及相关术语,例如 ResourceClaim 和 ResourceClaimTemplate。 更多信息参阅动态资源分配(DRA)。
关于使用 DRA 分配设备
作为工作负载运维人员,你可以通过创建 ResourceClaim 或 ResourceClaimTemplate 来申领工作负载所需的设备。当你部署工作负载时,Kubernetes 和设备驱动会找到可用的设备, 将其分配给 Pod,并将 Pod 调度到可访问这些设备的节点上。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 v1.34.要获知版本信息,请输入 kubectl version.
- 请确保集群管理员已安装好 DRA,挂接了设备并安装了驱动程序。 详情请参见在集群中安装 DRA。
寻找可申领的设备
你的集群管理员或设备驱动程序会创建定义设备类别的 DeviceClass。你可以使用 通用表达式语言(CEL) 表达式筛选特定的设备属性,从而申领设备。
获取集群中的 DeviceClass 列表:
kubectl get deviceclasses
输出类似如下:
NAME AGE
driver.example.com 16m
如果你遇到权限错误,你可能无权获取 DeviceClass。 请与你的集群管理员或驱动提供商联系,了解可用的设备属性。
申领资源
你可以通过 ResourceClaim 请求某个 DeviceClass 的资源。要创建 ResourceClaim,可以采用以下方式之一:
- 手动创建 ResourceClaim,如果你希望多个 Pod 共享相同设备,或希望申领在 Pod 生命期结束后仍然存在。
- 使用 ResourceClaimTemplate, 让 Kubernetes 为每个 Pod 生成并管理 ResourceClaim。如果你希望每个 Pod 访问独立的、具有类似配置的设备,你可以创建 ResourceClaimTemplate。例如, 在使用并行执行的 Job 中,你可能希望多个 Pod 同时访问设备。
如果你在 Pod 中直接引用了特定 ResourceClaim,该 ResourceClaim 必须已存在于集群中。否则, Pod 会保持在 Pending 状态,直到申领被创建。你可以在 Pod 中引用自动生成的 ResourceClaim, 但不推荐这样做,因为自动生成的 ResourceClaim 的生命期被绑定到了触发生成它的 Pod。
要创建申领资源的工作负载,请选择以下选项之一:
查看以下示例清单:
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
name: example-resource-claim-template
spec:
spec:
devices:
requests:
- name: gpu-claim
exactly:
deviceClassName: example-device-class
selectors:
- cel:
expression: |-
device.attributes["driver.example.com"].type == "gpu" &&
device.capacity["driver.example.com"].memory == quantity("64Gi")
此清单会创建一个 ResourceClaimTemplate,它请求属于 example-device-class
DeviceClass、且同时满足以下两个参数的设备:
- 属性
driver.example.com/type的值为gpu - 容量为
64Gi
创建 ResourceClaimTemplate 的命令如下:
kubectl apply -f https://k8s.io/examples/dra/resourceclaimtemplate.yaml
查看以下示例清单:
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: example-resource-claim
spec:
devices:
requests:
- name: single-gpu-claim
exactly:
deviceClassName: example-device-class
allocationMode: All
selectors:
- cel:
expression: |-
device.attributes["driver.example.com"].type == "gpu" &&
device.capacity["driver.example.com"].memory == quantity("64Gi")
此清单会创建一个 ResourceClaim,请求属于 example-device-class
DeviceClass、且同时满足以下两个参数的设备:
- 属性
driver.example.com/type的值为gpu - 容量为
64Gi
创建 ResourceClaim 的命令如下:
kubectl apply -f https://k8s.io/examples/dra/resourceclaim.yaml
使用 DRA 在工作负载中请求设备
要请求设备分配,请在 Pod 规约的 resourceClaims 字段中指定 ResourceClaim
或 ResourceClaimTemplate,然后在容器的 resources.claims 字段中按名称请求具体的资源申领。
你可以在 resourceClaims 中列出多个条目,并在不同容器中使用特定的申领。
-
查看以下 Job 示例:
apiVersion: batch/v1 kind: Job metadata: name: example-dra-job spec: completions: 10 parallelism: 2 template: spec: restartPolicy: Never containers: - name: container0 image: ubuntu:24.04 command: ["sleep", "9999"] resources: claims: - name: separate-gpu-claim - name: container1 image: ubuntu:24.04 command: ["sleep", "9999"] resources: claims: - name: shared-gpu-claim - name: container2 image: ubuntu:24.04 command: ["sleep", "9999"] resources: claims: - name: shared-gpu-claim resourceClaims: - name: separate-gpu-claim resourceClaimTemplateName: example-resource-claim-template - name: shared-gpu-claim resourceClaimName: example-resource-claim此 Job 中的每个 Pod 具备以下属性:
-
提供名为
separate-gpu-claim的 ResourceClaimTemplate 和名为shared-gpu-claim的 ResourceClaim 给容器使用。 -
运行以下容器:
container0请求separate-gpu-claimResourceClaimTemplate 中定义的设备。container1和container2共享对shared-gpu-claimResourceClaim 中设备的访问。
-
-
创建 Job:
kubectl apply -f https://k8s.io/examples/dra/dra-example-job.yaml
尝试以下故障排查步骤:
- 当工作负载未如预期启动时,从 Job 到 Pod 再到 ResourceClaim 逐步深入检查,
并使用
kubectl describe检查每个层级的对象, 查看是否有状态字段或事件可以解释工作负载为何没有启动。 - 当创建 Pod 失败并显示
must specify one of:resourceClaimName, resourceClaimTemplateName时, 检查pod.spec.resourceClaims中的所有条目是否正好设置了这些字段之一。如果是这样, 那么可能是集群安装了一个针对 Kubernetes < 1.32 的 API 构建的 Pod 变更 Webhook。 请与你的集群管理员合作检查这个问题。
清理
要删除本任务中创建的 Kubernetes 对象,请按照以下步骤操作:
-
删除示例 Job:
kubectl delete -f https://k8s.io/examples/dra/dra-example-job.yaml
-
运行以下其中一条命令来删除你的资源申领:
-
删除 ResourceClaimTemplate:
kubectl delete -f https://k8s.io/examples/dra/resourceclaimtemplate.yaml
-
删除 ResourceClaim:
kubectl delete -f https://k8s.io/examples/dra/resourceclaim.yaml
-
接下来
3 - 访问 DRA 设备元数据
Kubernetes v1.36 [alpha]
本页面展示如何从使用动态资源分配(DRA)的容器中访问 设备元数据。 设备元数据让工作负载能够发现有关已分配设备的信息(如设备属性或网络接口详细信息), 具体方式是在容器内的已知路径读取 JSON 文件。
在阅读本页面之前,你应该熟悉 动态资源分配(DRA) 以及如何为工作负载分配设备。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须是 v1.36.要获知版本信息,请输入 kubectl version.
- 确保集群管理员已安装配置了 DRA、挂接了设备并安装了驱动程序。 更多信息请参阅在集群中设置 DRA。
- 确保集群中部署的 DRA 驱动程序支持设备元数据。
使用 DRA kubelet 插件
的驱动程序在启动插件时会启用
EnableDeviceMetadata和MetadataVersions选项。 有关详细信息,请查阅驱动程序的文档。
通过 ResourceClaim 访问设备元数据
当你使用直接引用的 ResourceClaim 来分配设备时, 设备元数据文件会出现在容器内的以下路径:
/var/run/kubernetes.io/dra-device-attributes/resourceclaims/<claimName>/<requestName>/<driverName>-metadata.json
-
查看以下示例清单:
apiVersion: resource.k8s.io/v1 kind: ResourceClaim metadata: name: gpu-claim spec: devices: requests: - name: gpu exactly: deviceClassName: gpu.example.com --- apiVersion: v1 kind: Pod metadata: name: gpu-metadata-reader spec: resourceClaims: - name: my-gpu resourceClaimName: gpu-claim containers: - name: workload image: ubuntu:24.04 resources: claims: - name: my-gpu request: gpu command: - sh - -c - | echo "=== DRA device metadata ===" find /var/run/kubernetes.io/dra-device-attributes -name '*-metadata.json' -print -exec cat {} \; sleep 3600 restartPolicy: Never此清单创建一个名为
gpu-claim的 ResourceClaim, 请求从gpu.example.comDeviceClass 获取设备,以及一个读取设备元数据的 Pod。
-
创建 ResourceClaim 和 Pod:
kubectl apply -f https://k8s.io/examples/dra/dra-device-metadata-pod.yaml
-
Pod 运行后,查看容器日志以查看元数据:
kubectl logs gpu-metadata-reader输出类似于:
=== DRA device metadata === /var/run/kubernetes.io/dra-device-attributes/resourceclaims/gpu-claim/gpu/gpu.example.com-metadata.json { "kind": "DeviceMetadata", "apiVersion": "metadata.resource.k8s.io/v1alpha1", ... }
-
要检查完整的元数据文件,请在容器中执行命令:
kubectl exec gpu-metadata-reader -- \ cat /var/run/kubernetes.io/dra-device-attributes/resourceclaims/gpu-claim/gpu/gpu.example.com-metadata.json输出是一个 JSON 对象,包含设备属性,例如型号、驱动版本和设备 UUID。 有关 JSON 结构的详细信息,请参阅 元数据模式。
通过 ResourceClaimTemplate 访问设备元数据
当你使用 ResourceClaimTemplate 时,Kubernetes 会为每个 Pod 生成一个 ResourceClaim。 由于生成的 claim 名称不可预测,元数据文件出现在使用 Pod 的 claim 引用名称的路径中:
/var/run/kubernetes.io/dra-device-attributes/resourceclaimtemplates/<podClaimName>/<requestName>/<driverName>-metadata.json
<podClaimName> 对应 Pod 的 spec.resourceClaims[] 条目中的 name 字段。
JSON 元数据还包括一个 podClaimName 字段,用于记录此映射。
-
查看以下示例清单:
apiVersion: resource.k8s.io/v1 kind: ResourceClaimTemplate metadata: name: gpu-claim-template spec: spec: devices: requests: - name: gpu exactly: deviceClassName: gpu.example.com --- apiVersion: v1 kind: Pod metadata: name: gpu-metadata-template-reader spec: resourceClaims: - name: my-gpu resourceClaimTemplateName: gpu-claim-template containers: - name: workload image: ubuntu:24.04 resources: claims: - name: my-gpu request: gpu command: - sh - -c - | echo "=== DRA device metadata (from template) ===" find /var/run/kubernetes.io/dra-device-attributes -name '*-metadata.json' -print -exec cat {} \; sleep 3600 restartPolicy: Never此清单创建一个 ResourceClaimTemplate 和一个 Pod。 每个 Pod 获得自己生成的 ResourceClaim。元数据路径使用 Pod 的 claim 引用名称
my-gpu。
-
创建 ResourceClaimTemplate 和 Pod:
kubectl apply -f https://k8s.io/examples/dra/dra-device-metadata-template-pod.yaml
-
Pod 运行后,查看元数据:
kubectl exec gpu-metadata-template-reader -- \ cat /var/run/kubernetes.io/dra-device-attributes/resourceclaimtemplates/my-gpu/gpu/gpu.example.com-metadata.json
在应用程序中读取元数据
Go 应用程序
k8s.io/dynamic-resource-allocation/devicemetadata 包提供了用于读取元数据文件的现成函数。
这些函数自动处理版本协商,解码元数据流并将其转换为内部类型,
使你的代码能够跨模式版本工作,而无需手动版本检查。
对于直接引用的 ResourceClaim:
import "k8s.io/dynamic-resource-allocation/devicemetadata"
dm, err := devicemetadata.ReadResourceClaimMetadata("gpu-claim", "gpu")
对于模板生成的 claim(使用 Pod 的 claim 引用名称):
dm, err := devicemetadata.ReadResourceClaimTemplateMetadata("my-gpu", "gpu")
如果你知道特定的驱动程序名称,可以读取单个驱动程序的元数据文件:
dm, err := devicemetadata.ReadResourceClaimMetadataWithDriverName("gpu.example.com", "gpu-claim", "gpu")
返回的 *metadata.DeviceMetadata 包含 claim 元数据、请求和每个设备的属性。
其他语言的应用程序可以直接读取 JSON 文件,并在解析之前检查 apiVersion 字段以确定模式版本。
清理
删除你创建的资源:
kubectl delete -f https://k8s.io/examples/dra/dra-device-metadata-pod.yaml
kubectl delete -f https://k8s.io/examples/dra/dra-device-metadata-template-pod.yaml
接下来
- 进一步了解 DRA 设备元数据
- 使用 DRA 为工作负载分配设备
- 有关设计的更多信息,请参阅 KEP-5304。