部署带有 NVIDIA GPU 加速支持的 Kubernetes 节点
由于最近工作需要,所以学习了一下简单部署一个单节点K8s 并添加 GPU 支持的方式。 Kuebernetes(K8s) 是一个 Google 公司开源的主要用于自动化部署、自动缩扩容的容器集群系统。这次因为只需要单节点,为了方便,笔者选了 K3s 作为实现。K3s 实现了几乎所有 K8s 的主要功能,并且只需要一个单可执行文件。使用方法和 K8s 没有区别,但是内存占用更小,速度更快。
这次的主机环境选择了Ubuntu 22.04,并使用570.173.x 的驱动版本。
Warning本文系完成工作后脱机回忆过程并参考文档、历史记录和 AI 复现的过程,实际尝试过程曲折复杂,因此本文可能有偏差和错误。若发现问题,欢迎评论区指出纠正!
环境部署:安装驱动
Warning本文假设要进行作业的系统是完全纯净的、未安装桌面环境的操作系统,若已自动安装驱动、已安装开源驱动或其他版本驱动,在开始前需要手动全部清理干净。
要在Ubuntu22.04系统中添加NVIDIA驱动支持,有两种方式:
- 前往官网下载
.run
包执行 - 使用apt 直接安装
Warning注意两种安装方式是有区别的,直接下载执行
.run
包,你的版本最新,但是类似LibGL.so
等文件的软链接需要手动操作,后续更新也需要手动进行。而使用 apt 安装则不必手动进行链接和维护,但是apt 版本有可能不是最新的,这会影响后续容器部署,因为如果你使用类似nvidia/cuda:12.8.1-base-ubuntu22.04
这样的基底镜像,自带的驱动很有可能和你宿主机的不同,导致容器里无法识别 GPU 设备。在撰写本文时,笔者就遇到了下载到570.173.x
的.run
包,但是apt 却只能找到570.160.x
的包导致出现问题的情况。
方法1:下载.run
包执行
前往英伟达官网搜索你所使用的设备,并下载.run
包。
Important若要使用企业级功能(如官方支持的
vGPU
),请前往企业驱动门户登录企业账户,下载专用的-grid
结尾的.run
驱动包。此驱动不能和常规驱动共存,是互斥的。
.run
文件是一个可执行文件,下载后为其赋予执行权限,并运行即可:
sudo chmod +x NVIDIA-Linux-x86_64-[version].run
sudo ./NVIDIA-Linux-x86_64-[version].run
等待执行完毕即可。
方法2:使用软件包管理器apt安装
使用这种方式,你需要先添加仓库:
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
然后,执行安装:
sudo apt install nvidia-driver-570
Tip为了方便测试和使用,你可能还需要安装其他附加的组件,例如 glxinfo。
Warning若要在当前设备直接渲染内容,你可能还需要检查LibGL.so 的指向是否是英伟达驱动中的库。
安装驱动后
无论使用何种方式安装,都建议在安装后重启一次系统。随后,可以通过nvidia-smi
检查结果。
Important如果还要安装 Mesa 虚拟驱动包,请注意一定要先安装 Mesa 再安装驱动,因为 Mesa 会覆盖 NVIDIA 驱动的一些设定,导致默认走虚拟驱动。
环境部署:安装 K3s
K3s本体
K3s 的部署比较简单,只需要一行命令:
curl -sfL https://get.k3s.io | sh -
Tip国内加速:
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
更多信息请查阅官方文档。
Warning默认情况下,由于 K3s 默认安装的鉴权文件和K8s 不同,如果不手动链接,则需要配置
KUBECONFIG
环境变量到对应路径/etc/rancher/k3s/k3s.yaml
。如果这个文件无权访问,你可能还需要使用 sudo 命令。如果环境变量设置在当前用户,可以在 sudo 命令后添加-E
参数保留环境变量到 sudo 环境。
Tip可能还有一些其他必须的插件例如
cni
,需要手动安装来提供部分功能。
Helm
Helm 是一个为 K8s 设计的插件管理系统,快速部署一些预设功能时最常用的工具。安装的方式也比较简单:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
环境部署:安装nvidia-container-toolkit
nvidia-container-toolkit 是 NVIDIA 为容器运行时准备的一套显卡工具包,配置后允许在容器内调用显卡能力。具体设置方法可以参考下文和官方文档。
安装
首先添加官方存储库
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
更新软件源
sudo apt-get update
安装工具包:
export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.17.8-1
sudo apt-get install -y \
nvidia-container-toolkit=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
nvidia-container-toolkit-base=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
libnvidia-container-tools=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
libnvidia-container1=${NVIDIA_CONTAINER_TOOLKIT_VERSION}
Warning请修改上方版本号为要安装的版本。
配置
安装后还需要让所用的容器运行时使用nvidia-container-toolkit 才行。
sudo nvidia-ctk runtime configure --runtime=containerd --set-as-default
# 输出类似 “Updated /etc/containerd/config.toml” 即可
sudo systemctl restart containerd
确认K3s 可以找到nvidia-container-toolkit:
grep nvidia /var/lib/rancher/k3s/agent/etc/containerd/config.toml
# 出现 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] 即 OK
创建 RuntimeClass(供 Pod 显式调用)
# nvidia-runtimeclass.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia
handler: nvidia
kubectl apply -f nvidia-runtimeclass.yaml
Tip你可能需要sudo 来执行命令,取决于前文中你是否对鉴权文件进行处理。
环境部署:安装 gpu-operator
gpu-operator 是 NVIDIA 提供的给K8s 用的一体式 GPU 管理工具,能够很好的控制Pod 访问GPU 的能力。可以参考官网文档安装:
kubectl create ns gpu-operator
kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
&& helm repo update
helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v25.3.0
后续
到此,应该能看到相关 Pod 已经跑起来了。给一个小提示,如果没有在容器计算 CUDA 的需求,容器内可以直接使用ubuntu:22.04
镜像,而不需要nvidia/cuda
镜像。必要的驱动,会从gpu-operator 自动挂载。