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

第三方裝置指標達到 GA

隨著 Kubernetes 1.20 的釋出,管理大型 Kubernetes 叢集的基礎設施團隊將看到兩個令人興奮且期待已久的特性畢業。

  • Pod Resources API(在 1.13 中引入)終於畢業到 GA 階段。這允許 Kubernetes 外掛獲取有關節點資源使用和分配的資訊;例如:哪個 Pod/容器使用哪個裝置。
  • DisableAcceleratorMetrics 功能(在 1.19 中引入)將畢業到 Beta 階段,並將預設啟用。這將移除 kubelet 報告的裝置指標,轉而採用新的外掛架構。

許多與基本裝置支援(裝置發現、外掛和監控)相關的功能正在達到高度穩定水平。Kubernetes 使用者應將這些功能視為實現更復雜用例(網路、排程、儲存等)的墊腳石!

其中一個例子是非統一記憶體訪問(NUMA)放置,在這種情況下,在選擇裝置時,應用程式通常希望確保 CPU 記憶體和裝置記憶體之間的資料傳輸儘可能快。在某些情況下,不正確的 NUMA 放置會抵消將計算解除安裝到外部裝置的優勢。

如果您對這些主題感興趣,請考慮加入 Kubernetes Node 特別興趣小組 (SIG) 討論所有與 Kubernetes 節點相關的主題,或加入 COD(容器編排裝置)工作組討論與執行時相關的主題,或加入資源管理論壇討論與資源管理相關的主題!

Pod 資源 API - 為什麼需要它?

Kubernetes 是一個與供應商無關的平臺。如果我們要讓它支援裝置監控,在 Kubernetes 程式碼庫中新增供應商特定的程式碼並不是一個理想的解決方案。歸根結底,裝置是一個需要深入專業知識的領域,在該領域新增和維護程式碼的最佳人選是裝置供應商本身。

Pod 資源 API 是為解決此問題而構建的。每個供應商都可以構建和維護自己的樹外監控外掛。這個監控外掛通常作為叢集中的一個獨立 Pod 部署,然後可以將裝置發出的指標與使用該裝置的 Pod 相關聯。

例如,使用 NVIDIA GPU dcgm-exporter 以 Prometheus 格式抓取指標

$ curl -sL http://127.0.01:8080/metrics


# HELP DCGM_FI_DEV_SM_CLOCK SM clock frequency (in MHz).
# TYPE DCGM_FI_DEV_SM_CLOCK gauge
# HELP DCGM_FI_DEV_MEM_CLOCK Memory clock frequency (in MHz).
# TYPE DCGM_FI_DEV_MEM_CLOCK gauge
# HELP DCGM_FI_DEV_MEMORY_TEMP Memory temperature (in C).
# TYPE DCGM_FI_DEV_MEMORY_TEMP gauge
...
DCGM_FI_DEV_SM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 139
DCGM_FI_DEV_MEM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 405
DCGM_FI_DEV_MEMORY_TEMP{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 9223372036854775794

每個代理都應遵守節點監控準則。換句話說,外掛應以 Prometheus 格式生成指標,並且新指標不應直接依賴於 Kubernetes 基礎。

這允許指標的消費者使用相容的監控管道來收集和分析來自各種代理的指標,即使它們由不同的供應商維護。

Device metrics flowchart

停用 NVIDIA GPU 指標 - 警告

隨著外掛監控系統的畢業,Kubernetes 正在棄用 kubelet 報告的 NVIDIA GPU 指標。

隨著 DisableAcceleratorMetrics 功能在 Kubernetes 1.20 中預設啟用,NVIDIA GPU 在 Kubernetes 中不再是特殊公民。這符合供應商中立的精神,並使最適合的人能夠按照自己的釋出計劃維護他們的外掛!

使用者現在需要安裝 NVIDIA GDGM exporter 或使用 bindings 來收集更準確、更完整的 NVIDIA GPU 指標。此棄用意味著您不能再依賴 kubelet 報告的指標,例如用於收集 NVIDIA GPU 記憶體利用率的 container_accelerator_duty_cyclecontainer_accelerator_memory_used_bytes

這意味著以前依賴 kubelet 報告的 NVIDIA GPU 指標的使用者,需要更新其引用並部署 NVIDIA 外掛。即 Kubernetes 報告的不同指標對映到以下指標

Kubernetes 指標NVIDIA dcgm-exporter 指標
container_accelerator_duty_cycleDCGM_FI_DEV_GPU_UTIL
container_accelerator_memory_used_bytesDCGM_FI_DEV_FB_USED
container_accelerator_memory_total_bytesDCGM_FI_DEV_FB_FREE + DCGM_FI_DEV_FB_USED

您可能還對其他指標感興趣,例如 DCGM_FI_DEV_GPU_TEMP(GPU 溫度)或 DCGM_FI_DEV_POWER_USAGE(功耗)。預設集合可在 Nvidia 的 資料中心 GPU 管理器文件中找到。

請注意,對於此版本,您仍然可以將 DisableAcceleratorMetrics 功能門設定為 false,從而有效地重新啟用 kubelet 報告 NVIDIA GPU 指標的功能。

結合 Pod 資源 API 的畢業,這些工具可用於生成 GPU 遙測資料,可用於視覺化儀表盤,示例如下

Grafana visualization of device metrics

Pod 資源 API - 我可以用它來做什麼?

這個介面一經推出,許多供應商就開始將其用於各種不同的用例!列舉幾個例子:

kuryr-kubernetes CNI 外掛與 intel-sriov-device-plugin 協同工作。這使得 CNI 外掛能夠了解 kubelet 對 SR-IOV 虛擬功能 (VF) 的分配情況,並利用這些資訊正確設定容器網路名稱空間,並使用具有適當 NUMA 節點的裝置。我們還期望此介面用於跟蹤已分配和可用資源,並提供有關工作節點 NUMA 拓撲的資訊。

另一個用例是 GPU 遙測,其中 GPU 指標可以與分配給 GPU 的容器和 Pod 相關聯。NVIDIA 的 dcgm-exporter 就是一個例子,但也可以很容易地以相同的範例構建其他工具。

Pod Resources API 是一個簡單的 gRPC 服務,它向客戶端提供 kubelet 知道的 Pod 資訊。該資訊涉及 kubelet 所做的裝置分配和 CPU 分配。這些資訊分別來自 kubelet 的裝置管理器和 CPU 管理器的內部狀態。

您可以在下面看到 API 的示例以及 Go 客戶端如何用幾行程式碼使用該資訊

service PodResourcesLister {
    rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
    rpc GetAllocatableResources(AllocatableResourcesRequest) returns (AllocatableResourcesResponse) {}

    // Kubernetes 1.21
    rpc Watch(WatchPodResourcesRequest) returns (stream WatchPodResourcesResponse) {}
}
func main() {
	ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)
	defer cancel()

	socket := "/var/lib/kubelet/pod-resources/kubelet.sock"
	conn, err := grpc.DialContext(ctx, socket, grpc.WithInsecure(), grpc.WithBlock(),
		grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
			return net.DialTimeout("unix", addr, timeout)
		}),
	)

	if err != nil {
		panic(err)
	}

    client := podresourcesapi.NewPodResourcesListerClient(conn)
    resp, err := client.List(ctx, &podresourcesapi.ListPodResourcesRequest{})
	if err != nil {
		panic(err)
	}
	net.Printf("%+v\n", resp)
}

最後,請注意,您可以透過在 kubelet 的 /metrics 端點上檢視名為 pod_resources_endpoint_requests_total 的新 kubelet 指標來觀察對 Pod Resources 端點發出的請求數量。

裝置監控適合生產環境嗎?我可以擴充套件它嗎?我可以貢獻嗎?

是的!此功能於近兩年前在 1.13 版本中釋出,已被廣泛採用,已用於各種雲託管服務,並隨著其在 Kubernetes 1.20 中畢業到 GA 階段,已達到生產就緒水平!

如果您是裝置供應商,您可以立即開始使用它!如果您只想監控叢集中的裝置,請獲取最新版本的監控外掛!

如果您對該領域充滿熱情,請加入 Kubernetes 社群,幫助改進 API 或貢獻裝置監控外掛!

致謝

我們感謝為本功能做出貢獻或提供反饋的社群成員,包括 WG-Resource-Management、SIG-Node 和資源管理論壇的成員!