動態資源分配

特性狀態: Kubernetes v1.34 [穩定] (預設啟用:true)

本頁面描述了 Kubernetes 中的**動態資源分配 (DRA)**。

關於 DRA

DRA 是 Kubernetes 的一項功能,它允許你在 Pod 之間請求和共享資源。這些資源通常是附加的裝置,例如硬體加速器。

藉助 DRA,裝置驅動程式和叢集管理員可以定義可供工作負載**宣告**的裝置**類**。Kubernetes 將匹配的裝置分配給特定的宣告,並將相應的 Pod 放置在可以訪問所分配裝置的節點上。

使用 DRA 分配資源與動態卷供應的體驗類似,在動態卷供應中,你使用 PersistentVolumeClaims 從儲存類中宣告儲存容量,並在 Pod 中請求所宣告的容量。

DRA 的優勢

DRA 提供了一種靈活的方式來對叢集中的裝置進行分類、請求和使用。使用 DRA 具有以下優勢:

  • **靈活的裝置過濾**:使用通用表示式語言 (CEL) 對特定裝置屬性執行細粒度過濾。
  • **裝置共享**:透過引用相應的資源宣告,與多個容器或 Pod 共享同一資源。
  • **集中式裝置分類**:裝置驅動程式和叢集管理員可以使用裝置類,為應用操作員提供針對各種用例最佳化的硬體類別。例如,你可以為通用工作負載建立成本最佳化裝置類,為關鍵作業建立高效能裝置類。
  • **簡化的 Pod 請求**:藉助 DRA,應用操作員無需在 Pod 資源請求中指定裝置數量。相反,Pod 引用資源宣告,該宣告中的裝置配置將應用於 Pod。

裝置外掛相比,這些優勢顯著改善了裝置分配工作流程。裝置外掛需要按容器進行裝置請求,不支援裝置共享,也不支援基於表示式的裝置過濾。

DRA 使用者型別

使用 DRA 分配裝置的工作流程涉及以下使用者型別:

  • **裝置所有者**:負責裝置。裝置所有者可能是商業供應商、叢集操作員或其他實體。要使用 DRA,裝置必須具有 DRA 相容的驅動程式,這些驅動程式執行以下操作:

    • 建立 ResourceSlice,向 Kubernetes 提供節點和資源資訊。
    • 當叢集中的資源容量發生變化時更新 ResourceSlice。
    • (可選)建立 DeviceClass,工作負載操作員可以使用它來宣告裝置。
  • **叢集管理員**:負責配置叢集和節點、連線裝置、安裝驅動程式以及類似任務。要使用 DRA,叢集管理員執行以下操作:

    • 將裝置連線到節點。
    • 安裝支援 DRA 的裝置驅動程式。
    • (可選)建立 DeviceClass,工作負載操作員可以使用它來宣告裝置。
  • **工作負載操作員**:負責在叢集中部署和管理工作負載。要使用 DRA 將裝置分配給 Pod,工作負載操作員執行以下操作:

    • 建立 ResourceClaim 或 ResourceClaimTemplate,以請求 DeviceClass 中的特定配置。
    • 部署使用特定 ResourceClaim 或 ResourceClaimTemplate 的工作負載。

DRA 術語

DRA 使用以下 Kubernetes API 種類來提供核心分配功能。所有這些 API 種類都包含在 `resource.k8s.io/v1` API 組中。

DeviceClass
定義可宣告的裝置類別以及如何在宣告中選擇特定裝置屬性。DeviceClass 引數可以匹配 ResourceSlice 中零個或多個裝置。要從 DeviceClass 宣告裝置,ResourceClaim 會選擇特定的裝置屬性。
ResourceClaim
描述了對叢集中附加資源(如裝置)的訪問請求。ResourceClaim 為 Pod 提供了對特定資源的訪問許可權。ResourceClaim 可以由工作負載操作員建立,也可以由 Kubernetes 根據 ResourceClaimTemplate 生成。
ResourceClaimTemplate
定義了一個模板,Kubernetes 使用它為工作負載建立每個 Pod 的 ResourceClaim。ResourceClaimTemplate 為 Pod 提供了對獨立、配置相似的資源的訪問許可權。Kubernetes 從模板生成的每個 ResourceClaim 都繫結到特定的 Pod。當 Pod 終止時,Kubernetes 會刪除相應的 ResourceClaim。
ResourceSlice
表示連線到節點的一個或多個資源,例如裝置。驅動程式在叢集中建立和管理 ResourceSlice。當 ResourceClaim 在 Pod 中建立和使用時,Kubernetes 使用 ResourceSlice 查詢可以訪問所宣告資源的節點。Kubernetes 將資源分配給 ResourceClaim,並將 Pod 排程到可以訪問資源的節點上。

DeviceClass

DeviceClass 允許叢集管理員或裝置驅動程式定義叢集中的裝置類別。DeviceClass 告訴操作員他們可以請求哪些裝置以及如何請求這些裝置。你可以使用通用表示式語言 (CEL) 根據特定屬性選擇裝置。引用 DeviceClass 的 ResourceClaim 可以請求 DeviceClass 內的特定配置。

要建立 DeviceClass,請參閱在叢集中設定 DRA

ResourceClaim 和 ResourceClaimTemplate

ResourceClaim 定義了工作負載所需的資源。每個 ResourceClaim 都有引用 DeviceClass 並從該 DeviceClass 中選擇裝置的**請求**。ResourceClaim 還可以使用**選擇器**來篩選滿足特定要求的裝置,並可以使用**約束**來限制可以滿足請求的裝置。ResourceClaim 可以由工作負載操作員建立,也可以由 Kubernetes 根據 ResourceClaimTemplate 生成。ResourceClaimTemplate 定義了一個模板,Kubernetes 可以使用它為 Pod 自動生成 ResourceClaim。

ResourceClaim 和 ResourceClaimTemplate 的用例

你使用的方法取決於你的要求,具體如下:

  • **ResourceClaim**:你希望多個 Pod 共享對特定裝置的訪問。你手動管理你建立的 ResourceClaim 的生命週期。
  • **ResourceClaimTemplate**:你希望 Pod 獨立訪問單獨的、配置相似的裝置。Kubernetes 根據 ResourceClaimTemplate 中的規範生成 ResourceClaim。每個生成的 ResourceClaim 的生命週期都繫結到相應 Pod 的生命週期。

當你定義工作負載時,你可以使用通用表示式語言 (CEL)來過濾特定裝置屬性或容量。可用於過濾的引數取決於裝置和驅動程式。

如果你在 Pod 中直接引用了特定的 ResourceClaim,那麼該 ResourceClaim 必須已經存在於與 Pod 相同的名稱空間中。如果 ResourceClaim 不存在於該名稱空間中,則 Pod 將無法排程。此行為類似於 PersistentVolumeClaim 必須存在於引用它的 Pod 所在的相同名稱空間中。

你可以在 Pod 中引用一個自動生成的 ResourceClaim,但不建議這樣做,因為自動生成的 ResourceClaim 繫結到觸發生成的 Pod 的生命週期。

要了解如何使用這些方法之一宣告資源,請參閱使用 DRA 為工作負載分配裝置

優先順序列表

特性狀態: Kubernetes v1.34 [beta] (預設啟用:true)

你可以為 ResourceClaim 或 ResourceClaimTemplate 中的請求提供一個優先順序排序的子請求列表。排程器將選擇第一個可分配的子請求。這允許使用者指定替代裝置,如果首選裝置不可用,工作負載可以使用這些替代裝置。

在下面的示例中,ResourceClaimTemplate 請求了一個顏色為黑色、尺寸為大型的裝置。如果具有這些屬性的裝置不可用,則 Pod 無法排程。透過優先順序列表功能,可以指定第二個替代選項,該選項請求兩個顏色為白色、尺寸為小型裝置。如果大型黑色裝置可用,則將分配它。如果不可用,但有兩個小型白色裝置可用,則 Pod 仍然可以執行。

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: prioritized-list-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        firstAvailable:
        - name: large-black
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "black" &&
                device.attributes["resource-driver.example.com"].size == "large"                
        - name: small-white
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "white" &&
                device.attributes["resource-driver.example.com"].size == "small"                
          count: 2

此決定是針對每個 Pod 做出的,因此,如果 Pod 是 ReplicaSet 或類似分組的成員,你不能依賴組的所有成員都選擇相同的子請求。你的工作負載必須能夠適應這種情況。

優先順序列表是一個**Beta 特性**,在 kube-apiserver 和 kube-scheduler 中,透過 `DRAPrioritizedList` Feature Gate 預設啟用。

ResourceSlice

每個 ResourceSlice 代表池中的一個或多個裝置。該池由裝置驅動程式管理,裝置驅動程式建立和管理 ResourceSlice。池中的資源可以由單個 ResourceSlice 表示,也可以跨多個 ResourceSlice。

ResourceSlice 為裝置使用者和排程器提供有用的資訊,對於動態資源分配至關重要。每個 ResourceSlice 必須包含以下資訊:

  • **資源池**:驅動程式管理的一個或多個資源組。該池可以跨越多個 ResourceSlice。池中資源的變化必須傳播到該池中的所有 ResourceSlice。管理該池的裝置驅動程式負責確保這種傳播發生。
  • **裝置**:受管池中的裝置。ResourceSlice 可以列出池中的所有裝置或池中裝置的一個子集。ResourceSlice 定義裝置資訊,例如屬性、版本和容量。裝置使用者可以透過過濾 ResourceClaim 或 DeviceClass 中的裝置資訊來選擇要分配的裝置。
  • **節點**:可以訪問資源的節點。驅動程式可以選擇哪些節點可以訪問資源,無論是叢集中的所有節點、單個命名節點還是具有特定節點標籤的節點。

驅動程式使用控制器來協調叢集中的 ResourceSlice 與驅動程式必須釋出的資訊。此控制器會覆蓋任何手動更改,例如叢集使用者建立或修改 ResourceSlice。

考慮以下 ResourceSlice 示例:

apiVersion: resource.k8s.io/v1
kind: ResourceSlice
metadata:
  name: cat-slice
spec:
  driver: "resource-driver.example.com"
  pool:
    generation: 1
    name: "black-cat-pool"
    resourceSliceCount: 1
  # The allNodes field defines whether any node in the cluster can access the device.
  allNodes: true
  devices:
  - name: "large-black-cat"
    attributes:
      color:
        string: "black"
      size:
        string: "large"
      cat:
        boolean: true

此 ResourceSlice 由 `black-cat-pool` 池中的 `resource-driver.example.com` 驅動程式管理。`allNodes: true` 欄位表示叢集中的任何節點都可以訪問這些裝置。ResourceSlice 中有一個名為 `large-black-cat` 的裝置,具有以下屬性:

  • `color`:`black`
  • `size`:`large`
  • `cat`:`true`

DeviceClass 可以透過使用這些屬性來選擇此 ResourceSlice,ResourceClaim 可以過濾該 DeviceClass 中的特定裝置。

DRA 資源分配的工作原理

以下各節描述了各種DRA 使用者型別以及 Kubernetes 系統在動態資源分配期間的工作流程。

使用者工作流程

  1. **驅動程式建立**:裝置所有者或第三方實體建立驅動程式,這些驅動程式可以在叢集中建立和管理 ResourceSlice。這些驅動程式(可選)還會建立 DeviceClass,用於定義裝置類別以及如何請求它們。
  2. **叢集配置**:叢集管理員建立叢集,將裝置連線到節點,並安裝 DRA 裝置驅動程式。叢集管理員(可選)建立 DeviceClass,用於定義裝置類別以及如何請求它們。
  3. **資源宣告**:工作負載操作員建立 ResourceClaimTemplate 或 ResourceClaim,請求 DeviceClass 中的特定裝置配置。在同一步驟中,工作負載操作員修改其 Kubernetes 清單以請求這些 ResourceClaimTemplate 或 ResourceClaim。

Kubernetes 工作流程

  1. **ResourceSlice 建立**:叢集中的驅動程式建立 ResourceSlice,代表受管的類似裝置池中的一個或多個裝置。

  2. **工作負載建立**:叢集控制平面檢查新工作負載是否引用 ResourceClaimTemplate 或特定的 ResourceClaim。

    • 如果工作負載使用 ResourceClaimTemplate,則名為 `resourceclaim-controller` 的控制器會為工作負載中的每個 Pod 生成 ResourceClaim。
    • 如果工作負載使用特定的 ResourceClaim,Kubernetes 會檢查該 ResourceClaim 是否存在於叢集中。如果 ResourceClaim 不存在,則 Pod 將無法部署。
  3. **ResourceSlice 過濾**:對於每個 Pod,Kubernetes 檢查叢集中的 ResourceSlice,以查詢滿足以下所有條件的裝置:

    • 可以訪問資源的節點有資格執行該 Pod。
    • ResourceSlice 具有未分配的資源,與 Pod 的 ResourceClaim 的要求相匹配。
  4. **資源分配**:在為 Pod 的 ResourceClaim 找到符合條件的 ResourceSlice 後,Kubernetes 排程器會使用分配詳細資訊更新 ResourceClaim。

  5. **Pod 排程**:資源分配完成後,排程器將 Pod 放置在可以訪問所分配資源的節點上。裝置驅動程式和該節點上的 kubelet 會配置裝置以及 Pod 對裝置的訪問許可權。

動態資源的可觀測性

你可以使用以下任何方法檢查動態分配資源的狀態:

kubelet 裝置指標

`PodResourcesLister` kubelet gRPC 服務允許你監控正在使用的裝置。`DynamicResource` 訊息提供了特定於動態資源分配的資訊,例如裝置名稱和宣告名稱。有關詳細資訊,請參閱監控裝置外掛資源

ResourceClaim 裝置狀態

功能狀態: Kubernetes v1.33 [beta] (預設啟用:true)

DRA 驅動程式可以在 ResourceClaim 的 `status.devices` 欄位中報告每個已分配裝置的特定於驅動程式的裝置狀態資料。例如,驅動程式可以列出分配給網路介面裝置的 IP 地址。

驅動程式新增到 ResourceClaim `status.devices` 欄位中的資訊的準確性取決於驅動程式。評估驅動程式以確定你是否可以依賴此欄位作為裝置資訊的唯一來源。

如果停用 `DRAResourceClaimDeviceStatus` Feature Gate,則 `status.devices` 欄位在儲存 ResourceClaim 時會自動清除。當 DRA 驅動程式可以更新已設定 `status.devices` 欄位的現有 ResourceClaim 時,支援 ResourceClaim 裝置狀態。

有關 `status.devices` 欄位的詳細資訊,請參閱 ResourceClaim API 參考。

裝置健康監測

特性狀態: Kubernetes v1.31 [alpha] (預設停用)

作為一項 Alpha 功能,Kubernetes 提供了一種機制來監控和報告動態分配的基礎設施資源的健康狀況。對於在專用硬體上執行的有狀態應用程式,瞭解裝置何時發生故障或變得不健康至關重要。瞭解裝置是否恢復也很有幫助。

要啟用此功能,必須啟用 `ResourceHealthStatus` Feature Gate,並且 DRA 驅動程式必須實現 `DRAResourceHealth` gRPC 服務。

當 DRA 驅動程式檢測到已分配裝置變得不健康時,它會將此狀態報告給 kubelet。然後,此健康資訊直接暴露在 Pod 的狀態中。kubelet 會在每個容器的狀態中填充 `allocatedResourcesStatus` 欄位,詳細說明分配給該容器的每個裝置的健康狀況。

這為使用者和控制器對硬體故障做出反應提供了關鍵的可見性。對於正在發生故障的 Pod,你可以檢查此狀態以確定故障是否與不健康的裝置有關。

預排程 Pod

當你(或其他 API 客戶端)建立 Pod 時,如果 `spec.nodeName` 已經設定,則排程器將被跳過。如果該 Pod 需要的某些 ResourceClaim 尚不存在,未分配或未為該 Pod 預留,則 kubelet 將無法執行該 Pod,並會定期重新檢查,因為這些要求可能仍會在以後得到滿足。

當 Pod 排程時(版本偏差、配置、Feature Gate 等),如果排程器中未啟用動態資源分配支援,也可能出現這種情況。kube-controller-manager 會檢測到這種情況,並嘗試透過預留所需的 ResourceClaim 來使 Pod 可執行。然而,這僅適用於這些 ResourceClaim 已由排程器為其他 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` 欄位,轉而使用節點選擇器。

DRA Beta 特性

以下各節描述了在 Beta 特性階段可用的 DRA 特性。有關更多資訊,請參閱在叢集中設定 DRA

管理員訪問

特性狀態: Kubernetes v1.34 [beta] (預設啟用:true)

你可以將 ResourceClaim 或 ResourceClaimTemplate 中的請求標記為具有特權功能,用於維護和故障排除任務。具有管理員訪問許可權的請求授予對正在使用的裝置的訪問許可權,並可能在容器中使裝置可用時啟用額外的許可權。

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

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

管理員訪問是一種特權模式,不應在多租戶叢集中授予普通使用者。從 Kubernetes v1.33 開始,只有被授權在帶有 `resource.k8s.io/admin-access: "true"`(區分大小寫)標籤的名稱空間中建立 ResourceClaim 或 ResourceClaimTemplate 物件的使用者才能使用 `adminAccess` 欄位。這確保了非管理員使用者不能濫用此功能。從 Kubernetes v1.34 開始,此標籤已更新為 `resource.kubernetes.io/admin-access: "true"`。

DRA Alpha 特性

以下各節描述了在 Alpha 特性階段可用的 DRA 特性。要使用這些特性中的任何一個,你還必須透過啟用 DynamicResourceAllocation Feature Gate 和 DRA API 組來在叢集中設定 DRA。有關更多資訊,請參閱在叢集中設定 DRA

DRA 的擴充套件資源分配

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

你可以為 DeviceClass 提供一個擴充套件資源名稱。排程器將為擴充套件資源請求選擇與該類匹配的裝置。這允許使用者繼續在 Pod 中使用擴充套件資源請求,以請求裝置外掛提供的擴充套件資源或 DRA 裝置。同一擴充套件資源可以由裝置外掛或 DRA 在單個叢集節點上提供。同一擴充套件資源可以由裝置外掛在某些節點上提供,由 DRA 在同一叢集中的其他節點上提供。

在下面的示例中,DeviceClass 被賦予了擴充套件資源名稱 `example.com/gpu`。如果一個 Pod 請求擴充套件資源 `example.com/gpu: 2`,它可以排程到具有兩個或更多與 DeviceClass 匹配的裝置的節點。

apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
  name: gpu.example.com
spec:
  selectors:
  - cel:
      expression: device.driver == 'gpu.example.com' && device.attributes['gpu.example.com'].type
        == 'gpu'
  extendedResourceName: example.com/gpu

此外,使用者可以使用一個特殊的擴充套件資源來分配裝置,而無需顯式建立 ResourceClaim。使用擴充套件資源名稱字首 `deviceclass.resource.kubernetes.io/` 和 DeviceClass 名稱。這適用於任何 DeviceClass,即使它沒有指定擴充套件資源名稱。生成的 ResourceClaim 將包含對該 DeviceClass 的指定數量裝置的 `ExactCount` 請求。

DRA 的擴充套件資源分配是一個**Alpha 特性**,僅當 kube-apiserver、kube-scheduler 和 kubelet 中啟用了 `DRAExtendedResource` Feature Gate 時才啟用。

可分割槽裝置

特性狀態: `Kubernetes v1.33 [alpha]`(預設啟用:false)

DRA 中表示的裝置不一定是一個連線到單個機器的單個單元,也可以是由連線到多個機器的多個裝置組成的邏輯裝置。這些裝置可能會消耗底層物理裝置的重疊資源,這意味著當一個邏輯裝置被分配時,其他裝置將不再可用。

在 ResourceSlice API 中,這表示為命名 CounterSets 的列表,每個 CounterSet 包含一組命名計數器。計數器表示物理裝置上可用的資源,這些資源由透過 DRA 宣傳的邏輯裝置使用。

邏輯裝置可以指定 ConsumesCounters 列表。每個條目包含對 CounterSet 的引用和一組命名的計數器以及它們將消耗的數量。因此,要使裝置可分配,引用的 CounterSet 必須具有裝置引用的計數器的足夠數量。

下面是兩個裝置的示例,每個裝置從共享計數器(8Gi 記憶體)中消耗 6Gi 記憶體。因此,在任何時間點,只有一個裝置可以被分配。排程器處理此問題,並且對於消費者是透明的,因為 ResourceClaim API 不受影響。

kind: ResourceSlice
apiVersion: resource.k8s.io/v1
metadata:
  name: resourceslice
spec:
  nodeName: worker-1
  pool:
    name: pool
    generation: 1
    resourceSliceCount: 1
  driver: dra.example.com
  sharedCounters:
  - name: gpu-1-counters
    counters:
      memory:
        value: 8Gi
  devices:
  - name: device-1
    consumesCounters:
    - counterSet: gpu-1-counters
      counters:
        memory:
          value: 6Gi
  - name: device-2
    consumesCounters:
    - counterSet: gpu-1-counters
      counters:
        memory:
          value: 6Gi

可分割槽裝置是一個**Alpha 特性**,僅當 kube-apiserver 和 kube-scheduler 中啟用了 `DRAPartitionableDevices` Feature Gate 時才啟用。

可消耗容量

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

可消耗容量功能允許同一裝置被多個獨立的 ResourceClaims 消耗,Kubernetes 排程器管理每個宣告使用了多少裝置容量。這類似於 Pod 如何共享節點上的資源;ResourceClaims 可以共享裝置上的資源。

裝置驅動程式可以在 `ResourceSlice` 的 `.spec.devices` 中設定 `allowMultipleAllocations` 欄位,以允許將該裝置分配給多個獨立的 ResourceClaims 或 ResourceClaim 中的多個請求。

使用者可以在 `ResourceClaim` 的 `spec.devices.requests` 中設定 `capacity` 欄位,以指定每個分配的裝置資源要求。

對於允許多次分配的裝置,請求的容量是從其總容量中提取或**消耗**的,這個概念被稱為**可消耗容量**。然後,排程器確保所有宣告的總消耗容量不超過裝置的總體容量。此外,驅動程式作者可以在單個裝置容量上使用 `requestPolicy` 約束來控制這些容量的消耗方式。例如,驅動程式作者可以指定給定的容量僅以 1Gi 的增量消耗。

這是一個網路裝置的示例,它允許多次分配幷包含可消耗的頻寬容量。

kind: ResourceSlice
apiVersion: resource.k8s.io/v1
metadata:
  name: resourceslice
spec:
  nodeName: worker-1
  pool:
    name: pool
    generation: 1
    resourceSliceCount: 1
  driver: dra.example.com
  devices:
  - name: eth1
    allowMultipleAllocations: true
    attributes:
      name:
        string: "eth1"
    capacity:
      bandwidth:
        requestPolicy:
          default: "1M"
          validRange:
            min: "1M"
            step: "8"
        value: "10G"

可消耗容量可以按以下示例所示進行請求。

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: bandwidth-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        exactly:
        - deviceClassName: resource.example.com
          capacity:
            requests:
              bandwidth: 1G

分配結果將包括消耗的容量和份額識別符號。

apiVersion: resource.k8s.io/v1
kind: ResourceClaim
...
status:
  allocation:
    devices:
      results:
      - consumedCapacity:
          bandwidth: 1G
        device: eth1
        shareID: "a671734a-e8e5-11e4-8fde-42010af09327"

在此示例中,選擇了一個可多重分配的裝置。但是,任何至少具有請求的 1G 頻寬的 `resource.example.com` 裝置都可以滿足要求。如果選擇一個不可多重分配的裝置,則分配將導致整個裝置。要強制使用僅可多重分配的裝置,可以使用 CEL 條件 `device.allowMultipleAllocations == true`。

裝置汙點和容忍度

特性狀態: `Kubernetes v1.33 [alpha]`(預設啟用:false)

裝置汙點類似於節點汙點:汙點具有字串鍵、字串值和效應。效應應用於使用被汙點裝置的 ResourceClaim 以及引用該 ResourceClaim 的所有 Pod。 “NoSchedule”效應阻止排程這些 Pod。當嘗試分配 ResourceClaim 時,被汙點裝置將被忽略,因為使用它們將阻止 Pod 的排程。

“NoExecute”效應意味著“NoSchedule”,此外還會導致已排程所有 Pod 的逐出。這種逐出是由 kube-controller-manager 中的裝置汙點逐出控制器透過刪除受影響的 Pod 來實現的。

ResourceClaims 可以容忍汙點。如果汙點被容忍,則其效應不適用。空容忍度匹配所有汙點。容忍度可以限制為某些效應和/或匹配某些鍵/值對。容忍度可以檢查某個鍵是否存在,無論其值如何,也可以檢查鍵的特定值。有關此匹配的更多資訊,請參閱節點汙點概念

透過在一定時間內容忍汙點,可以延遲逐出。該延遲從汙點新增到裝置的時間開始,該時間記錄在汙點的一個欄位中。

汙點如上所述也適用於分配節點上“所有”裝置的 ResourceClaims。所有裝置必須是無汙點的,或者它們的所有汙點都必須被容忍。分配具有管理員訪問許可權的裝置(如上文所述)也不例外。使用該模式的管理員必須明確容忍所有汙點才能訪問被汙點裝置。

裝置汙點和容忍度是一個**Alpha 特性**,僅當 kube-apiserver、kube-controller-manager 和 kube-scheduler 中啟用了 `DRADeviceTaints` Feature Gate 時才啟用。要使用 DeviceTaintRules,必須啟用 `resource.k8s.io/v1alpha3` API 版本。

你可以透過使用 DeviceTaintRule API 種類,以以下方式向裝置新增汙點。

驅動程式設定的汙點

DRA 驅動程式可以向其在 ResourceSlice 中釋出的裝置資訊新增汙點。查閱 DRA 驅動程式的文件以瞭解驅動程式是否使用汙點以及其鍵和值是什麼。

管理員設定的汙點

管理員或控制平面元件可以對裝置施加汙點,而無需告訴 DRA 驅動程式在其 ResourceSlice 的裝置資訊中包含汙點。他們透過建立 DeviceTaintRule 來實現這一點。每個 DeviceTaintRule 會向匹配裝置選擇器的裝置新增一個汙點。如果沒有這樣的選擇器,則不會對任何裝置施加汙點。這使得在不小心遺漏選擇器時,意外逐出所有使用 ResourceClaim 的 Pod 變得更加困難。

可以透過給出 DeviceClass、驅動程式、池和/或裝置的名稱來選擇裝置。DeviceClass 選擇該 DeviceClass 中選擇器選擇的所有裝置。僅使用驅動程式名稱,管理員可以對該驅動程式管理的所有裝置施加汙點,例如在整個叢集中對該驅動程式進行某種維護時。新增池名稱可以將汙點限制到單個節點,如果驅動程式管理節點本地裝置的話。

最後,新增裝置名稱可以選擇一個特定裝置。如果需要,裝置名稱和池名稱也可以單獨使用。例如,鼓勵節點本地裝置的驅動程式使用節點名稱作為其池名稱。然後,使用該池名稱施加汙點會自動對節點上的所有裝置施加汙點。

驅動程式可能會使用“gpu-0”等穩定名稱,這些名稱隱藏了當前分配給該名稱的特定裝置。為了支援對特定硬體例項施加汙點,可以在 DeviceTaintRule 中使用 CEL 選擇器來匹配供應商特定的唯一 ID 屬性,如果驅動程式為其硬體支援該屬性的話。

只要 DeviceTaintRule 存在,汙點就適用。它可以隨時修改和刪除。這是一個虛構 DRA 驅動程式的 DeviceTaintRule 示例:

apiVersion: resource.k8s.io/v1alpha3
kind: DeviceTaintRule
metadata:
  name: example
spec:
  # The entire hardware installation for this
  # particular driver is broken.
  # Evict all pods and don't schedule new ones.
  deviceSelector:
    driver: dra.example.com
  taint:
    key: dra.example.com/unhealthy
    value: Broken
    effect: NoExecute

裝置繫結條件

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

裝置繫結條件允許 Kubernetes 排程器延遲 Pod 繫結,直到確認外部資源(例如連線到網路的 GPU 或可程式設計 FPGA)已準備就緒。

這種等待行為在排程框架的PreBind 階段實現。在此階段,排程器會檢查所有所需的裝置條件是否滿足,然後才繼續繫結。

這透過避免過早繫結來提高排程可靠性,並能夠與外部裝置控制器協調。

要使用此功能,裝置驅動程式(通常由驅動程式所有者管理)必須在 `ResourceSlice` 的 `Device` 部分發布以下欄位。叢集管理員必須啟用 `DRADeviceBindingConditions` 和 `DRAResourceClaimDeviceStatus` Feature Gate,排程器才能識別這些欄位。

  • `bindingConditions`:在 Pod 繫結之前,必須在關聯 ResourceClaim 的 `status.conditions` 欄位中設定為 `True` 的條件型別列表。這些通常表示就緒訊號,例如“DeviceAttached”或“DeviceInitialized”。
  • `bindingFailureConditions`:如果關聯 ResourceClaim 的 `status.conditions` 欄位中設定為 `True`,則表示失敗狀態的條件型別列表。如果任何這些條件為 `True`,排程器將中止繫結並重新排程 Pod。
  • `bindsToNode`:如果設定為 `true`,排程器會將選定的節點名稱記錄在 ResourceClaim 的 `status.allocation.nodeSelector` 欄位中。這不影響 Pod 的 `spec.nodeSelector`。相反,它在 ResourceClaim 內部設定一個節點選擇器,外部控制器可以使用它來執行節點特定操作,例如裝置連線或準備。

`bindingConditions` 和 `bindingFailureConditions` 中列出的所有條件型別都從 ResourceClaim 的 `status.conditions` 欄位進行評估。外部控制器負責使用標準的 Kubernetes 條件語義(`type`、`status`、`reason`、`message`、`lastTransitionTime`)更新這些條件。

排程器最多等待 **600 秒**,直到所有 `bindingConditions` 變為 `True`。如果達到超時或任何 `bindingFailureConditions` 為 `True`,排程器將清除分配並重新排程 Pod。

apiVersion: resource.k8s.io/v1
kind: ResourceSlice
metadata:
  name: gpu-slice
spec:
  driver: dra.example.com
  nodeSelector:
    accelerator-type: high-performance
  pool:
    name: gpu-pool
    generation: 1
    resourceSliceCount: 1
  devices:
    - name: gpu-1
      attributes:
        vendor:
          string: "example"
        model:
          string: "example-gpu"
      bindsToNode: true
      bindingConditions:
        - dra.example.com/is-prepared
      bindingFailureConditions:
        - dra.example.com/preparing-failed

此 ResourceSlice 示例具有以下屬性:

  • ResourceSlice 以帶有 `accelerator-type=high-performance` 標籤的節點為目標,以便排程器僅使用一組特定的合格節點。
  • 排程器從選定組中選擇一個節點(例如 `node-3`),並將 ResourceClaim 中的 `status.allocation.nodeSelector` 欄位設定為該節點名稱。
  • `dra.example.com/is-prepared` 繫結條件表示裝置 `gpu-1` 必須在繫結之前準備好(`is-prepared` 條件的狀態為 `True`)。
  • 如果 `gpu-1` 裝置準備失敗(`preparing-failed` 條件的狀態為 `True`),排程器將中止繫結。
  • 排程器最多等待 600 秒,直到裝置準備就緒。
  • 外部控制器可以使用 ResourceClaim 中的節點選擇器,在選定的節點上執行節點特定設定。

下一步

上次修改時間為太平洋標準時間 2025 年 8 月 31 日凌晨 2:24:更新 DRA 術語 API 版本至 resource.k8s.io/v1 (8c2db7787f)