趋近智
您将配置一个支持GPU的节点池,该节点池可从零扩缩,确保仅在实际需要时才供应这些昂贵的资源。这种设置是构建经济高效的共享ML平台的基础。
我们将结合Kubernetes的污点(taints)、容忍度(tolerations)和资源请求,以创建一个系统,使集群自动扩缩器(Cluster Autoscaler)能够做出明智的、了解GPU的扩缩决策。您将部署一个明确请求GPU的Pod,并观察整个自动化过程,从Pod最初的Pending状态,到新GPU节点的供应,以及最终工作负载的调度。
开始之前,请确保您的环境已具备以下条件:
kubectl已配置为与您的集群通信。gcloud、aws、az)已通过认证。了解GPU的自动扩缩逻辑不依赖于集群自动扩缩器中的特殊“GPU模式”。相反,它是标准Kubernetes调度原语共同运作的结果。该过程如下进行:
nvidia.com/gpu=present:NoSchedule。此污点阻止任何Pod调度到这些节点上,除非它明确具有匹配的容忍度。这将我们昂贵的GPU资源圈定给真正需要它们的工作负载使用。resources.limits请求GPU,并包含对前一步骤中应用的污点的toleration(容忍度)。Pending(待处理)状态。Pending状态的Pod。它分析Pod的需求(GPU资源、容忍度),并确定从污点化的GPU节点池添加一个节点将允许该Pod被调度。Ready(就绪)状态,Kubernetes调度器将待处理的Pod调度到该节点上。以下图表说明了这一系列事件的完整流程。
从Pod提交到成功调度到新供应的GPU节点上的自动扩缩流程。
首先,我们定义一个符合自动扩缩条件的节点池,且专门用于GPU工作负载。两个最重要的参数是将最小规模设置为0并应用NoSchedule污点。将min-nodes设置为零是我们节约成本策略的核心。
以下是在Google Kubernetes Engine (GKE)中创建此类节点池的示例命令。对于EKS或AKS,原理是相同的,尽管具体参数会有所不同。
# Example for GKE
gcloud container node-pools create gpu-pool \
--project "<your-gcp-project>" \
--cluster "<your-cluster-name>" \
--zone "<your-cluster-zone>" \
--machine-type "n1-standard-4" \
--accelerator "type=nvidia-tesla-t4,count=1" \
--enable-autoscaling \
--min-nodes "0" \
--max-nodes "5" \
--node-taints "nvidia.com/gpu=present:NoSchedule" \
--node-labels "app-type=gpu-workloads"
运行此命令后,您会得到一个名为gpu-pool的节点池。它目前没有节点,但已准备好扩容至最多五个配备T4的节点。在此池中创建的任何节点都将自动被污点化,从而排斥没有正确容忍度的Pod。
Kubernetes本身不原生理解GPU是什么。它需要一个设备插件来发现并公开节点上的GPU硬件。NVIDIA GPU Operator是管理此过程的推荐方式,因为它会自动处理驱动安装、设备插件注册和监控组件。
如果您尚未安装,请添加NVIDIA Helm仓库并安装该操作符。
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo update
helm install gpu-operator nvidia/gpu-operator \
--wait \
--namespace gpu-operator \
--create-namespace
一旦操作符的Pod开始运行,任何带有NVIDIA GPU的节点都将自动被标记为nvidia.com/gpu=true,并且其GPU容量将作为名为nvidia.com/gpu的可分配资源对Kubernetes调度器可见。
现在,创建将触发扩容的工作负载。以下YAML清单定义了一个简单的Pod,它除了占用一个GPU外不执行任何操作。请注意两个重要部分:resources.limits用于请求GPU,以及tolerations用于允许它调度到我们污点化的节点上。
将此内容保存为gpu-test-pod.yaml。
apiVersion: v1
kind: Pod
metadata:
name: gpu-test-pod
spec:
restartPolicy: Never
containers:
- name: cuda-container
image: nvidia/cuda:11.4.2-base-ubuntu20.04
command: ["/bin/bash", "-c", "sleep 3600"] # 暂停1小时
resources:
limits:
nvidia.com/gpu: 1
tolerations:
- important: "nvidia.com/gpu"
operator: "Equal"
value: "present"
effect: "NoSchedule"
所有部分准备就绪后,应用清单并观察自动化过程。
部署Pod:
kubectl apply -f gpu-test-pod.yaml
观察Pod状态:
立即检查其状态。您将看到它处于Pending(待处理)状态。
kubectl get pods -w
# 初始输出将类似如下
# NAME READY STATUS RESTARTS AGE
# gpu-test-pod 0/1 Pending 0 2s
检查Pod事件:
为了理解它为何待处理,请描述该Pod。在Events(事件)部分,您将看到调度器发出的消息,指示它找不到合适的节点。
kubectl describe pod gpu-test-pod
您应该看到类似这样的事件:Warning FailedScheduling ... 0/X nodes are available: X node(s) had taints that the pod didn't tolerate. 这是预期的,也是集群自动扩缩器的触发条件。
检查集群自动扩缩器日志:
在另一个终端中,查看集群自动扩缩器部署的日志。您将看到它识别出待处理的Pod并触发gpu-pool的扩容。
# 查找自动扩缩器Pod
kubectl get pods -n kube-system | grep cluster-autoscaler
# 查看其日志
kubectl logs -f <cluster-autoscaler-pod-name> -n kube-system
查找包含Scale-up、pod gpu-test-pod triggered scale-up和... expanding node group .../gpu-pool from 0 to 1的行。
观察新节点出现:
在自动扩缩器日志运行的同时,观察您集群中的节点。gpu-pool中的一个新节点将会出现,最初处于NotReady(未就绪)状态,几分钟后会转换为Ready(就绪)状态。
kubectl get nodes -w
确认Pod调度:
一旦新节点就绪,Kubernetes调度器将自动把gpu-test-pod放置到该节点上。Pod的状态将从Pending(待处理)变为ContainerCreating(容器创建中),最终变为Running(运行中)。
该系统还处理缩容以节约成本。完成GPU工作负载后,请删除Pod。
kubectl delete -f gpu-test-pod.yaml
Pod删除后,新的GPU节点现在处于空闲状态。集群自动扩缩器将识别到这种资源利用不足的情况。在其配置的超时时间(通常为10分钟)过后,它将终止该节点并将gpu-pool缩容回零。您已成功创建了一个完全弹性、按需的GPU资源池。为避免本次练习产生任何额外费用,您还可以删除节点池本身。
# Example for GKE
gcloud container node-pools delete gpu-pool \
--cluster "<your-cluster-name>" \
--zone "<your-cluster-zone>"
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造