Kubernetes v1.35 [stable](enabled by default)本教學示範如何在叢集中安裝動態資源分配(DRA)驅動程式,以及如何搭配 DRA API 將裝置配置給 Pod。本頁面適合叢集管理員閱讀。
動態資源分配(DRA)讓叢集能夠管理硬體資源的可用性與分配,以滿足 Pod 對硬體資源的需求與偏好。
為了支援此功能,Kubernetes 內建組件(如 Kubernetes 排程器、kubelet 和 kube-controller-manager)與裝置擁有者提供的第三方驅動程式(稱為 DRA 驅動程式)共同負責在 Pod 生命週期中公告、分配、準備、掛載、健康檢查、解除準備及清理資源。這些組件透過 resource.k8s.io API 群組中的一系列 DRA 專用 API 共享資訊,包括 DeviceClasses、ResourceSlices、ResourceClaims,以及 Pod 規格本身的新欄位。
您的叢集應支援 RBAC。您可以在使用其他授權機制的叢集上嘗試本教學,但在這種情況下,您需要調整定義角色和權限的步驟。
您需要有一個 Kubernetes 叢集,且必須設定 kubectl 命令列工具與叢集通訊。建議在至少有兩個不擔任控制平面主機的節點的叢集上執行本教學。如果您還沒有叢集,可以使用 Minikube 建立一個,或使用以下其中一個 Kubernetes 練習環境:
本教學已在 Linux 節點上測試,但也可能適用於其他類型的節點。
您的 Kubernetes 伺服器版本必須不低於 v1.34.若要確認版本,請輸入 kubectl version.
若您的叢集目前未執行 Kubernetes 1.35,請查閱您計劃使用的 Kubernetes 版本的文件。
您可以花些時間觀察啟用 DRA 的叢集初始狀態,對於還不熟悉這些 API 的使用者來說尤為有用。 若您為本教學設定了新叢集,且尚未安裝驅動程式也沒有待滿足的 Pod 請求,這些指令的輸出將不會顯示任何資源。
取得 DeviceClasses 清單:
kubectl get deviceclasses
輸出類似如下:
No resources found
取得 ResourceSlices 清單:
kubectl get resourceslices
輸出類似如下:
No resources found
取得 ResourceClaims 和 ResourceClaimTemplates 清單:
kubectl get resourceclaims -A
kubectl get resourceclaimtemplates -A
輸出類似如下:
No resources found
No resources found
至此,您已確認 DRA 在叢集中已啟用且設定正確,且目前尚無 DRA 驅動程式向 DRA API 公告任何資源。
DRA 驅動程式是在叢集每個節點上執行的第三方應用程式,用於與該節點的硬體及 Kubernetes 內建 DRA 組件互動。 安裝程序取決於您選擇的驅動程式,但通常會以 DaemonSet 的形式部署到叢集中的全部或部分節點(使用選擇器或類似機制)。
請查閱您的驅動程式文件以取得特定安裝說明,其中可能包含 Helm chart、一組設定檔或其他部署工具。
本教學使用可在 kubernetes-sigs/dra-example-driver 儲存庫中找到的範例驅動程式來示範驅動程式安裝。此範例驅動程式會向 Kubernetes 公告模擬 GPU,供您的 Pod 互動。
為了簡化清理工作,請建立名為 dra-tutorial 的命名空間:
建立命名空間:
kubectl create namespace dra-tutorial
在正式環境中,您通常會使用驅動程式廠商或您所屬組織先前發佈或認證的映像檔, 且您的節點需要能夠存取託管驅動程式映像檔的映像檔儲存庫。 在本教學中,您將使用公開發佈的 dra-example-driver 映像檔來模擬存取 DRA 驅動程式映像檔。
在叢集的其中一個節點上執行以下指令,確認節點可以存取映像檔:
docker pull registry.k8s.io/dra-example-driver/dra-example-driver:v0.2.0
在本教學中,您將使用 kubectl 逐一安裝重要的範例資源驅動程式組件。
建立代表此 DRA 驅動程式所支援裝置類型的 DeviceClass:
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
name: gpu.example.com
spec:
selectors:
- cel:
expression: "device.driver == 'gpu.example.com'"kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/deviceclass.yaml
建立驅動程式與此叢集 Kubernetes API 互動所需的 ServiceAccount、ClusterRole 和 ClusterRoleBinding:
建立 ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: dra-example-driver-service-account
namespace: dra-tutorial
labels:
app.kubernetes.io/name: dra-example-driver
app.kubernetes.io/instance: dra-example-driverkubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/serviceaccount.yaml
建立 ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dra-example-driver-role
rules:
- apiGroups: ["resource.k8s.io"]
resources: ["resourceclaims"]
verbs: ["get"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get"]
- apiGroups: ["resource.k8s.io"]
resources: ["resourceslices"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/clusterrole.yaml
建立 ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dra-example-driver-role-binding
subjects:
- kind: ServiceAccount
name: dra-example-driver-service-account
namespace: dra-tutorial
roleRef:
kind: ClusterRole
name: dra-example-driver-role
apiGroup: rbac.authorization.k8s.iokubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/clusterrolebinding.yaml
為 DRA 驅動程式建立 PriorityClass。 PriorityClass 可防止 DRA 驅動程式組件被搶佔,該組件負責處理具有資源請求的 Pod 的重要生命週期操作。 深入了解 Pod 優先權與搶佔。
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: dra-driver-high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for DRA driver pods only."kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/priorityclass.yaml
將實際的 DRA 驅動程式部署為 DaemonSet,並設定為使用上述已配置的權限執行範例驅動程式二進位檔。 DaemonSet 具有您在前述步驟中授予 ServiceAccount 的權限。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: dra-example-driver-kubeletplugin
namespace: dra-tutorial
labels:
app.kubernetes.io/name: dra-example-driver
spec:
selector:
matchLabels:
app.kubernetes.io/name: dra-example-driver
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: dra-example-driver
spec:
priorityClassName: dra-driver-high-priority
serviceAccountName: dra-example-driver-service-account
securityContext:
{}
containers:
- name: plugin
securityContext:
privileged: true
image: registry.k8s.io/dra-example-driver/dra-example-driver:v0.2.0
imagePullPolicy: IfNotPresent
command: ["dra-example-kubeletplugin"]
resources:
{}
# Production drivers should always implement a liveness probe
# For the tutorial we simply omit it
# livenessProbe:
# grpc:
# port: 51515
# service: liveness
# failureThreshold: 3
# periodSeconds: 10
env:
- name: CDI_ROOT
value: /var/run/cdi
- name: KUBELET_REGISTRAR_DIRECTORY_PATH
value: "/var/lib/kubelet/plugins_registry"
- name: KUBELET_PLUGINS_DIRECTORY_PATH
value: "/var/lib/kubelet/plugins"
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
# Simulated number of devices the example driver will pretend to have.
- name: NUM_DEVICES
value: "9"
- name: HEALTHCHECK_PORT
value: "51515"
volumeMounts:
- name: plugins-registry
mountPath: "/var/lib/kubelet/plugins_registry"
- name: plugins
mountPath: "/var/lib/kubelet/plugins"
- name: cdi
mountPath: /var/run/cdi
volumes:
- name: plugins-registry
hostPath:
path: "/var/lib/kubelet/plugins_registry"
- name: plugins
hostPath:
path: "/var/lib/kubelet/plugins"
- name: cdi
hostPath:
path: /var/run/cdikubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/daemonset.yaml
DaemonSet 設定了與底層容器裝置介面(CDI)目錄互動所需的卷掛載,並透過 kubelet/plugins 目錄向 kubelet 公開其 socket。
取得所有工作節點上 DRA 驅動程式 DaemonSet 的 Pod 清單:
kubectl get pod -l app.kubernetes.io/name=dra-example-driver -n dra-tutorial
輸出類似如下:
NAME READY STATUS RESTARTS AGE
dra-example-driver-kubeletplugin-4sk2x 1/1 Running 0 13s
dra-example-driver-kubeletplugin-cttr2 1/1 Running 0 13s
每個節點本地 DRA 驅動程式的初始職責是透過將其中繼資料發布到 ResourceSlices API, 向叢集更新該節點上 Pod 可使用的裝置資訊。您可以查看該 API,確認每個安裝了驅動程式的節點都在公告其所代表的裝置類別。
查看可用的 ResourceSlices:
kubectl get resourceslices
輸出類似如下:
NAME NODE DRIVER POOL AGE
kind-worker-gpu.example.com-k69gd kind-worker gpu.example.com kind-worker 19s
kind-worker2-gpu.example.com-qdgpn kind-worker2 gpu.example.com kind-worker2 19s
至此,您已成功安裝範例 DRA 驅動程式並確認其初始設定。您現在可以使用 DRA 來排程 Pod。
若要使用 DRA 請求資源,您需要建立 ResourceClaims 或 ResourceClaimTemplates 來定義 Pod 所需的資源。 在範例驅動程式中,模擬 GPU 裝置會公開記憶體容量屬性。 本節說明如何使用 Common Expression Language 在 ResourceClaim 中表達您的需求、 在 Pod 規格中選取該 ResourceClaim,以及觀察資源分配情況。
本教學僅展示 DRA ResourceClaim 的一個基本範例。請閱讀動態資源分配以深入了解 ResourceClaims。
在本節中,您將建立一個 ResourceClaim 並在 Pod 中參照它。
無論請求內容為何,deviceClassName 都是必填欄位,用於將請求範圍縮小到特定裝置類別。
請求本身可以包含 Common Expression Language 表達式,
用來參照驅動程式針對該裝置類別所公告的屬性。
在本範例中,您將建立一個 ResourceClaim,用於請求任何公告超過 10Gi 記憶體容量的 GPU。
範例驅動程式公開容量的屬性格式為 device.capacity['gpu.example.com'].memory。
另請注意,此請求的名稱設定為 some-gpu。
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: some-gpu
namespace: dra-tutorial
spec:
devices:
requests:
- name: some-gpu
exactly:
deviceClassName: gpu.example.com
selectors:
- cel:
expression: "device.capacity['gpu.example.com'].memory.compareTo(quantity('10Gi')) >= 0"kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/example/resourceclaim.yaml
以下是透過 spec.resourceClaims.resourceClaimName 欄位參照 some-gpu ResourceClaim 的 Pod 設定檔。
該請求的別名 gpu 隨後會在 spec.containers.resources.claims.name 欄位中使用,
以將請求分配給 Pod 的底層容器。
apiVersion: v1
kind: Pod
metadata:
name: pod0
namespace: dra-tutorial
labels:
app: pod
spec:
containers:
- name: ctr0
image: ubuntu:24.04
command: ["bash", "-c"]
args: ["export; trap 'exit 0' TERM; sleep 9999 & wait"]
resources:
claims:
- name: gpu
resourceClaims:
- name: gpu
resourceClaimName: some-gpukubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/example/pod.yaml
確認 Pod 已部署:
kubectl get pod pod0 -n dra-tutorial
輸出類似如下:
NAME READY STATUS RESTARTS AGE
pod0 1/1 Running 0 9s
建立 Pod 後,叢集會嘗試將該 Pod 排程到 Kubernetes 可以滿足 ResourceClaim 的節點。 在本教學中,DRA 驅動程式部署在所有節點上,並在所有節點上公告模擬 GPU, 所有節點公告的容量都足以滿足 Pod 的請求,因此 Kubernetes 可以將此 Pod 排程到任何節點, 並分配該節點上的任何模擬 GPU。
當 Kubernetes 將模擬 GPU 分配給 Pod 時,範例驅動程式會為每個被分配到該裝置的容器新增環境變數, 以指示真實資源驅動程式_本應_注入哪些 GPU 及其設定方式, 您可以查看這些環境變數來了解系統如何處理這些 Pod。
查看 Pod 日誌,其中記錄了已分配的模擬 GPU 名稱:
kubectl logs pod0 -c ctr0 -n dra-tutorial | grep -E "GPU_DEVICE_[0-9]+=" | grep -v "RESOURCE_CLAIM"
輸出類似如下:
declare -x GPU_DEVICE_0="gpu-0"
查看 ResourceClaim 物件的狀態:
kubectl get resourceclaims -n dra-tutorial
輸出類似如下:
NAME STATE AGE
some-gpu allocated,reserved 34s
在此輸出中,STATE 欄位顯示 ResourceClaim 已被分配且已保留。
查看 some-gpu ResourceClaim 的詳細資訊。ResourceClaim 的 status 區段包含已分配裝置及其保留對象 Pod 的資訊:
kubectl get resourceclaim some-gpu -n dra-tutorial -o yaml
輸出類似如下:
1apiVersion: resource.k8s.io/v1
2kind: ResourceClaim
3metadata:
4 creationTimestamp: "2025-08-20T18:17:31Z"
5 finalizers:
6 - resource.kubernetes.io/delete-protection
7 name: some-gpu
8 namespace: dra-tutorial
9 resourceVersion: "2326"
10 uid: d3e48dbf-40da-47c3-a7b9-f7d54d1051c3
11spec:
12 devices:
13 requests:
14 - exactly:
15 allocationMode: ExactCount
16 count: 1
17 deviceClassName: gpu.example.com
18 selectors:
19 - cel:
20 expression: device.capacity['gpu.example.com'].memory.compareTo(quantity('10Gi'))
21 >= 0
22 name: some-gpu
23status:
24 allocation:
25 devices:
26 results:
27 - device: gpu-0
28 driver: gpu.example.com
29 pool: kind-worker
30 request: some-gpu
31 nodeSelector:
32 nodeSelectorTerms:
33 - matchFields:
34 - key: metadata.name
35 operator: In
36 values:
37 - kind-worker
38 reservedFor:
39 - name: pod0
40 resource: pods
41 uid: c4dadf20-392a-474d-a47b-ab82080c8bd7若要查看驅動程式如何處理裝置分配,請取得驅動程式 DaemonSet Pod 的日誌:
kubectl logs -l app.kubernetes.io/name=dra-example-driver -n dra-tutorial
輸出類似如下:
I0820 18:17:44.131324 1 driver.go:106] PrepareResourceClaims is called: number of claims: 1
I0820 18:17:44.135056 1 driver.go:133] Returning newly prepared devices for claim 'd3e48dbf-40da-47c3-a7b9-f7d54d1051c3': [{[some-gpu] kind-worker gpu-0 [k8s.gpu.example.com/gpu=common k8s.gpu.example.com/gpu=d3e48dbf-40da-47c3-a7b9-f7d54d1051c3-gpu-0]}]
您現在已成功部署了一個使用 DRA 請求裝置的 Pod,確認該 Pod 已被排程到適當的節點, 並確認相關的 DRA API 物件已反映最新的分配狀態。
當具有資源請求的 Pod 被刪除時,DRA 驅動程式會釋放資源,使其可用於未來的排程。 為了驗證此行為,請刪除您在前述步驟中建立的 Pod,並觀察 ResourceClaim 和驅動程式的相應變更。
刪除 pod0 Pod:
kubectl delete pod pod0 -n dra-tutorial
輸出類似如下:
pod "pod0" deleted
當 Pod 被刪除時,驅動程式會從 ResourceClaim 中釋放裝置,並更新 Kubernetes API 中的 ResourceClaim 資源。
ResourceClaim 將保持 pending 狀態,直到它被新的 Pod 參照為止。
查看 some-gpu ResourceClaim 的狀態:
kubectl get resourceclaims -n dra-tutorial
輸出類似如下:
NAME STATE AGE
some-gpu pending 76s
查看驅動程式日誌,確認驅動程式已解除此請求的裝置配置:
kubectl logs -l app.kubernetes.io/name=dra-example-driver -n dra-tutorial
輸出類似如下:
I0820 18:22:15.629376 1 driver.go:138] UnprepareResourceClaims is called: number of claims: 1
您現在已刪除了具有資源請求的 Pod,並觀察到驅動程式解除了底層硬體資源的配置, 同時更新 DRA API,讓該資源再次可供排程使用。
若要清理本教學中建立的資源,請執行以下步驟:
kubectl delete namespace dra-tutorial
kubectl delete deviceclass gpu.example.com
kubectl delete clusterrole dra-example-driver-role
kubectl delete clusterrolebinding dra-example-driver-role-binding
kubectl delete priorityclass dra-driver-high-priority