本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 1.28: 節點 podresources API 進入 GA 階段
podresources API 是 kubelet 在節點上本地提供的一個 API,用於公開專門分配給容器的計算資源。隨著 Kubernetes 1.28 的釋出,該 API 現已正式釋出(GA)。
它解決了什麼問題?
kubelet 可以為容器分配獨佔資源,例如CPU,授予對完整核心的獨佔訪問許可權,或記憶體,無論是記憶體區域還是大頁。需要高效能或低延遲(或兩者兼備)的工作負載會利用這些特性。kubelet 還可以將裝置分配給容器。這些支援獨佔分配的功能統稱為“資源管理器”。
如果沒有像 podresources 這樣的 API,瞭解資源分配的唯一可能選項是讀取資源管理器使用的狀態檔案。雖然這是出於必要,但這種方法的問題在於這些檔案的路徑和格式都是內部實現細節。儘管非常穩定,但專案保留自由更改它們的權利。因此,使用狀態檔案的內容是脆弱且不受支援的,建議這樣做專案考慮遷移到 podresources API 或其他受支援的 API。
API 概述
podresources API 最初是為了實現裝置監控而提出的。為了啟用監控代理,一個關鍵的前提是能夠內省由 kubelet 執行的裝置分配。滿足這一目的是該 API 的最初目標。API 的第一個迭代版本只實現了一個函式,List
,用於返回有關裝置分配給容器的資訊。該 API 被 multus CNI 和 GPU 監控工具使用。
自誕生以來,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 在其執行的同一節點上本地提供。在 Unix 風格的系統上,端點透過 Unix 域套接字提供;預設路徑是 /var/lib/kubelet/pod-resources/kubelet.sock
。在 Windows 上,端點透過命名管道提供;預設路徑是 npipe://\\.\pipe\kubelet-pod-resources
。
為了讓容器化的監控應用程式使用該 API,應將套接字掛載到容器內部。一個好的做法是掛載 podresources 套接字端點所在的目錄,而不是直接掛載套接字。這將確保在 kubelet 重啟後,容器化的監控應用程式能夠重新連線到套接字。
一個假設的監控代理的示例清單,它使用 podresources API 並作為 DaemonSet 部署,可能如下所示
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 推動。請加入我們,與社群聯絡,分享您圍繞上述功能及其他方面的想法和反饋。我們期待您的聲音!