Incus 和 Podman 作为容器化方案,都支持挂载显卡让容器内应用能够使用 CUDA 进行加速。不过两者具体的操作方式有所不同,交换的东西也不一样,需要根据实际情况进行取舍。
Incus
Incus 的操作方法在docker in incus with cuda一文有所介绍,不过在这里再总结一下。
在incus config edit <容器名>的config:和device:中,需要有以下配置来利用 nvidia-container-toolkit 自动挂载驱动和库、挂载 pci bus 到容器:
1 | config: |
其中 pci: 的值用 nvidia-smi 来找,例子参见挂载 GPU PCI Bus 目录到容器。同时需要在容器内用一个 systemd service unit 来把 PCI Bus 链接一份到 /proc/driver/nvidia,前面这个链接中有详细介绍。
上述部署完成之后,地基就已经打好了。根据 distribution 的不同可能还需要在容器内安装运行时的库才能让应用成功跑起来,但是这里就不具体介绍了。
不过在我的服务器上,开机时这个容器是启动不起来的,必须要在 host 跑一次 nvidia-smi 才能启动。
Podman (Quadlet)
相比起 Incus 配置上的复杂,podman 和 quadlet 就简单许多了。podman run 只需要加一个参数: --gpus all。Quadlet则是在[Container]中加一行AddDevice=nvidia.com/gpu=all就行了。以 Jellyfin 为例:
1 | [Unit] |
取舍
Podman 虽然方便,但它是 Application Container,容器的环境是以镜像为基础、半永久的——每次 pull 新 image 之后,之前对容器环境的变更都会丢失。出于个人习惯,在跑大型应用比如 gitlab 的时候,我就不太喜欢用 Application Container 因为定制起来太麻烦了。
Incus 作为 System Container 则是另一个极端,对环境的定制非常方便,但是配置环境就需要花费很多精力,对于某些应用则会有“水土不服”的问题——比如 Jellyfin 就经常资料库卡住。