在当今的高性能计算和机器学习领域,GPU(图形处理单元)因其卓越的并行计算能力而扮演着至关重要的角色。随着容器化技术如 Docker 的普及,越来越多的数据科学家和开发者选择将他们的应用和工作负载封装到 Docker 容器中,以实现更便捷的开发、测试和部署流程。然而,默认情况下,Docker 容器是无法自动识别或利用宿主机上的 NVIDIA GPU 资源的。这一限制可能会导致那些依赖于 GPU 加速的工作负载性能大幅下降,甚至完全无法运行。
为了打破这种隔离,使得容器内的应用程序可以像在裸机上一样使用 GPU,接下来我们一起来探索,开启容器对 NVIDIA GPU 的访问之旅。
1.安装 NVIDIA 驱动程序
Nvidia官网下载驱动程序: https://www.nvidia.cn/drivers/lookup/
wget https://cn.download.nvidia.com/XFree86/Linux-x86_64/550.120/NVIDIA-Linux-x86_64-550.120.run
安装过程中会出现:
he distribution-provided pre-install script failed! Are you sure you want to continue? 选择 yes 继续。
Would you like to register the kernel module souces with DKMS? This will allow DKMS to automatically build a new module, if you install a different kernel later? 选择 no 继续。
Would you like to run the nvidia-xconfigutility to automatically update your x configuration so that the NVIDIA x driver will be used when you restart x? Any pre-existing x confile will be backed up。选择 yes 继续。
安装成功后,reboot 重启,输入nvidia-smi 查看。
2.安装 CUDA Toolkit
CUDA Toolkit 是 NVIDIA 提供的一套全面的开发工具,旨在帮助开发者创建、优化和部署基于 CUDA 的应用程序。它为利用 GPU 进行加速计算提供了必要的基础设施和支持,使得开发者可以充分利用 NVIDIA GPU 的并行处理能力来加速各种计算密集型任务。
https://developer.nvidia.com/cuda-toolkit-archive
NVIDIA驱动版本与CUDA版本对应关系查看: https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
3.安装
NVIDIA Container Toolkit
NVIDIA Container Toolkit 是一个专为构建和运行利用 GPU 加速的容器而设计的强大工具集。它通过集成到 Docker 引擎中,自动配置容器以支持 NVIDIA GPU,从而简化了 GPU 支持的容器化应用的部署与管理。
该工具包包括一个容器运行时库和一系列实用程序,能够自动处理与 NVIDIA GPU 交互的复杂性。当启动一个配置了 --gpus
选项的容器时,NVIDIA Container Toolkit 会自动将必要的 GPU 设备文件挂载到容器内,并设置相应的环境变量,使应用程序可以直接访问 GPU 资源。
Make sure you have installed the NVIDIA driver for your Linux Distribution Note that you do not need to install the CUDA Toolkit on the host system, but the NVIDIA driver needs to be installed。
https://github.com/NVIDIA/nvidia-container-toolkit
截至 2024/04/08 ,nvidia-container-runtime 已经废弃了,现在叫 nvidia-container-toolkit
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
依赖关系如下,version 是指 NVIDIA Container Toolkit 版本:
例如下面是官方文档的图,它是如何和 docker 工作的。
3.1.安装容器
工具包
curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | \sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
sudo yum install -y nvidia-container-toolkit
3.2.配置容器运行时
-
使用
nvidia-ctk
命令配置:
sudo nvidia-ctk runtime configure --runtime=docker
The nvidia-ctk
command modifies the /etc/docker/daemon.json
file on the host. The file is updated so that Docker can use the NVIDIA Container Runtime.
{"default-runtime": "nvidia","runtimes": {"nvidia": {"path": "/usr/bin/nvidia-container-runtime","runtimeArgs": []}}
-
重启 Docker 守护进程
sudo systemctl restart docker
-
验证配置
docker run --rm --gpus all nvidia/cuda:11.4.0-base-ubuntu20.04 nvidia-smi
4.K8S如何使用GPU
k8s 需要部署 NVIDIA 的 device plugin ,会 daemonset 起一个服务挂载宿主机 /var/lib/kubelet/device-plugins/
目录,然后在目录下生成 socket 文件,kubelet 和这个 socket 文件按照 device plugin 要求 grpc 调用,部署去看官方的 github 部署。
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.13.0/nvidia-device-plugin.yml
确保 Kubernetes 集群中已安装 NVIDIA Device Plugin。
kubectl get pods -n kube-system kubectl logs nvidia-device-plugin-daemonset-hzldk -n kube-system
-
kubectl describe node ?
-
新建
gpu-pod.yaml
并部署
apiVersion: v1
kind: Pod
metadata:name: gpu-pod
spec:restartPolicy: OnFailurecontainers:- name: cuda-vector-addimage: "nvidia/samples:vectoradd-cuda10.2"resources:limits:nvidia.com/gpu: 1requests:nvidia.com/gpu: "1"
kubectl apply -f gpu-pod.yaml
-
kubectl describe pod gpu-pod
-
kubectl logs gpu-pod
在 Kubernetes (K8s) 中,GPU 资源的管理通常依赖于设备插件(Device Plugin),它使得 GPU 可以作为扩展资源被调度。然而,默认情况下,Kubernetes 对于 GPU 的资源请求和限制只支持整数级别的分配,即你只能请求整个 GPU 或者不请求。这意味着如果你想要更细粒度地控制 GPU 资源,例如只分配一部分显存或计算核心给某个容器,就需要采取额外的措施。
这个简单介绍一种方法,HAMi 是一个开源的 vGPU 方案,它可以实现对 GPU core 和 memory 使用 1% 级别的隔离,确保共享同一 GPU 的各个 Pod 都能获得足够的资源。
通过 HAMi,你可以为每个 Pod 指定具体的 GPU 显存量和核心数量,从而更好地利用 GPU 资源。具体来说,你可以修改 Pod 的 YAML 文件,在 resources
字段中添加 gpu-mem
和 gpu-count
这样的扩展资源。
apiVersion: v1
kind: Pod
metadata:name: gpu-pod
spec:containers:- name: ubuntu-containerimage: ubuntu:18.04command: ["bash", "-c", "sleep 86400"]resources:limits:nvidia.com/gpu: 1gpu-mem: "2048Mi" # 限制显存为2GBrequests:nvidia.com/gpu: 1gpu-mem: "2048Mi" # 请求显存为2GB