Одна из самых ожидаемых мной ИТ технологий это лёгкое прокидывание GPU внутрь виртуальной среды без выделения отдельной карты под эти цели. В принципе она появилась и имя ей - KVMGT. Осталось дождаться простоты использования её на десктопе. И хоть контейнеры иногда называют лёгкой виртуализацией, но внутри них может быть гостем только Linux система. В статье Стефана Грабера (Stéphane Graber) речь пойдёт о возможности внутри контейнера LXD использовать GPU хоста.
LXD поддерживает GPU passthrough, но реализовано совсем по-другому, чем вы ожидаете по аналогии с виртуальными машинами. Вместо проброса сырого PCI устройства (raw PCI device), есть хост-система со всеми необходимыми драйверами и внутрь контейнера передаются результирующие ноды устройства (device nodes).
В данной статье основное внимание уделено NVidia и её инструментарию CUDA, но технология проброса будет работать с любым GPU. Продукция NVidia просто именно то, что есть в данный момент на руках.
Тестовая система обладает двумя NVidia GT 730. Это дешёвые, малопроизводительные графические процессоры, которые обладают редким плюсом, что существуют в таких PCI картах, что прекрасно вписываются в один из доступных серверов и не требуют дополнительного питания. Для реальных нагрузок CUDA вам лучше подыскать что-то более серьёзное.
Нужно установить CUDA инструментарий и драйвера.
wget developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
sudo apt update
sudo apt install cuda
После перезагрузки нужно убедиться что NVidia GPU работают.
nvidia-smi
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 375.39 Driver Version: 375.39 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GT 730 Off | 0000:02:06.0 N/A | N/A | | 30% 30C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ | 1 GeForce GT 730 Off | 0000:02:08.0 N/A | N/A | | 30% 26C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | | 1 Not Supported | +-----------------------------------------------------------------------------+
и CUDA так же
/usr/local/cuda-8.0/extras/demo_suite/bandwidthTest
[CUDA Bandwidth Test] - Starting... Running on... Device 0: GeForce GT 730 Quick Mode Host to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 3059.4 Device to Host Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 3267.4 Device to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 30805.1 Result = PASS NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
Вначале создадим обычный контейнер с Ubuntu 16.04
lxc launch ubuntu:16.04 cuda
Creating cuda Starting cuda
Нужно установить демонстрационный инструмент CUDA
lxc exec cuda -- wget developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
lxc exec cuda -- dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
lxc exec cuda -- apt update
lxc exec cuda -- apt install cuda-demo-suite-8-0 --no-install-recommends
И пробуем на данном этапе выполнить
lxc exec cuda -- nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
Ошибка вполне ожидаема, так как мы не указывали LXD пробрасывать какой-либо GPU.
LXD позволяет указывать конкретные GPU по различным критериям.
Ключ | Тип | По умолч. | Требуется | Описание |
---|---|---|---|---|
vendorid | string | - | нет | id производителя GPU устройства. |
productid | string | - | нет | id продукта GPU устройства. |
id | string | - | нет | id карты GPU устройства |
pci | string | - | нет | адрес pci GPU устройства |
uid | int | 0 | нет | UID владельца устройства в контейнере |
gid | int | 0 | нет | GID владельца устройства в контейнере |
mode | int | 0660 | нет | права доступа к устройству внутри контейнера |
Вначале просто разрешим доступ ко всем GPU
lxc config device add cuda gpu gpu
Device gpu added to cuda
lxc exec cuda -- nvidia-smi
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 375.39 Driver Version: 375.39 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GT 730 Off | 0000:02:06.0 N/A | N/A | | 30% 30C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ | 1 GeForce GT 730 Off | 0000:02:08.0 N/A | N/A | | 30% 27C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | | 1 Not Supported | +-----------------------------------------------------------------------------+
lxc config device remove cuda gpu
Device gpu removed from cuda
Попробуем дать доступ к первому GPU в системе
lxc config device add cuda gpu gpu id=0
Device gpu added to cuda
lxc exec cuda -- nvidia-smi
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 375.39 Driver Version: 375.39 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GT 730 Off | 0000:02:06.0 N/A | N/A | | 30% 30C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | +-----------------------------------------------------------------------------+
lxc config device remove cuda gpu
Device gpu removed from cuda
Можно легко указать нужную карту по её идентификаторам (id) производителя (vendor) и устройства.
lspci -nnn | grep NVIDIA
02:06.0 VGA compatible controller [0300]: NVIDIA Corporation GK208 [GeForce GT 730] [10de:1287] (rev a1) 02:07.0 Audio device [0403]: NVIDIA Corporation GK208 HDMI/DP Audio Controller [10de:0e0f] (rev a1) 02:08.0 VGA compatible controller [0300]: NVIDIA Corporation GK208 [GeForce GT 730] [10de:1287] (rev a1) 02:09.0 Audio device [0403]: NVIDIA Corporation GK208 HDMI/DP Audio Controller [10de:0e0f] (rev a1)
lxc config device add cuda gpu gpu vendorid=10de productid=1287
Device gpu added to cuda
lxc exec cuda -- nvidia-smi
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 375.39 Driver Version: 375.39 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GT 730 Off | 0000:02:06.0 N/A | N/A | | 30% 30C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ | 1 GeForce GT 730 Off | 0000:02:08.0 N/A | N/A | | 30% 27C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | | 1 Not Supported | +-----------------------------------------------------------------------------+
lxc config device remove cuda gpu
Device gpu removed from cuda
Заметьте, что от предыдущей команды добавилось два GPU, так как они одинаковой модели и производителя. В нашем случае, для отбора карты лучше использовать PCI ID.
lxc config device add cuda gpu gpu pci=0000:02:08.0
Device gpu added to cuda
lxc exec cuda -- nvidia-smi
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 375.39 Driver Version: 375.39 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GT 730 Off | 0000:02:08.0 N/A | N/A | | 30% 27C P0 N/A / N/A | 0MiB / 2001MiB | N/A Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 Not Supported | +-----------------------------------------------------------------------------+
lxc config device remove cuda gpu
Device gpu removed from cuda
На прощание сверим результаты что мы получим внутри контейнера и что получали при измерении непосредственно в хост-системе.
lxc config device add cuda gpu gpu
Device gpu added to cuda
lxc exec cuda -- /usr/local/cuda-8.0/extras/demo_suite/bandwidthTest
[CUDA Bandwidth Test] - Starting... Running on... Device 0: GeForce GT 730 Quick Mode Host to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 3065.4 Device to Host Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 3305.8 Device to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 30825.7 Result = PASS NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
LXD может легко предоставить один или несколько GPU внутри контейнера. Можно выдавать конкретные GPU конкретным контейнерам или просто отдать их все. Нет никаких накладных расходов как в случае с PCI based passthrough. Работа контейнера с GPU похожа на обычные процессы хоста.
Тем не менее требуется, чтобы внутри контейнеров версия инструментария CUDA поддерживала версию драйверов NVidia, установленных в хосте.
Цикл из 12 статей Стефана про LXD.
Из свежего про LXD и LXC, который работает под капотом.