本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes 1.28:節點 podresources API 升級至 GA

podresources API 是由 kubelet 在節點本地提供的 API,它公開了專門分配給容器的計算資源。隨著 Kubernetes 1.28 的發布,該 API 現在已正式發布。

它解決了什麼問題?

kubelet 可以將獨佔資源分配給容器,例如 CPU,授予對完整核心的獨佔訪問權記憶體,無論是區域還是巨頁。需要高效能或低延遲(或兩者兼具)的工作負載會利用這些功能。kubelet 也可以將 設備分配給容器。總體而言,這些啟用獨佔分配的功能被稱為「資源管理器」。

如果沒有像 podresources 這樣的 API,了解資源分配的唯一可能選項是讀取資源管理器使用的狀態檔案。雖然這是出於必要性而採取的做法,但這種方法的問題是這些檔案的路徑和格式都是內部實作細節。儘管非常穩定,但專案保留隨時自由更改它們的權利。因此,使用狀態檔案的內容是脆弱且不受支援的,建議這樣做的專案考慮遷移到 podresources API 或其他受支援的 API。

API 概述

podresources API 最初是 為了啟用設備監控而提出的。為了啟用監控代理程式,一個關鍵的先決條件是啟用設備分配的自省,這由 kubelet 執行。服務於此目的是 API 的最初目標。API 的第一個迭代僅實作了一個函數 List,以返回有關設備分配給容器的資訊。此 API 被 multus CNIGPU 監控工具 使用。

自成立以來,podresources API 擴大了其範圍,以涵蓋設備管理器以外的其他資源管理器。從 Kubernetes 1.20 開始,List API 還報告 CPU 核心和記憶體區域(包括巨頁);API 還報告設備的 NUMA 局部性,而 CPU 和記憶體的局部性可以從系統中推斷出來。

在 Kubernetes 1.21 中,API 獲得了 GetAllocatableResources 函數。這個較新的 API 補充了現有的 List API,並使監控代理程式能夠確定未分配的資源,從而啟用基於 podresources API 之上的新功能,例如 NUMA 感知的調度器外掛程式

最後,在 Kubernetes 1.27 中,引入了另一個函數 Get,以便對 CNI 元外掛程式更友善,使其更簡單地訪問分配給特定 Pod 的資源,而不必篩選節點上所有 Pod 的資源。Get 函數目前處於 alpha 級別。

使用 API

podresources API 由 kubelet 在本地提供服務,與 kubelet 運行的節點相同。在 Unix 風格中,端點通過 Unix 域套接字提供服務;默認路徑是 /var/lib/kubelet/pod-resources/kubelet.sock。在 Windows 上,端點通過命名管道提供服務;默認路徑是 npipe://\\.\pipe\kubelet-pod-resources

為了使容器化的監控應用程式使用 API,應將套接字掛載在容器內部。一個好的做法是掛載 podresources 套接字端點所在的目錄,而不是直接掛載套接字。這將確保在 kubelet 重新啟動後,容器化的監控應用程式能夠重新連接到套接字。

一個假設的監控代理程式使用 podresources API 並部署為 DaemonSet 的範例 Manifest 可能如下所示

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: podresources-monitoring-app
  namespace: monitoring
spec:
  selector:
    matchLabels:
      name: podresources-monitoring
  template:
    metadata:
      labels:
        name: podresources-monitoring
    spec:
      containers:
      - args:
        - --podresources-socket=unix:///host-podresources/kubelet.sock
        command:
        - /bin/podresources-monitor
        image: podresources-monitor:latest  # just for an example
        volumeMounts:
        - mountPath: /host-podresources
          name: host-podresources
      serviceAccountName: podresources-monitor
      volumes:
      - hostPath:
          path: /var/lib/kubelet/pod-resources
          type: Directory
        name: host-podresources

我希望您發現以程式化的方式使用 podresources API 很簡單。kubelet API 套件提供了協議檔案和 Go 類型定義;但是,專案目前尚無可用的客戶端套件,並且不應直接使用現有程式碼。建議的 方法是在您的專案中重新實作客戶端,複製並貼上相關函數,例如 multus 專案 正在做的那樣

在運營使用 podresources API 的容器化監控應用程式時,有幾點值得強調,以防止出現「陷阱」時刻

  • 即使 API 僅公開數據,並且設計上不允許客戶端修改 kubelet 狀態,gRPC 請求/響應模型也需要對 podresources API 套接字進行讀寫訪問。換句話說,無法將容器掛載限制為 ReadOnly
  • 允許多個客戶端連接到 podresources 套接字並使用 API,因為它是無狀態的。
  • kubelet 具有 內建速率限制,以減輕來自行為不端或惡意使用者的本地阻斷服務攻擊。API 的使用者必須容忍伺服器返回的速率限制錯誤。速率限制目前是硬編碼且全局的,因此行為不端的客戶端可能會消耗所有配額,並可能使行為正確的客戶端挨餓。

未來增強功能

由於歷史原因,podresources API 的規範不如典型的 Kubernetes API(例如 Kubernetes HTTP API 或容器運行時介面)精確。這導致在邊緣情況下出現未指定的行為。目前正在 努力 糾正這種狀態並制定更精確的規範。

動態資源分配 (DRA) 基礎架構是對資源管理的一次重大改革。與 podresources API 的 整合 已經在進行中。

目前正在 努力 推薦或創建一個隨時可供使用的參考客戶端套件。

參與其中

此功能由 SIG Node 驅動。請加入我們,與社群聯繫,並分享您對上述功能及其他方面的想法和回饋。我們期待您的來信!