在 Kubernetes 中優(yōu)化 AI 和機器學習工作負載
Kubernetes 非常適合各種類型的容器化工作負載,從服務到作業(yè)再到有狀態(tài)應用程序。但是 AI 和需要 GPU 的機器學習工作負載呢?是的,Kubernetes 也支持這些,但有很多細微差別。
譯自Optimizing AI and Machine Learning Workloads in Kubernetes,作者 Eugene Burd 。
本文將介紹 Kubernetes 如何支持 GPU,包括調度、過度訂閱和時間共享以及安全性/隔離。此外,我們將討論三大公共云提供商如何支持這些功能,以及如何確保您的 GPU 節(jié)點僅由 GPU 工作負載使用。
設備插件
讓我們首先看一下 Kubernetes 支持 GPU 的機制。Kubernetes 本身不知道任何關于 GPU 的信息。相反,它提供了一個擴展機制,稱為設備插件。設備插件框架允許第三方廣告節(jié)點上可用的其他功能,如 GPU、InfiniBand 適配器等。
設備插件,通常以守護進程集實現(xiàn),向節(jié)點的 kubelet 注冊自己,并向 kubelet 廣告節(jié)點上可調度的資源。Kubelet 將此信息傳遞給 API 服務器,然后由 Kubernetes 調度程序使用,以調度請求每個容器的資源的工作負載到節(jié)點上。
圖片
從工作負載請求 GPU
既然我們了解了 Kubernetes 如何知道 GPU,那么讓我們來討論容器如何請求一個 GPU。工作負載可以以類似請求 CPU 或內存的方式請求 GPU,但有些不同。與 Kubernetes 本身支持的 CPU 不同,GPU(和設備插件一般)僅支持限制(您可以提供請求,但如果這樣做,您也必須提供限制,并且兩個值必須相等)。限制還必須是整數(shù)(不允許使用小數(shù)限制)。
讓我們看一個示例 pod。在本例中,pod 正在請求 1 個 Nvidia gpu。調度程序將嘗試找到一個具有可用 Nvidia gpu 且尚未分配的節(jié)點,并繼續(xù)在該節(jié)點上放置 pod。
apiVersion: v1
kind: Pod
metadata:
name: my-gpu-pod
spec:
containers:
- name: my-gpu-container
image: nvidia/cuda:11.0.3-runtime-ubuntu20.04
command: ["/bin/bash", "-c", "--"]
args: ["while true; do sleep 600; done;"]
resources:
requests:
cpu: 100m
memory: 500Mi
limits:
memory: 1000Mi
nvidia.com/gpu: 1
過度訂閱和時間共享
CPU 時間共享由 CNI 使用 linuxcgroups本地處理。它受您的請求和限制的影響 - 請參閱有關如何設置 CPU 請求和限制的文章(以及為什么要避免限制)。
GPU 時間共享對于 Nvidia GPU 通過兩種機制支持:
- 多實例 GPU(Nvidia A100、H100)支持多個計算和內存單元。在這種情況下,您可以配置要公開的分區(qū)數(shù)量。此配置驅動設備插件顯示每個物理 GPU 的多個“虛擬 GPU”。這由AWS、Azure和GCP支持。
- 對于單實例 GPU,Nvidia 的 GPU 調度程序通過對 GPU 上的工作負載進行時間分片來支持時間共享。這只有AWS和GCP支持。
雖然這種方法意味著可以過度訂閱 GPU,但您必須小心,因為您的工作負載可能會被餓死,與 CPU 不同,沒有完全公平的調度程序(CFS),也沒有 cgroup 優(yōu)先級,因此時間只能由工作負載平等劃分。
安全性/隔離
與 CPU 不同,當前 GPU 內沒有進程或內存隔離。這意味著調度到 GPU 上的所有工作負載共享其內存,因此您只應在互相信任的工作負載之間共享 GPU。
創(chuàng)建 GPU 節(jié)點
既然我們已經知道如何請求 GPU,您可能想知道如何創(chuàng)建具有 GPU 的節(jié)點以及如何安裝設備插件。這根據您使用的 kubernetes 提供商而有所不同,我們將在下面介紹 3 大提供商。
AWS
AWS 支持使用任何 EC2 GPU 實例類型創(chuàng)建節(jié)點組。您可以從兩個選項中進行選擇:
- 運行預裝了 Nvidia 驅動程序的 EKS 加速的 Amazon Linux AMI 。在這種情況下,您需要自行單獨安裝Nvidia 設備插件。
- 在節(jié)點組上運行 Nvidia 的GPU Operator。在這種情況下,升級是手動的。
Azure
Azure 支持使用三種選項創(chuàng)建節(jié)點池:
- 創(chuàng)建 GPU 節(jié)點池,其中自動包括 GPU 驅動程序,但需要您自己安裝 Nvidia 設備插件。
- 使用AKS GPU 鏡像預覽,其中包括 GPU 驅動程序和 Nvidia 設備插件。在這種情況下,升級是手動的。
- 在節(jié)點組上運行Nvidia 的 GPU Operator,它為您處理所有事項。
GCP
GKE 支持使用兩種選項創(chuàng)建節(jié)點池。
- 讓 google 管理 GPU 驅動程序安裝以及設備插件。使用此選項還允許 GKE 自動升級節(jié)點。
- 自己管理 GPU 驅動程序和設備插件
保護 GPU 節(jié)點免受非 GPU 工作負載的影響
最后,既然您已經創(chuàng)建了 GPU 節(jié)點,您會希望這些節(jié)點免受集群上運行的任何非 GPU 工作負載的影響。您可以通過污點和容忍來實現(xiàn)這一點。在創(chuàng)建節(jié)點池和組時,您會想要應用污點。如果集群具有非 GPU 節(jié)點池,GKE 會自動為您執(zhí)行此操作。其他提供商不會,所以您需要確保這樣做。
對于 pod,您會希望為污點提供容忍,以便它們可以調度到 GPU 節(jié)點上。下面的示例為名為“nvidia.com/gpu”的污點創(chuàng)建了一個容忍,這允許此 pod 在 nvidia GPU 節(jié)點上運行。
apiVersion: v1
kind: Pod
metadata:
name: my-gpu-pod
spec:
containers:
- name: my-gpu-container
image: nvidia/cuda:11.0.3-runtime-ubuntu20.04
command: ["/bin/bash", "-c", "--"]
args: ["while true; do sleep 600; done;"]
resources:
requests:
cpu: 100m
memory: 500Mi
limits:
memory: 1000Mi
nvidia.com/gpu: 1
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
隨著 AI 和機器學習工作負載的不斷增長,希望您考慮在 Kubernetes 上運行它們,而不是更昂貴的云提供商專有選項。
您是否已經嘗試在 Kubernetes 上運行 GPU 工作負載?哪些方面效果好?遇到哪些問題?