![]()
Publicado originalmente en jocke.no
También con información de theorangeone.net
Host de Proxmox
El primer paso es instalar los controladores en el sistema anfitrión. Nvidia cuenta con un repositorio oficial de Debian que podríamos usar. Sin embargo, esto presenta un problema potencial: necesitamos instalar los controladores en el contenedor LXC posteriormente, sin módulos del kernel. No encontré la manera de hacerlo usando los paquetes del repositorio oficial de Debian, por lo que tuve que instalar los controladores manualmente dentro del contenedor LXC. Otro aspecto importante es que tanto el sistema anfitrión como el contenedor LXC deben ejecutar la misma versión del controlador (de lo contrario, no funcionará). Si instalamos usando el repositorio oficial de Debian en el sistema anfitrión e instalamos manualmente el controlador en el contenedor LXC, podríamos terminar fácilmente con versiones diferentes (cada vez que ejecutemos `apt upgrade` en el sistema anfitrión). Para lograr la mayor consistencia posible, instalaremos el controlador manualmente tanto en el sistema anfitrión como dentro del contenedor LXC.
echo -e "blacklist nouveau\noptions nouveau modeset=0" > /etc/modprobe.d/blacklist-nouveau.conf
update-initramfs -u
reboot
Instala las cabeceras PVE que coincidan con tu kernel actual.
apt install pve-headers-$(uname -r)
Descargar e instalar el controlador de Nvidia
Nota: La versión 520.56.06 era la más reciente al momento de escribir este documento; sin embargo, consulte https://download.nvidia.com/XFree86/Linux-x86_64/ para obtener controladores más recientes.
Responda «no» cuando le pregunte si desea instalar controladores de compatibilidad de 32 bits.
Responda «no» cuando le pregunte si debe actualizar la configuración X.
wget -O NVIDIA-Linux-x86_64.run https://download.nvidia.com/XFree86/Linux-x86_64/520.56.06/NVIDIA-Linux-x86_64-520.56.06.run
chmod +x NVIDIA-Linux-x86_64.run
./NVIDIA-Linux-x86_64.run --check
./NVIDIA-Linux-x86_64.run
Una vez instalados los controladores, debemos añadir algunas reglas udev. Esto garantiza que se carguen los módulos del kernel adecuados y que se creen todos los archivos de dispositivo necesarios al arrancar el sistema.
Agregar módulos del kernel
echo -e '\n# load nvidia modules\nnvidia\nnvidia_uvm\nnvidia-drm\nnvidia-uvm' >> /etc/modules-load.d/modules.conf
Una vez hecho esto, tendrás que actualizar el initramfs.
update-initramfs -u -k all.
Añade lo siguiente a /etc/udev/rules.d/70-nvidia.rules. Esto creará los archivos de dispositivo correspondientes en /dev/ durante el arranque.
nano /etc/udev/rules.d/70-nvidia.rules
KERNEL=="nvidia", RUN+="/bin/bash -c '/usr/bin/nvidia-smi -L && /bin/chmod 666 /dev/nvidia*'"
KERNEL=="nvidia_uvm", RUN+="/bin/bash -c '/usr/bin/nvidia-modprobe -c0 -u && /bin/chmod 0666 /dev/nvidia-uvm*'"
SUBSYSTEM=="module", ACTION=="add", DEVPATH=="/module/nvidia", RUN+="/usr/bin/nvidia-modprobe -m"
Para evitar que el controlador/módulo del kernel se descargue cuando la GPU no se utilice, debemos ejecutar el servicio de persistencia proporcionado por Nvidia . Este servicio estará disponible tras la instalación del controlador.
Copiar y extraer
cp /usr/share/doc/NVIDIA_GLX-1.0/samples/nvidia-persistenced-init.tar.bz2 .
bunzip2 nvidia-persistenced-init.tar.bz2
tar -xf nvidia-persistenced-init.tar
Retire las piezas antiguas, si las hubiera (para evitar un servicio enmascarado).
rm /etc/systemd/system/nvidia-persistenced.service
Instalar
chmod +x nvidia-persistenced-init/install.sh
./nvidia-persistenced-init/install.sh
Comprueba que esté bien.
systemctl status nvidia-persistenced.service
rm -rf nvidia-persistenced-init*
Si has llegado hasta aquí sin ningún error, ya puedes reiniciar el host Proxmox. Tras el reinicio, deberías ver la siguiente información (el tipo/información de la GPU, por supuesto, cambiará dependiendo de tu GPU);
nvidia-smi
Producción
Wed Feb 23 01:34:17 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 520.56.06 Driver Version: 520.56.06 CUDA Version: 11.8 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA RTX A2000 On | 00000000:82:00.0 Off | Off |
| 30% 36C P2 4W / 70W | 1MiB / 6138MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
systemctl status nvidia-persistenced.service
Producción
● nvidia-persistenced.service - NVIDIA Persistence Daemon
Loaded: loaded (/lib/systemd/system/nvidia-persistenced.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2022-02-23 00:18:04 CET; 1h 16min ago
Process: 9300 ExecStart=/usr/bin/nvidia-persistenced --user nvidia-persistenced (code=exited, status=0/SUCCESS)
Main PID: 9306 (nvidia-persiste)
Tasks: 1 (limit: 154511)
Memory: 512.0K
CPU: 1.309s
CGroup: /system.slice/nvidia-persistenced.service
└─9306 /usr/bin/nvidia-persistenced --user nvidia-persistenced
Feb 23 00:18:03 foobar systemd[1]: Starting NVIDIA Persistence Daemon...
Feb 23 00:18:03 foobar nvidia-persistenced[9306]: Started (9306)
Feb 23 00:18:04 foobar systemd[1]: Started NVIDIA Persistence Daemon.
root@foobar:~# ls -alh /dev/nvidia*
crw-rw-rw- 1 root root 195, 0 Feb 23 00:17 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Feb 23 00:17 /dev/nvidiactl
crw-rw-rw- 1 root root 195, 254 Feb 23 00:17 /dev/nvidia-modeset
crw-rw-rw- 1 root root 511, 0 Feb 23 00:17 /dev/nvidia-uvm
crw-rw-rw- 1 root root 511, 1 Feb 23 00:17 /dev/nvidia-uvm-tools
Si nvidia-smi muestra la GPU correcta, el servicio de persistencia funciona correctamente y los cinco archivos están disponibles, estamos listos para proceder al contenedor LXC.
contenedor LXC
Necesitamos añadir la configuración LXC pertinente a nuestro contenedor. Apague el contenedor LXC y realice los siguientes cambios en el archivo de configuración LXC;
Edita el archivo /etc/pve/lxc/1xx.conf y añade lo siguiente:
lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 509:* rwm
lxc.cgroup2.devices.allow: c 511:* rwm
lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file
Los números en las líneas de cgroup2 provienen de la quinta columna de la lista de dispositivos anterior (obtenida con `ls -alh /dev/nvidia*`). En mi caso, los dos archivos nvidia-uvm cambian aleatoriamente entre 509 y 511, mientras que los otros tres permanecen estáticos en 195. Desconozco el motivo de esta alternancia (si sabes cómo establecerlos en un valor fijo, te agradecería que me lo indicaras), pero LXC no muestra ningún error al configurar números que no existen (es decir, podemos añadir los tres para comprobar que funciona).
Ahora podemos activar el contenedor LXC y estaremos listos para instalar el controlador de Nvidia. Esta vez lo instalaremos sin los controladores del kernel, por lo que no es necesario instalar las cabeceras del kernel.
Responda «no» cuando le pregunte si debe actualizar la configuración X.
wget -O NVIDIA-Linux-x86_64.run https://download.nvidia.com/XFree86/Linux-x86_64/520.56.06/NVIDIA-Linux-x86_64-520.56.06.run
chmod +x NVIDIA-Linux-x86_64.run
./NVIDIA-Linux-x86_64.run --check
./NVIDIA-Linux-x86_64.run --no-kernel-module
En este punto, ya debería poder reiniciar su contenedor LXC. Verifique que los archivos y el controlador funcionen correctamente antes de continuar con la configuración de Docker.
ls -alh /dev/nvidia*
Producción
crw-rw-rw- 1 root root 195, 0 Feb 23 00:17 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Feb 23 00:17 /dev/nvidiactl
crw-rw-rw- 1 root root 195, 254 Feb 23 00:17 /dev/nvidia-modeset
crw-rw-rw- 1 root root 511, 0 Feb 23 00:17 /dev/nvidia-uvm
crw-rw-rw- 1 root root 511, 1 Feb 23 00:17 /dev/nvidia-uvm-tools
Ejecutar nvidia-smi
nvidia-smi
Producción
Wed Feb 23 01:50:15 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 520.56.06 Driver Version: 520.56.06 CUDA Version: 11.8 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA RTX A2000 Off | 00000000:82:00.0 Off | Off |
| 30% 34C P8 10W / 70W | 3MiB / 6138MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
contenedor Docker
Ahora podemos proceder a configurar Docker. Usaremos docker-compose y nos aseguraremos de tener la última versión eliminando las versiones de Docker y docker-compose proporcionadas por Debian. También instalaremos el entorno de ejecución de Docker proporcionado por Nvidia . Ambos son necesarios para que la GPU esté disponible en Docker.
Eliminar paquetes proporcionados por Debian
apt remove docker-compose docker docker.io containerd runc
Instala Docker desde el repositorio oficial
apt update
apt install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install docker-ce docker-ce-cli containerd.io
Instalar docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Instalar la función de autocompletado de docker-compose bash
curl \
-L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \
-o /etc/bash_completion.d/docker-compose
Instalar nvidia-docker2
apt install -y curl
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
keyring_file="/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg"
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o ${keyring_file}
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sed "s#deb https://#deb [signed-by=${keyring_file}] https://#g" | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
apt update
apt install nvidia-docker2
Reinicia systemd + docker (si no recargas systemd, puede que no funcione).
systemctl daemon-reload
systemctl restart docker
Ahora deberíamos poder ejecutar contenedores Docker con soporte para GPU. Vamos a probarlo.
docker run --rm --gpus all nvidia/cuda:11.8.0-devel-ubuntu22.04 nvidia-smi
Producción
Tue Feb 22 22:15:14 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 520.56.06 Driver Version: 520.56.06 CUDA Version: 11.8 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA RTX A2000 Off | 00000000:82:00.0 Off | Off |
| 30% 29C P8 4W / 70W | 1MiB / 6138MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
Probando que todo funciona
Una forma sencilla de comprobar que todo funciona es añadir un contenedor FileFlows.
nano docker-compose.yml
version: '3.7'
services:
fileflows:
image: revenz/fileflows
container_name: fileflows
runtime: nvidia
stdin_open: true # docker run -i
tty: true # docker run -t
environment:
- TZ=Pacific/Auckland
- TempPathHost=/temp
- NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
- NVIDIA_VISIBLE_DEVICES=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /mnt/docker/fileflows/data:/app/Data
- /mnt/docker/fileflows/logs:/app/Logs
- /mnt/docker/fileflows/temp:/temp
ports:
- 19200:5000
restart: unless-stopped
Ejecutar el contenedor
docker-compose up
Luego, ejecuta una prueba de ffmpeg para NVIDIA.
ffmpeg -loglevel error -f lavfi -i color=black:s=1920x1080 -vframes 1 -an -c:v hevc_nvenc -f null -
Si el comando se ejecuta sin errores, ¡todo funciona correctamente!

