服务器K8s集群GPU算力接入GitOps:从设备插件到自动同步
在K8s集群里使用GPU算力,核心链路是宿主机驱动、容器运行时、设备插件和调度器四层配合;
把这条链路交给GitOps管理,就是让GPU相关配置以声明文件形式存放在Git仓库,由Argo CD这类工具自动同步到集群。
本文按这个思路讲清从准备到验证的完整过程,适合已经有一套可用的K8s集群、希望把GPU节点纳入统一发布流程的运维人员。
开始之前要满足的条件
GPU算力能不能被Pod用上,取决于底层环境是否就绪。
动手前先确认这几项:
- 集群版本可用,kubectl能正常连接,节点处于Ready状态。
- GPU节点已安装与显卡型号匹配的NVIDIA驱动,执行
nvidia-smi能看到显卡信息和驱动版本。 - 容器运行时已配置为使用NVIDIA容器运行时,Docker环境对应
nvidia-container-toolkit,containerd环境需要在配置文件里挂载对应的runtime。 - 集群已具备Git仓库和Argo CD(或其他GitOps控制器),并有一个用于存放平台组件的目录。
如果驱动或运行时没配好,后面设备插件会一直报找不到设备,先解决底层再继续。
让K8s识别GPU的两步配置
安装NVIDIA设备插件
设备插件的作用是把宿主机上的GPU以nvidia.com/gpu这种扩展资源的形式上报给Kubernetes。
推荐用DaemonSet方式部署,并只调度到带GPU标签的节点:
kubectl create namespace gpu-operator
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/main/deployments/static/nvidia-device-plugin.yml
部署后检查Pod是否在每个GPU节点上运行:
kubectl get pods -n gpu-operator -o wide
kubectl describe node | grep -A5 "Capacity"
如果Capacity里出现nvidia.com/gpu: 1(数量与物理卡数一致),说明算力已经暴露给调度器。
用GitOps管理这份配置
直接把kubectl apply写进脚本不利于审计和回滚。
更稳妥的做法是把设备插件、命名空间、标签相关的YAML放进Git仓库,例如目录结构:
platform/gpu/
namespace.yaml
device-plugin.yaml
node-label.yaml
然后在Argo CD中创建一个Application指向该目录,开启自动同步:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gpu-stack
namespace: argocd
spec:
project: default
source:
repoURL: https://git.example.com/ops/platform.git
targetRevision: main
path: platform/gpu
destination:
server: https://kubernetes.default.svc
namespace: gpu-operator
syncPolicy:
automated:
prune: true
selfHeal: true
提交后Argo CD会自动把仓库里的状态同步到集群。
之后新增GPU节点,只要给节点打上标签并让DaemonSet覆盖到,算力就会自动纳入管理。
验证GPU算力是否真正可用
配置完成不等于能跑任务,用一个最小Pod做端到端验证:
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
containers:
- name: cuda
image: nvidia/cuda:12.0.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
restartPolicy: Never
应用后查看日志,如果nvidia-smi正常输出显卡信息,说明从调度到运行时的整条链路是通的。
kubectl apply -f gpu-test.yaml
kubectl logs gpu-test
同时可以在Argo CD界面确认Application状态为Synced和Healthy,表示Git中的期望状态与集群实际状态一致。
容易踩坑的几个地方
- 驱动与运行时版本不匹配:设备插件日志里出现
no devices found时,先确认容器运行时是否真的调用了NVIDIA runtime,而不是只看驱动装没装。 - 没有给节点打标签:DaemonSet如果带了nodeSelector,节点缺少对应标签就不会部署,Capacity里自然看不到GPU资源。
- GitOps同步范围过大:把整个集群交给一个Application管理,误删或误改的影响面会很大。建议按命名空间或组件拆分,GPU相关配置单独一个目录。
- prune策略误删资源:开启
prune: true后,从Git删除的文件会同步删除集群资源。对设备插件这类基础组件,先确认仓库内容完整再开启自动清理。 - 多卡节点资源申请写错:
nvidia.com/gpu只支持整数申请,写小数或超量会被调度器拒绝,表现为Pod一直Pending。
常见疑问
GPU节点扩容后需要手动做什么?
通常只需要给新节点装好驱动和运行时、打上标签,DaemonSet会自动部署设备插件,GitOps会保持其余配置一致。
GitOps工具能管理GPU驱动本身吗?
驱动安装涉及内核模块和重启,多数场景更适合放在节点初始化流程里,GitOps负责管理K8s层面的设备插件和调度配置。
怎么判断问题出在集群还是驱动?
先用nvidia-smi在宿主机确认驱动正常,再看设备插件日志和节点Capacity,逐层缩小范围。
把GPU算力接入GitOps的价值在于配置可追溯、变更可回滚。
先保证驱动、运行时、设备插件这条链路通畅,再用Git仓库和Argo CD接管声明文件,最后通过一个申请GPU的最小Pod验证结果。
遇到异常时按宿主机驱动、设备插件日志、节点资源上报的顺序排查,基本能定位到具体环节。