動態資源分配

功能狀態: Kubernetes v1.32 [beta] (預設停用:false)

動態資源分配是一個 API,用於請求和共用 Pod 和 Pod 內容器之間的資源。它是通用資源持久性磁碟區 API 的一般化。通常,這些資源是 GPU 等裝置。

第三方資源驅動程式負責追蹤和準備資源,而資源的分配由 Kubernetes 透過結構化參數(在 Kubernetes 1.30 中引入)處理。不同種類的資源支援任意參數,用於定義需求和初始化。

Kubernetes v1.26 到 1.31 包含經典 DRA 的 (alpha) 實作,現已不再支援。本文件適用於 Kubernetes v1.32,說明 Kubernetes 中動態資源分配的目前方法。

開始之前

Kubernetes v1.32 包含動態資源分配的叢集層級 API 支援,但它需要明確啟用。您也必須為特定資源安裝資源驅動程式,這些資源旨在使用此 API 進行管理。如果您未執行 Kubernetes v1.32,請查看該 Kubernetes 版本的說明文件。

API

resource.k8s.io/v1beta1 API 群組提供這些類型

ResourceClaim
描述叢集中資源存取的請求,供工作負載使用。例如,如果工作負載需要具有特定屬性的加速器裝置,這就是表達該請求的方式。狀態段落追蹤此宣告是否已滿足以及已分配哪些特定資源。
ResourceClaimTemplate
定義用於建立 ResourceClaim 的規範和一些中繼資料。由使用者在部署工作負載時建立。然後,每個 Pod 的 ResourceClaim 由 Kubernetes 自動建立和移除。
DeviceClass
包含某些裝置的預先定義的選擇標準及其組態。DeviceClass 由叢集管理員在安裝資源驅動程式時建立。ResourceClaim 中分配裝置的每個請求都必須參考正好一個 DeviceClass。
ResourceSlice
DRA 驅動程式用於發佈有關叢集中可用資源的資訊。

選擇裝置的所有參數都在 ResourceClaim 和 DeviceClass 中使用樹狀結構內類型定義。組態參數可以嵌入在那裡。哪些組態參數有效取決於 DRA 驅動程式——Kubernetes 僅傳遞它們而不進行解譯。

core/v1 PodSpecresourceClaims 欄位中定義 Pod 所需的 ResourceClaim。該清單中的條目參考 ResourceClaim 或 ResourceClaimTemplate。當參考 ResourceClaim 時,使用此 PodSpec 的所有 Pod(例如,在部署或 StatefulSet 內)共用相同的 ResourceClaim 執行個體。當參考 ResourceClaimTemplate 時,每個 Pod 都會取得自己的執行個體。

容器資源的 resources.claims 清單定義容器是否可以存取這些資源執行個體,這使得在一個或多個容器之間共用資源成為可能。

以下是虛構資源驅動程式的範例。將為此 Pod 建立兩個 ResourceClaim 物件,並且每個容器都可以存取其中一個。

apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
name: resource.example.com
spec:
  selectors:
  - cel:
      expression: device.driver == "resource-driver.example.com"
---
apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        deviceClassName: resource.example.com
        selectors:
        - cel:
           expression: |-
              device.attributes["resource-driver.example.com"].color == "black" &&
              device.attributes["resource-driver.example.com"].size == "large"              
–--
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-cats
spec:
  containers:
  - name: container0
    image: ubuntu:20.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-0
  - name: container1
    image: ubuntu:20.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-1
  resourceClaims:
  - name: cat-0
    resourceClaimTemplateName: large-black-cat-claim-template
  - name: cat-1
    resourceClaimTemplateName: large-black-cat-claim-template

排程

排程器負責在 Pod 需要資源時將資源分配給 ResourceClaim。它透過從 ResourceSlice 物件擷取可用資源的完整清單、追蹤哪些資源已分配給現有的 ResourceClaim,然後從剩餘的資源中進行選擇來實現此目的。

目前唯一支援的資源種類是裝置。裝置執行個體具有名稱以及多個屬性和容量。裝置透過 CEL 表達式進行選擇,這些表達式檢查這些屬性和容量。此外,所選裝置的集合也可以限制為滿足某些約束的集合。

所選資源記錄在 ResourceClaim 狀態中,以及任何供應商特定的組態,因此當 Pod 即將在節點上啟動時,節點上的資源驅動程式擁有準備資源所需的所有資訊。

透過使用結構化參數,排程器能夠在不與任何 DRA 資源驅動程式通訊的情況下做出決策。它還可以透過將 ResourceClaim 分配的資訊保留在記憶體中,並在後台將此資訊寫入 ResourceClaim 物件,同時並行地將 Pod 繫結到節點,從而快速排程多個 Pod。

監控資源

kubelet 提供 gRPC 服務,以啟用執行中 Pod 的動態資源探索。有關 gRPC 端點的更多資訊,請參閱資源分配報告

預先排程的 Pod

當您 - 或另一個 API 用戶端 - 建立已設定 spec.nodeName 的 Pod 時,會繞過排程器。如果該 Pod 需要的某些 ResourceClaim 尚不存在、未分配或未為 Pod 保留,則 kubelet 將無法執行 Pod 並定期重新檢查,因為這些需求稍後可能仍會得到滿足。

這種情況也可能發生在排程器中未啟用動態資源分配支援時(版本偏差、組態、功能閘道等),Pod 卻被排程的情況。kube-controller-manager 會偵測到此情況,並嘗試透過保留所需的 ResourceClaims 來使 Pod 成為可執行狀態。但是,這僅在這些 ResourceClaims 已由排程器為其他 Pod 分配時才有效。

最好避免繞過排程器,因為分配到節點的 Pod 會封鎖正常的資源(RAM、CPU),而當 Pod 停滯時,這些資源將無法用於其他 Pod。為了讓 Pod 在特定節點上執行,同時仍通過正常的排程流程,請建立具有節點選取器的 Pod,該選取器與所需的節點完全匹配

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-cats
spec:
  nodeSelector:
    kubernetes.io/hostname: name-of-the-intended-node
  ...

您也可以在允許請求階段修改傳入的 Pod,以取消設定 .spec.nodeName 欄位並改為使用節點選取器。

管理員存取權限

功能狀態: Kubernetes v1.32 [alpha] (預設為停用:false)

您可以在 ResourceClaim 或 ResourceClaimTemplate 中將請求標記為具有特權功能。具有管理員存取權限的請求授予對正在使用中的裝置的存取權,並且在容器中提供裝置時可能會啟用其他權限

apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        deviceClassName: resource.example.com
        adminAccess: true

如果停用此功能,則在建立此類 ResourceClaim 時,將自動移除 adminAccess 欄位。

管理員存取權限是一種特權模式,不應在多租戶叢集中提供給一般使用者。叢集管理員可以透過安裝類似於以下範例的驗證准入策略來限制此功能的使用。叢集管理員至少需要調整名稱並替換 "dra.example.com"。

# Permission to use admin access is granted only in namespaces which have the
# "admin-access.dra.example.com" label. Other ways of making that decision are
# also possible.

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: resourceclaim-policy.dra.example.com
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["resource.k8s.io"]
      apiVersions: ["v1alpha3", "v1beta1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["resourceclaims"]
  validations:
    - expression: '! object.spec.devices.requests.exists(e, has(e.adminAccess) && e.adminAccess)'
      reason: Forbidden
      messageExpression: '"admin access to devices not enabled"'
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: resourceclaim-binding.dra.example.com
spec:
  policyName:  resourceclaim-policy.dra.example.com
  validationActions: [Deny]
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: admin-access.dra.example.com
        operator: DoesNotExist
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: resourceclaimtemplate-policy.dra.example.com
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["resource.k8s.io"]
      apiVersions: ["v1alpha3", "v1beta1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["resourceclaimtemplates"]
  validations:
    - expression: '! object.spec.spec.devices.requests.exists(e, has(e.adminAccess) && e.adminAccess)'
      reason: Forbidden
      messageExpression: '"admin access to devices not enabled"'
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: resourceclaimtemplate-binding.dra.example.com
spec:
  policyName:  resourceclaimtemplate-policy.dra.example.com
  validationActions: [Deny]
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: admin-access.dra.example.com
        operator: DoesNotExist

ResourceClaim 裝置狀態

功能狀態: Kubernetes v1.32 [alpha] (預設為停用:false)

驅動程式可以報告資源宣告中每個已分配裝置的驅動程式特定裝置狀態資料。例如,分配給網路介面裝置的 IP 可以報告在 ResourceClaim 狀態中。

由於驅動程式設定了狀態,因此資訊的準確性取決於這些 DRA 驅動程式的實作。因此,裝置的報告狀態可能無法始終反映裝置狀態的即時變化。

當停用此功能時,該欄位會在儲存 ResourceClaim 時自動清除。

當 DRA 驅動程式可以更新現有的 ResourceClaim,並且已設定 status.devices 欄位時,才支援 ResourceClaim 裝置狀態。

啟用動態資源分配

動態資源分配是一項Beta 功能,預設為關閉,僅在啟用 DynamicResourceAllocation 功能閘道resource.k8s.io/v1beta1 API 群組 時才會啟用。有關詳細資訊,請參閱 --feature-gates--runtime-config kube-apiserver 參數。kube-scheduler、kube-controller-manager 和 kubelet 也需要功能閘道。

當資源驅動程式報告裝置狀態時,除了 DynamicResourceAllocation 之外,還必須啟用 DRAResourceClaimDeviceStatus 功能閘道。

快速檢查 Kubernetes 叢集是否支援此功能的方法是使用以下命令列出 DeviceClass 物件

kubectl get deviceclasses

如果您的叢集支援動態資源分配,則回應會是 DeviceClass 物件的清單,或者

No resources found

如果不支援,則會改為印出此錯誤訊息

error: the server doesn't have a resource type "deviceclasses"

如果已啟用功能閘道並使用 v1 組態 API,則 kube-scheduler 的預設組態會啟用 "DynamicResources" 外掛程式。自訂組態可能必須修改才能包含它。

除了在叢集中啟用此功能外,還必須安裝資源驅動程式。請參閱驅動程式的文件以取得詳細資訊。

啟用管理員存取權限

管理員存取權限 是一項Alpha 功能,僅在 kube-apiserver 和 kube-scheduler 中啟用 DRAAdminAccess 功能閘道 時才會啟用。

啟用裝置狀態

ResourceClaim 裝置狀態 是一項Alpha 功能,僅在 kube-apiserver 中啟用 DRAResourceClaimDeviceStatus 功能閘道 時才會啟用。

下一步

上次修改時間為 2024 年 11 月 19 日上午 11:15 PST:DRA:包含 v1beta1 API 參考 (26b5da0885)