K8s集群GPU算力MiddlewareOps实战:从设备插件到监控告警
在Kubernetes集群里用上GPU算力,核心是三件事:节点能被调度器识别出nvidia.com/gpu资源、容器运行时能把GPU设备透传给Pod、监控能看清每张卡的利用率和显存占用。
只装驱动不做设备插件,kubectl describe node里就不会出现GPU资源,Pod会一直Pending。
本文按MiddlewareOps的常见落地顺序,把准备、部署、验证和排错串一遍。
适用环境与前置检查
这套流程适用于自建或云上的K8s集群,节点为NVIDIA GPU服务器,集群版本建议在1.20以上。
开始前先确认三件事。
- 节点能识别到GPU:执行
nvidia-smi,能看到显卡型号、驱动版本和显存容量。如果命令不存在,先装好NVIDIA驱动。 - K8s节点已加入集群:
kubectl get nodes显示Ready。 - 节点标签可用于区分GPU机器,例如给节点打标:
kubectl label nodes <节点名> gpu=true。
容器运行时方面,containerd和Docker都可以,但都要配置NVIDIA运行时。
以containerd为例,安装nvidia-container-toolkit后,在/etc/containerd/config.toml中确认存在nvidia运行时配置,然后重启containerd:systemctl restart containerd。
Docker环境则执行nvidia-ctk runtime configure --runtime=docker并重启Docker。
避坑: 驱动版本、CUDA版本和容器镜像里的CUDA版本要大致匹配。
镜像CUDA比驱动支持的版本高,容器内nvidia-smi可能报错或直接失败。
部署NVIDIA设备插件与算力上报
设备插件(Device Plugin)负责把节点上的GPU数量上报给kubelet,是GPU能被调度的前提。
官方提供DaemonSet方式部署。
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/main/deployments/static/nvidia-device-plugin.yml
部署后检查DaemonSet是否在每个GPU节点上跑起来:
kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds -o wide
kubectl describe node | grep -A3 -i gpu
预期结果是在节点的Allocatable里看到nvidia.com/gpu: 4(数量按实际卡数)。
如果看不到,先看插件Pod日志:kubectl logs -n kube-system <插件Pod名>,常见原因是运行时未配置nvidia或驱动未装好。
在Pod中申请GPU算力并验证
设备插件正常后,Pod通过resources字段申请GPU。
注意GPU是整数资源,不能写小数。
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
containers:
- name: cuda
image: nvidia/cuda:12.2.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
应用并查看结果:
kubectl apply -f gpu-test.yaml
kubectl logs gpu-test
日志里能打印出显卡信息,说明算力已成功透传。
如果Pod卡在Pending,用kubectl describe pod gpu-test看事件,常见提示是Insufficient nvidia.com/gpu,这时回到上一步确认节点资源是否真正上报。
算力监控与告警配置
只看单卡nvidia-smi不够,集群层面需要采集每张卡的利用率、显存、温度和功耗。
常用方案是dcgm-exporter配合Prometheus。
用Helm部署dcgm-exporter:
helm repo add gpu-helm-charts https://nvidia.github.io/dcgm-exporter/helm-charts
helm repo update
helm install dcgm-exporter gpu-helm-charts/dcgm-exporter -n monitoring
部署后确认Service和Pod正常,在Prometheus的抓取配置里加入dcgm-exporter的指标端点。
关键指标包括DCGM_FI_DEV_GPU_UTIL(利用率)、DCGM_FI_DEV_FB_USED(显存已用)和DCGM_FI_DEV_POWER_USAGE(功耗)。
告警规则可以这样写:
- alert: GPUUtilHigh
expr: DCGM_FI_DEV_GPU_UTIL > 90
for: 10m
labels:
severity: warning
annotations:
summary: "GPU利用率持续偏高"
验证方式是打开Prometheus的Graph页面查询DCGM_FI_DEV_GPU_UTIL,能返回数据即采集成功。
高频问题与排查方向
GPU相关故障大多集中在资源上报和运行时两处,按下面顺序排查效率更高。
- 节点看不到
nvidia.com/gpu:检查驱动、nvidia-container-toolkit和设备插件Pod三者是否都正常。 - Pod一直Pending:先看
kubectl describe pod事件,区分是资源不足还是节点亲和性没匹配上。 - 容器内
nvidia-smi报错:多为镜像CUDA版本高于驱动支持版本,换匹配的镜像或升级驱动。 - 多卡节点只上报一张卡:检查设备插件是否限制了卡数,或节点上是否有卡处于异常状态。
避坑: 不要用kubectl edit直接改设备插件的DaemonSet镜像版本,升级时按官方发布说明操作,避免运行时和插件版本不兼容。
涉及重启containerd或kubelet会短暂影响该节点上的业务,操作前确认节点可以排水。
验证清单与收尾
一套MiddlewareOps流程跑完后,用下面几项确认结果:节点Allocatable出现GPU资源、测试Pod能打印nvidia-smi、Prometheus能查到dcgm指标、告警规则处于生效状态。
四项都通过,说明K8s集群的GPU算力已经可调度、可观测。
后续如果新增GPU节点,重复驱动、运行时和节点标签三步即可,设备插件会自动在新节点上拉起。
常见疑问
GPU资源可以像CPU那样申请0.5吗?
一般不行,nvidia.com/gpu按整卡分配。需要共享算力要另用MIG或时间片方案,配置复杂度更高,建议先跑通整卡再考虑。
设备插件升级会不会影响正在运行的Pod?
升级DaemonSet会重建插件Pod,已运行的GPU Pod通常不受影响,但期间新调度可能短暂受阻,建议在业务低峰操作。
没有Prometheus还能看GPU监控吗?
可以先用nvidia-smi和dcgm-exporter自带的指标端点临时查看,但告警和长期趋势还是需要时序数据库支撑。