這是本節的多頁可打印視圖。 點擊此處打印.

返回此頁面的常規視圖.

教學

本節收錄了 Kubernetes 的教學。 教學示範了如何完成一個比單一任務更大的目標。 通常一個教學會有幾個小節,每個小節都有一系列的步驟。 在閱讀每個教學之前,建議您將詞彙表頁面加入書籤,以便日後參考。

基礎

設定

撰寫 Pod

無狀態應用程式

有狀態應用程式

服務

安全性

叢集管理

接下來

如果您想撰寫教學,請參閱 內容頁面類型 以取得有關教學頁面類型的資訊。

1 - Hello Minikube

本教學示範如何使用 minikube 在 Kubernetes 上執行一個範例應用程式。 教學提供了一個使用 NGINX 回應所有請求的容器映像檔。

學習目標

  • 將範例應用程式部署到 minikube。
  • 執行應用程式。
  • 查看應用程式日誌。

開始之前

本教學假設您已完成 minikube 的設定。 請參閱 minikube start 中的步驟 1 以取得安裝說明。

說明:

請只執行步驟 1:安裝中的指令,其餘部分將在本頁說明。

您還需要安裝 kubectl。 請參閱安裝工具以取得安裝說明。

建立 minikube 叢集

minikube start

確認 minikube 叢集狀態

確認 minikube 叢集的狀態,以確保所有元件都處於執行狀態。

minikube status

上述指令的輸出應顯示所有元件為 Running 或 Configured,如以下範例輸出所示:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

開啟 Dashboard

開啟 Kubernetes Dashboard,您可以透過以下兩種方式進行:

開啟一個新的終端機,並執行:

# Start a new terminal, and leave this running.
# 開啟新終端機,讓此指令持續執行。
minikube dashboard

接著,切換回您執行 minikube start 的終端機。

說明:

若您不想讓 minikube 自動開啟網頁瀏覽器,請使用 --url 旗標執行 dashboard 子指令。 minikube 會輸出一個 URL,您可以在偏好的瀏覽器中開啟。

開啟一個新的終端機,並執行:

# Start a new terminal, and leave this running.
# 開啟新終端機,讓此指令持續執行。
minikube dashboard --url

接著,您可以使用此 URL 並切換回您執行 minikube start 的終端機。

建立 Deployment

Kubernetes Pod 是由一個或多個容器組成的群組, 以便集中管理並共用網路資源。本教學中的 Pod 只有一個容器。Kubernetes Deployment 會檢查 Pod 的健康狀態, 並在 Pod 的容器終止時將其重新啟動。建議使用 Deployment 來管理 Pod 的建立和擴展。

  1. 使用 kubectl create 指令建立一個管理 Pod 的 Deployment。 Pod 會根據提供的 Docker 映像檔執行容器。

    # Run a test container image that includes a webserver
    kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.53 -- /agnhost netexec --http-port=8080
    
  1. 查看 Deployment:

    kubectl get deployments
    
    輸出類似如下:
    
    NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    hello-node   1/1     1            1           1m
    
    (Pod 可能需要一些時間才能就緒。若看到「0/1」,請稍候幾秒後再試。)
    
  1. 查看 Pod:

    kubectl get pods
    
    輸出類似如下:
    
    NAME                          READY     STATUS    RESTARTS   AGE
    hello-node-5f76cf6ccf-br9b5   1/1       Running   0          1m
    
  1. 查看叢集事件:

    kubectl get events
    
  1. 查看 kubectl 設定:

    kubectl config view
    
  1. 查看 Pod 中容器的應用程式日誌(請將 Pod 名稱替換為您從 kubectl get pods 取得的名稱)。

    說明:

    請將 kubectl logs 指令中的 hello-node-5f76cf6ccf-br9b5 替換為 kubectl get pods 輸出中的 Pod 名稱。

    kubectl logs hello-node-5f76cf6ccf-br9b5
    

    輸出類似如下:

    I0911 09:19:26.677397       1 log.go:195] Started HTTP server on port 8080
    I0911 09:19:26.677586       1 log.go:195] Started UDP server on port  8081
    

說明:

有關 kubectl 指令的更多資訊,請參閱 kubectl 概述

建立 Service

預設情況下,Pod 只能透過其在 Kubernetes 叢集內的內部 IP 位址存取。 若要讓 hello-node 容器可從 Kubernetes 虛擬網路外部存取, 您必須將 Pod 公開為 Kubernetes Service

警告:

agnhost 容器有一個 /shell 端點,這對於除錯很有用,但若暴露於公開網際網路上則相當危險。 請勿在對外公開的叢集或正式環境叢集上執行此指令。

  1. 使用 kubectl expose 指令將 Pod 對外公開:

    kubectl expose deployment hello-node --type=LoadBalancer --port=8080
    
    `--type=LoadBalancer` 旗標表示您希望將 Service 公開至叢集外部。
    

    測試映像檔中的應用程式碼只監聽 TCP 通訊埠 8080。若您使用 kubectl expose 公開不同的通訊埠,用戶端將無法連線到該通訊埠。

  1. 查看您建立的 Service:

    kubectl get services
    
    輸出類似如下:
    
    NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    hello-node   LoadBalancer   10.108.144.78   <pending>     8080:30369/TCP   21s
    kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP          23m
    
    在支援負載平衡器的雲端供應商上,系統會分配一個外部 IP 位址來存取 Service。
    

    在 minikube 上,LoadBalancer 類型讓您可透過 minikube service 指令存取 Service。

  1. 執行以下指令:

    minikube service hello-node
    
    這會開啟一個瀏覽器視窗,顯示您的應用程式及其回應。
    

啟用附加元件

minikube 工具內建了一組 附加元件,可在本機 Kubernetes 環境中啟用、停用,或在瀏覽器中開啟。

  1. 列出目前支援的附加元件:

    minikube addons list
    
    輸出類似如下:
    
    addon-manager: enabled
    dashboard: enabled
    default-storageclass: enabled
    efk: disabled
    freshpod: disabled
    gvisor: disabled
    helm-tiller: disabled
    ingress: disabled
    ingress-dns: disabled
    logviewer: disabled
    metrics-server: disabled
    nvidia-driver-installer: disabled
    nvidia-gpu-device-plugin: disabled
    registry: disabled
    registry-creds: disabled
    storage-provisioner: enabled
    storage-provisioner-gluster: disabled
    
  1. 啟用附加元件,例如 metrics-server

    minikube addons enable metrics-server
    
    輸出類似如下:
    
    The 'metrics-server' addon is enabled
    
  1. 查看安裝該附加元件後建立的 Pod 和 Service:

    kubectl get pod,svc -n kube-system
    
    輸出類似如下:
    
    NAME                                        READY     STATUS    RESTARTS   AGE
    pod/coredns-5644d7b6d9-mh9ll                1/1       Running   0          34m
    pod/coredns-5644d7b6d9-pqd2t                1/1       Running   0          34m
    pod/metrics-server-67fb648c5                1/1       Running   0          26s
    pod/etcd-minikube                           1/1       Running   0          34m
    pod/influxdb-grafana-b29w8                  2/2       Running   0          26s
    pod/kube-addon-manager-minikube             1/1       Running   0          34m
    pod/kube-apiserver-minikube                 1/1       Running   0          34m
    pod/kube-controller-manager-minikube        1/1       Running   0          34m
    pod/kube-proxy-rnlps                        1/1       Running   0          34m
    pod/kube-scheduler-minikube                 1/1       Running   0          34m
    pod/storage-provisioner                     1/1       Running   0          34m
    
    NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
    service/metrics-server         ClusterIP   10.96.241.45    <none>        80/TCP              26s
    service/kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP       34m
    service/monitoring-grafana     NodePort    10.99.24.54     <none>        80:30002/TCP        26s
    service/monitoring-influxdb    ClusterIP   10.111.169.94   <none>        8083/TCP,8086/TCP   26s
    
  1. 查看 metrics-server 的輸出:

    kubectl top pods
    
    輸出類似如下:
    
    NAME                         CPU(cores)   MEMORY(bytes)
    hello-node-ccf4b9788-4jn97   1m           6Mi
    
    若您看到以下訊息,請等待後再試:
    
    error: Metrics API not available
    
  1. 停用 metrics-server

    minikube addons disable metrics-server
    
    輸出類似如下:
    
    metrics-server was successfully disabled
    

清理

現在您可以清理在叢集中建立的資源:

kubectl delete service hello-node
kubectl delete deployment hello-node

停止 Minikube 叢集:

minikube stop

選擇性地刪除 Minikube 虛擬機器:

# Optional
minikube delete

若您想再次使用 minikube 來學習更多 Kubernetes 知識,則不需要刪除它。

結論

本頁說明了啟動並執行 minikube 叢集的基本步驟,您現在已準備好部署應用程式。

接下來

2 - 學習 Kubernetes 基礎

學習目標

本教學將帶您逐步了解 Kubernetes 叢集編排系統的基礎。 每個模組都包含 Kubernetes 主要功能和概念的背景介紹,以及可供您逐步操作的教學。

透過這些教學,您將學會:

  • 在叢集上部署容器化應用程式。
  • 擴展 Deployment。
  • 將容器化應用程式更新至新的軟體版本。
  • 為容器化應用程式除錯。

Kubernetes 能為您做什麼?

在現代 Web 服務中,使用者期望應用程式能夠全天候運作,而開發人員則期望每天能多次部署新版本。 容器化技術有助於封裝軟體以達成這些目標,讓應用程式能夠在不停機的情況下發佈與更新。 Kubernetes 可確保容器化應用程式依照您的需求在指定的位置與時機運行,並協助取得運作所需的資源與相關工具。 Kubernetes 是一個可用於正式環境的開源平台,結合了 Google 在容器編排方面累積的豐富經驗,以及來自社群的最佳實踐。

Kubernetes 基礎模組

接下來

3 - 配置

3.1 - 使用 ConfigMap 設定 Redis

本頁提供了一個實際範例,說明如何使用 ConfigMap 設定 Redis,並延伸自設定 Pod 以使用 ConfigMap 任務。

學習目標

  • 建立一個包含 Redis 設定值的 ConfigMap
  • 建立一個掛載並使用該 ConfigMap 的 Redis Pod
  • 驗證設定是否正確套用。

開始之前

您需要有一個 Kubernetes 叢集,且必須設定 kubectl 命令列工具使其能與叢集通訊。 建議在至少有兩個未擔任控制平面主機之節點的叢集上執行本教學。 如果您還沒有叢集,可以使用 Minikube 建立一個, 或使用以下其中一個 Kubernetes 練習環境:

若要確認版本,請輸入 kubectl version.

實際範例:使用 ConfigMap 設定 Redis

請按照以下步驟,使用 ConfigMap 中的資料設定 Redis 快取。

首先,建立一個設定區塊為空的 ConfigMap:

cat <<EOF >./example-redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: ""
EOF

套用上述建立的 ConfigMap,以及 Redis Pod 的設定檔:

kubectl apply -f example-redis-config.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/config/redis-pod.yaml

查看 Redis Pod 設定檔的內容,並注意以下事項:

  • spec.volumes[1] 建立了一個名為 config 的卷
  • spec.volumes[1].configMap.items[0] 下的 keypath,將 example-redis-config ConfigMap 中的 redis-config 鍵,以名為 redis.conf 的檔案形式呈現在 config 卷中
  • spec.containers[0].volumeMounts[1] 接著將 config 卷掛載至 /redis-master

結果會將 example-redis-config ConfigMap 中 data.redis-config 的資料,以 /redis-master/redis.conf 的形式於 Pod 內呈現。

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis:8.0.2
    command:
      - redis-server
      - "/redis-master/redis.conf"
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf

查看已建立的物件:

kubectl get pod/redis configmap/example-redis-config

您應該會看到以下輸出:

NAME        READY   STATUS    RESTARTS   AGE
pod/redis   1/1     Running   0          8s

NAME                             DATA   AGE
configmap/example-redis-config   1      14s

回想一下,我們先前將 example-redis-config ConfigMap 中的 redis-config 鍵留白:

kubectl describe configmap/example-redis-config

您應該會看到空的 redis-config 鍵:

Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:

使用 kubectl exec 進入 Pod,並執行 redis-cli 工具以確認目前的設定:

kubectl exec -it pod/redis -- redis-cli

確認 maxmemory

127.0.0.1:6379> CONFIG GET maxmemory

應顯示預設值 0:

1) "maxmemory"
2) "0"

同樣地,確認 maxmemory-policy

127.0.0.1:6379> CONFIG GET maxmemory-policy

也應回傳其預設值 noeviction

1) "maxmemory-policy"
2) "noeviction"

現在,讓我們在 example-redis-config ConfigMap 中新增一些設定值:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru    

套用更新後的 ConfigMap:

kubectl apply -f example-redis-config.yaml

確認 ConfigMap 已更新:

kubectl describe configmap/example-redis-config

您應該會看到剛才新增的設定值:

Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:
----
maxmemory 2mb
maxmemory-policy allkeys-lru

再次透過 kubectl exec 使用 redis-cli 確認 Redis Pod 是否已套用設定:

kubectl exec -it pod/redis -- redis-cli

確認 maxmemory

127.0.0.1:6379> CONFIG GET maxmemory

它仍為在預設值 0:

1) "maxmemory"
2) "0"

同樣地,maxmemory-policy 仍維持 noeviction 的預設設定:

127.0.0.1:6379> CONFIG GET maxmemory-policy

回傳:

1) "maxmemory-policy"
2) "noeviction"

設定值沒有改變是因為 Pod 需要重新啟動才能取得相關 ConfigMap 更新後的值。讓我們刪除 Pod 並重新建立:

kubectl delete pod redis
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/config/redis-pod.yaml

最後再次確認設定值:

kubectl exec -it pod/redis -- redis-cli

確認 maxmemory

127.0.0.1:6379> CONFIG GET maxmemory

現在應回傳更新後的值 2097152:

1) "maxmemory"
2) "2097152"

同樣地,maxmemory-policy 也已更新:

127.0.0.1:6379> CONFIG GET maxmemory-policy

現在已反映期望的值 allkeys-lru

1) "maxmemory-policy"
2) "allkeys-lru"

刪除已建立的資源以清理環境:

kubectl delete pod/redis configmap/example-redis-config

接下來

4 - 叢集管理

4.1 - 使用 DRA 安裝驅動程式並配置裝置

FEATURE STATE: 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 共享資訊,包括 DeviceClassesResourceSlicesResourceClaims,以及 Pod 規格本身的新欄位。

學習目標

  • 部署範例 DRA 驅動程式
  • 部署使用 DRA API 請求硬體資源的 Pod
  • 刪除具有資源請求的 Pod

開始之前

您的叢集應支援 RBAC。 您可以在使用其他授權機制的叢集上嘗試本教學, 但在這種情況下,您需要調整定義角色和權限的步驟。

您需要有一個 Kubernetes 叢集,且必須設定 kubectl 命令列工具使其能與叢集通訊。 建議在至少有兩個未擔任控制平面主機之節點的叢集上執行本教學。 如果您還沒有叢集,可以使用 Minikube 建立一個, 或使用以下其中一個 Kubernetes 練習環境:

本教學已在 Linux 節點上測試,但也可能適用於其他類型的節點。

您的 Kubernetes 伺服器版本必須不低於 v1.34.

若要確認版本,請輸入 kubectl version.

若您的叢集目前未執行 Kubernetes 1.35,請查閱您計劃使用的 Kubernetes 版本的文件。

探索叢集的初始狀態

您可以花些時間觀察啟用 DRA 的叢集初始狀態,這對尚未熟悉這些 API 的使用者特別有幫助。 若您為本教學設定了新叢集,且尚未安裝驅動程式也沒有待滿足的 Pod 請求, 這些指令的輸出將不會顯示任何資源。

  1. 取得 DeviceClasses 清單:

    kubectl get deviceclasses
    

    輸出類似如下:

    No resources found
    
  1. 取得 ResourceSlices 清單:

    kubectl get resourceslices
    

    輸出類似如下:

    No resources found
    
  1. 取得 ResourceClaimsResourceClaimTemplates 清單:

    kubectl get resourceclaims -A
    kubectl get resourceclaimtemplates -A
    

    輸出類似如下:

    No resources found
    No resources found
    

至此,您已確認 DRA 在叢集中已啟用且設定正確, 且目前尚無 DRA 驅動程式向 DRA API 公告任何資源。

安裝範例 DRA 驅動程式

DRA 驅動程式是在叢集每個節點上執行的第三方應用程式, 用於與該節點的硬體及 Kubernetes 內建 DRA 組件介接。 安裝程序取決於您選擇的驅動程式, 但通常會以 DaemonSet 的形式部署到叢集中的全部或部分節點 (使用選擇器或類似機制)。

請查閱您的驅動程式文件以取得特定安裝說明, 其中可能包含 Helm chart、一組設定檔或其他部署工具。

本教學使用 kubernetes-sigs/dra-example-driver 儲存庫中的範例驅動程式,示範如何安裝驅動程式。 此範例驅動程式會向 Kubernetes 宣告模擬 GPU,讓 Pod 可使用這些 GPU。

準備叢集以安裝驅動程式

為了簡化清理工作,請建立名為 dra-tutorial 的命名空間:

  1. 建立命名空間:

    kubectl create namespace dra-tutorial 
    

在正式環境中,您通常會使用驅動程式廠商或您所屬組織先前發佈或認證的映像檔, 且您的節點需要能夠存取託管驅動程式映像檔的映像檔儲存庫。 在本教學中,您將使用公開發佈的 dra-example-driver 映像檔, 模擬使用 DRA 驅動程式映像檔的情境。

  1. 在叢集的其中一個節點上執行以下指令,確認節點可以存取映像檔:

    docker pull registry.k8s.io/dra-example-driver/dra-example-driver:v0.2.0
    

部署 DRA 驅動程式組件

在本教學中,您將使用 kubectl 逐一安裝重要的範例資源驅動程式組件。

  1. 建立代表此 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
    
  1. 建立驅動程式存取此叢集 Kubernetes API 所需的 ServiceAccount、ClusterRole 和 ClusterRoleBinding:

    1. 建立 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-driver
      kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/serviceaccount.yaml
      
    2. 建立 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
      
    3. 建立 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.io
      kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/clusterrolebinding.yaml
      
  1. 為 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
    
  1. 將實際的 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/cdi
    kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/daemonset.yaml
    

    DaemonSet 設定了與底層容器裝置介面(CDI)目錄互動所需的卷掛載,並透過 kubelet/plugins 目錄向 kubelet 公開其 socket。

驗證 DRA 驅動程式安裝

  1. 取得所有工作節點上 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
    
  1. 每個節點本地 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。

請求資源並部署 Pod

若要使用 DRA 請求資源,您需要建立 ResourceClaims 或 ResourceClaimTemplates 來定義 Pod 所需的資源。 在範例驅動程式中,模擬 GPU 裝置會提供記憶體容量屬性。 本節說明如何使用 Common Expression Language 在 ResourceClaim 中表達您的需求、 在 Pod 規格中選取該 ResourceClaim,以及觀察資源分配情況。

本教學僅展示 DRA ResourceClaim 的一個基本範例。 請閱讀動態資源分配以深入了解 ResourceClaims。

建立 ResourceClaim

在本節中,您將建立一個 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

建立引用 ResourceClaim 的 Pod

以下是 Pod 設定檔,其 spec.resourceClaims.resourceClaimName 欄位引用了剛建立的 some-gpu ResourceClaim。 該請求的別名 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-gpu
kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/example/pod.yaml
  1. 確認 Pod 已部署:

    kubectl get pod pod0 -n dra-tutorial
    

    輸出類似如下:

    NAME   READY   STATUS    RESTARTS   AGE
    pod0   1/1     Running   0          9s
    

探索 DRA 狀態

建立 Pod 後,叢集會嘗試將該 Pod 排程到 Kubernetes 可以滿足 ResourceClaim 的節點。 在本教學中,DRA 驅動程式部署在所有節點上,並在所有節點上公告模擬 GPU, 所有節點公告的容量都足以滿足 Pod 的請求, 因此 Kubernetes 可以將此 Pod 排程到任何節點並分配該節點上的任何模擬 GPU。

當 Kubernetes 將模擬 GPU 分配給 Pod 時,範例驅動程式會為每個被分配到該裝置的容器新增環境變數, 用來顯示真實資源驅動程式原本會注入哪些 GPU,以及其設定方式。 您可以查看這些環境變數來了解系統如何處理該 Pod。

  1. 查看 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"
    
  1. 查看 ResourceClaim 物件的狀態:

    kubectl get resourceclaims -n dra-tutorial
    

    輸出類似如下:

    NAME       STATE                AGE
    some-gpu   allocated,reserved   34s
    

    在此輸出中,STATE 欄位顯示 ResourceClaim 已被分配且已保留。

  1. 查看 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

  1. 若要查看驅動程式如何處理裝置分配,請取得驅動程式 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

當具有資源請求的 Pod 被刪除時,DRA 驅動程式會釋放資源, 使其可用於未來的排程。 為了驗證此行為,請刪除您在前述步驟中建立的 Pod, 並觀察 ResourceClaim 和驅動程式的相應變更。

  1. 刪除 pod0 Pod:

    kubectl delete pod pod0 -n dra-tutorial
    

    輸出類似如下:

    pod "pod0" deleted
    

觀察 DRA 狀態

當 Pod 被刪除時,驅動程式會從 ResourceClaim 中釋放裝置, 並更新 Kubernetes API 中的 ResourceClaim 資源。 ResourceClaim 將保持 pending 狀態,直到它被新的 Pod 引用為止。

  1. 查看 some-gpu ResourceClaim 的狀態:

    kubectl get resourceclaims -n dra-tutorial
    

    輸出類似如下:

    NAME       STATE     AGE
    some-gpu   pending   76s
    
  1. 查看驅動程式日誌,確認驅動程式已處理此請求的裝置解除準備作業:

    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

接下來