雲原生環境中的映象相容性

在電信、高效能計算或人工智慧計算等行業中,系統必須高度可靠地執行並滿足嚴格的效能標準,容器化應用通常需要特定的作業系統配置或硬體支援。要求使用特定版本的核心、其配置、裝置驅動程式或系統元件是一種常見的做法。儘管存在開放容器倡議 (Open Container Initiative, OCI) 這個旨在定義容器映象標準和規範的治理社群,但在表達此類相容性要求方面一直存在差距。解決這個問題的需求催生了不同的提案,並最終在 Kubernetes 的節點特性發現 (Node Feature Discovery, NFD) 中得以實現。

NFD 是一個開源的 Kubernetes 專案,它能自動檢測並報告叢集節點的硬體和系統特性。這些資訊幫助使用者將工作負載排程到滿足特定系統要求的節點上,這對於有嚴格硬體或作業系統依賴的應用尤其有用。

對映象相容性規範的需求

容器與宿主作業系統之間的依賴關係

容器映象基於基礎映象構建,基礎映象提供了一個最小的執行時環境,通常是一個精簡的 Linux 使用者區,完全為空或無發行版 (distroless)。當應用程式需要宿主作業系統的某些特性時,相容性問題就會出現。這些依賴關係可以體現在以下幾個方面:

  • 驅動程式:宿主驅動程式版本必須與容器內庫版本支援的範圍相匹配,以避免相容性問題。例如 GPU 和網路驅動程式。
  • 庫或軟體:容器必須附帶特定版本或版本範圍的庫或軟體,才能在環境中以最佳狀態執行。高效能計算領域的例子有 MPI、EFA 或 Infiniband。
  • 核心模組或特性:必須存在特定的核心特性或模組。例如,需要支援防寫的大頁錯誤 (write protected huge page faults),或存在 VFIO。
  • 還有更多……

雖然 Kubernetes 中的容器最可能是滿足這些需求的抽象單元,但相容性的定義可以進一步擴充套件,以包括其他容器技術(如 Singularity)和其他 OCI 工件(如來自 spack 二進位制快取的二進位制檔案)。

多雲和混合雲的挑戰

容器化應用部署在各種 Kubernetes 發行版和雲提供商上,其中不同的宿主作業系統帶來了相容性挑戰。這些系統通常需要在部署工作負載之前進行預配置,或者它們是不可變的。例如,不同的雲提供商會包含不同的作業系統,如:

  • RHCOS/RHEL
  • Photon OS
  • Amazon Linux 2
  • Container-Optimized OS
  • Azure Linux OS
  • 還有更多...

每種作業系統都帶有獨特的核心版本、配置和驅動程式,這使得對於需要特定功能的應用來說,相容性成為一個不容忽視的問題。必須能夠快速評估一個容器是否適合在任何特定環境中執行。

映象相容性倡議

開放容器倡議映象相容性工作組內,我們致力於引入一個映象相容性元資料的標準。一個相容性規範將允許容器作者宣告所需的宿主作業系統特性,使相容性要求變得可發現和可程式設計。在 Kubernetes Node Feature Discovery 中實現的規範是討論中的提案之一。它旨在:

  • 定義一種結構化的方式來表達 OCI 映象清單中的相容性。
  • 在映象倉庫中支援容器映象的同時,也支援相容性規範。
  • 允許在排程容器前自動驗證相容性。

這個概念此後已在 Kubernetes Node Feature Discovery 專案中實現。

在 Node Feature Discovery 中的實現

該解決方案透過 NFD 的特性和 NodeFeatureGroup API 將相容性元資料整合到 Kubernetes 中。這個介面使使用者能夠根據暴露的硬體和軟體特性將容器匹配到節點,從而實現智慧排程和工作負載最佳化。

相容性規範

相容性規範是一個結構化的相容性物件列表,其中包含 *節點特性組 (Node Feature Groups)*。這些物件定義了映象的需求,並有助於對照宿主節點進行驗證。特性需求透過使用 NFD 專案中可用特性列表來描述。該模式具有以下結構:

  • version (string) - 指定 API 版本。
  • compatibilities (array of objects) - 相容性集合列表。
    • rules (object) - 指定 NodeFeatureGroup 來定義映象需求。
    • weight (int, 可選) - 節點親和性權重。
    • tag (string, 可選) - 分類標籤。
    • description (string, 可選) - 簡短描述。

一個示例如下:

version: v1alpha1
compatibilities:
- description: "My image requirements"
  rules:
  - name: "kernel and cpu"
    matchFeatures:
    - feature: kernel.loadedmodule
      matchExpressions:
        vfio-pci: {op: Exists}
    - feature: cpu.model
      matchExpressions:
        vendor_id: {op: In, value: ["Intel", "AMD"]}
  - name: "one of available nics"
    matchAny:
    - matchFeatures:
      - feature: pci.device
        matchExpressions:
          vendor: {op: In, value: ["0eee"]}
          class: {op: In, value: ["0200"]}
    - matchFeatures:
      - feature: pci.device
        matchExpressions:
          vendor: {op: In, value: ["0fff"]}
          class: {op: In, value: ["0200"]}

用於節點驗證的客戶端實現

為了簡化相容性驗證,我們實現了一個客戶端工具,它允許根據映象的相容性工件進行節點驗證。在這個工作流中,映象作者會生成一個相容性工件,該工件透過 referrers API 指向它在倉庫中描述的映象。當需要評估一個映象與某個宿主機的匹配度時,該工具可以發現此工件並在部署前驗證映象與節點的相容性。該客戶端可以在 Kubernetes 叢集內外驗證節點,從而將工具的實用性擴充套件到單個 Kubernetes 用例之外。未來,映象相容性可以在根據映象相容性需求建立特定工作負載配置檔案方面發揮關鍵作用,從而幫助實現更高效的排程。此外,它還有可能在一定程度上實現自動節點配置,進一步最佳化資源分配並確保專業化工作負載的無縫部署。

使用示例

  1. 定義映象相容性元資料

    一個容器映象可以包含元資料,用於描述其基於從節點發現的特性(如核心模組或 CPU 型號)的需求。本文前面提到的相容性規範示例就說明了這種用例。

  2. 將工件附加到映象

    映象相容性規範以 OCI 工件的形式儲存。你可以使用 oras 工具將此元資料附加到你的容器映象。倉庫只需支援 OCI 工件即可,不需要支援任意型別。請記住,容器映象和工件必須儲存在同一個倉庫中。使用以下命令將工件附加到映象:

    oras attach \
    --artifact-type application/vnd.nfd.image-compatibility.v1alpha1 <image-url> \ 
    <path-to-spec>.yaml:application/vnd.nfd.image-compatibility.spec.v1alpha1+yaml
    
  3. 驗證映象相容性

    附加相容性規範後,你可以驗證一個節點是否滿足映象的要求。這個驗證可以使用 nfd 客戶端來完成:

    nfd compat validate-node --image <image-url>
    
  4. 讀取客戶端的輸出

    最後,你可以讀取該工具生成的報告,或使用你自己的工具根據生成的 JSON 報告採取行動。

    validate-node command output

結論

透過 Node Feature Discovery 將映象相容性功能新增到 Kubernetes 中,凸顯了在雲原生環境中解決相容性問題日益增長的重要性。這只是一個開始,因為還需要進一步的工作來將相容性整合到 Kubernetes 內外工作負載的排程中。然而,透過將此功能整合到 Kubernetes 中,任務關鍵型工作負載現在可以更有效地定義和驗證宿主作業系統的要求。展望未來,在 Kubernetes 生態系統中採用相容性元資料將顯著提高專業化容器應用的可靠性和效能,確保它們滿足電信、高效能計算或任何需要特殊硬體或宿主作業系統配置的行業的嚴格要求。

參與其中

如果你有興趣參與映象相容性 API 和工具的設計與開發,請加入 Kubernetes Node Feature Discovery 專案。我們隨時歡迎新的貢獻者。