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





























