K8s集群GPU算力调度配置与IOSOps运维实践
在Kubernetes集群里使用GPU算力,核心要做三件事:节点装好NVIDIA驱动、部署GPU设备插件、在Pod里声明nvidia.com/gpu资源。
完成这三步后,调度器才能把需要GPU的工作负载分配到有显卡的节点上。
下面按零基础可执行的顺序讲清楚准备、操作、避坑和验证。
环境前提与节点准备
先确认硬件和系统条件,避免装到一半发现不兼容。
- 服务器必须装有NVIDIA GPU,且BIOS中已启用Above 4G Decoding和PCIe相关选项。
- 操作系统建议使用主流Linux发行版,内核版本与NVIDIA驱动要求匹配。
- 集群已正常运行,
kubectl get nodes能列出所有节点。 - 需要给GPU节点打标签,方便后续调度定向。
给节点打标签的命令示例:
kubectl label nodes hardware-type=gpu
kubectl get nodes --show-labels | grep gpu
预期结果是目标节点出现hardware-type=gpu标签。
如果没有标签,后续Pod可能被调度到无GPU节点上。
安装驱动与GPU设备插件
GPU节点需要先有可用的NVIDIA驱动,再部署设备插件。
第一步,在GPU节点安装驱动。
不同发行版方式不同,以常见做法为例:
# 查看显卡是否被系统识别
lspci | grep -i nvidia
# 确认驱动是否已加载
nvidia-smi
如果nvidia-smi能输出显卡型号和驱动版本,说明驱动可用。
若报错,需要先安装匹配的驱动并重启节点。
第二步,部署NVIDIA设备插件。
推荐用DaemonSet方式:
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/main/nvidia-device-plugin.yml
kubectl get pods -n kube-system | grep nvidia
插件Pod处于Running状态后,节点会暴露GPU资源。
验证命令:
kubectl describe node | grep nvidia.com/gpu
如果看到nvidia.com/gpu: 1或对应卡数,说明GPU已被集群识别。
在Pod中申请GPU算力
声明GPU资源时,注意GPU不支持超卖,requests和limits必须相等。
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
containers:
- name: cuda
image: nvidia/cuda:12.0-base
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
创建后查看日志:
kubectl apply -f gpu-test.yaml
kubectl logs gpu-test
日志中出现显卡信息,说明GPU算力已成功分配给Pod。
IOSOps场景下的运维要点
iOS持续集成、自动化测试或构建任务常需要GPU加速,这类场景在K8s上要注意几点:
- 构建镜像内要包含与宿主机兼容的CUDA运行时,避免驱动版本冲突。
- 用节点亲和性把任务固定到GPU节点,减少调度等待。
- 给GPU任务设置合理的超时和清理策略,防止长期占用算力。
节点亲和性配置片段:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: hardware-type
operator: In
values: ["gpu"]
常见报错与避坑
- Pod一直Pending:先用
kubectl describe pod看事件,常见原因是节点没有可分配GPU或资源被占满。 - 插件Pod崩溃:检查驱动是否加载、
/dev/nvidia*设备是否存在。 - 容器内
nvidia-smi找不到:镜像缺少CUDA工具,或运行时未正确挂载设备。 - 驱动升级后GPU消失:升级驱动需要重启节点并重新确认插件状态。
避坑重点:不要在没装驱动的节点上直接部署插件;
不要给GPU资源设置小于limits的requests;
生产环境升级驱动前先做节点排水。
效果验证与收尾
完整验证顺序:节点有标签、nvidia-smi正常、插件Running、节点资源显示GPU、测试Pod日志输出显卡信息。
五项都通过,说明K8s集群GPU算力已可用。
如果用于IOSOps流水线,建议再用一个真实构建任务跑通,确认算力分配和任务回收都符合预期。
遇到异常时,优先回看插件状态和节点资源描述,多数问题能在这一步定位。