Запуск контейнеров на суперкомпьютере - Apptainer
Apptainer (Singularity) — это свободная платформа контейнеризации, созданная для суперкомпьютеров (HPC) и научных вычислений. Она позволяет запускать программы со всеми зависимостями в изоляции, но в отличие от Docker, дает обычным пользователям запускать контейнеры без прав суперпользователя (root), обеспечивая безопасность на общих серверах. |
Ключевые особенности:
- Совместимость с Docker, может запускать и конвертировать готовые образы из Docker Hub.
- Весь контейнер сохраняется в виде одного файла с расширением .sif, который просто копировать и переносить.
- Интеграция устройств поверх изоляции, позволяющая подключать GPU, вычислительную сеть и параллельные файловые системы.
- Простая и эффективная модель безопасности: пользователь и группа внутри контейнера совпадают с теми, с которыми контейнер был запущен.
Официальный сайт: https://apptainer.org
Версии на суперкомпьютерном комплексе:
module load apptainer/1.5.0 # рекомендуемая
Работа с контейнерами на суперкомпьютере
Подготовка образа
1. Скачать готовый образ из любого публичного или приватного репозитория контейнеров:
apptainer pull docker://ghcr.io/apptainer/lolcow
- в этом случае образ будет сохранен в текущей директории под названием lolcow_latest.sif (шаблон: имя_тэг.sif).
Если вы хотите назвать образ иначе, или указать другую директорию, то этот путь и имя указываются первым аргументом:
apptainer pull my_supa_lolcow.sif docker://ghcr.io/apptainer/lolcow
* в приватных репозиториях зачастую необходима авторизация, пример входа:
apptainer registry login --username <логин_docker_hub> docker://docker.io
Пароль или access token запрашивается интерактивно и сохраняется до конца сессии.
Где искать образы:
| Репозиторий | Адрес | Чем популярен |
| Docker Hub | docker://ubuntu:24.04 | базовые образы, популярный софт |
| GitHub Container Registry | docker://ghcr.io/<owner>/<image> | образы проектов с GitHub |
| Quay.io / BioContainers | docker://quay.io/biocontainers/samtools:1.19--h50ea8bc_0 | биоинформатика |
| NVIDIA NGC | docker://nvcr.io/nvidia/pytorch:24.07-py3 | PyTorch, TensorFlow, HPC под GPU |
* Docker Hub ограничивает число анонимных загрузок, а все пользователи кластера выходят в интернет с одного адреса. Если получаете ошибку toomanyrequests - авторизуйтесь или возьмите образ с ghcr.io Скачивайте образ один раз в .sif и запускайте задачи с локального файла, не указывайте docker:// внутри задачи.
2. Самостоятельно собрать нужный образ:
Зачастую публичные образы избыточны или не подходят по каким-то причинам, поэтому у нас поддерживается локальный билд образов из .def файлов. Права root для этого не нужны — сборка идет от вашего пользователя.
Пример файла my.def:
Bootstrap: docker
From: ubuntu:24.04
%post
apt-get -y update
apt-get -y install python3 python3-pip
pip3 install --no-cache-dir numpy pandas
%environment
export LC_ALL=C
%runscript
python3 "$@"
%labels
Author <ваше имя>
Version 1.0
В данном примере собирается образ на базе ubuntu 24 с python3 и его пакетами numpy и pandas.
Сборка:
apptainer build my.sif my.def
- права root внутри сборки эмулируются автоматически, отдельный флаг указывать не нужно. Явная форма apptainer build --fakeroot my.sif my.def дает тот же результат.
Проверить, что получилось:
apptainer inspect my.sif
apptainer exec my.sif python3 -c "import numpy; print(numpy.__version__)"
Секции .def файла:
| Секция | Когда выполняется | Для чего |
| Bootstrap / From | в начале сборки | откуда берется базовый образ: docker, oras, localimage |
| %setup | при сборке, вне контейнера | команды на хосте, до наполнения образа. Нужна редко |
| %files | при сборке | копирование файлов с кластера внутрь образа |
| %post | при сборке, внутри контейнера | установка пакетов, компиляция, настройка |
| %environment | при каждом запуске | переменные окружения контейнера |
| %runscript | по apptainer run | команда по умолчанию, "$@" передает ей аргументы |
| %test | в конце сборки и по apptainer test | проверка, что образ собрался рабочим |
| %labels | — | метаданные, видны в apptainer inspect |
| %help | по apptainer run-help | описание образа для пользователя |
* Переменные из %post в готовый образ не попадают. Все, что должно быть в окружении при запуске, пишется в %environment.
Кэш и временные файлы
При загрузке образа слои складываются в кэш, а при сборке образ распаковывается во временный каталог - обоим нужно место. Модуль apptainer задает эти пути автоматически: кэш на /scratch, временный каталог на локальном диске узла внутри задачи. Проверить текущие значения:
printenv APPTAINER_CACHEDIR APPTAINER_TMPDIR
Посмотреть, что лежит в кэше, и почистить его:
apptainer cache list
apptainer cache clean --days 30
Если нужны свои пути — задайте переменные до загрузки модуля, модуль их не перезапишет:
export APPTAINER_CACHEDIR=/scratch/$USER/.apptainer/cache
export APPTAINER_TMPDIR=/scratch/$USER/.apptainer/tmp
module load apptainer/1.5.0
Запуск контейнера
Три команды - отличаются тем, что именно выполняется внутри образа.
1. run - выполняет сценарий из секции %runscript, зашитый в образ:
apptainer run lolcow_latest.sif
_________________________________________
/ It is a wise father that knows his own \
\ child. /
-----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Аргументы после имени образа передаются в %runscript:
apptainer run my.sif script.py --epochs 10
2. exec - выполняет произвольную команду внутри контейнера. Основной способ запуска расчетов:
apptainer exec my.sif python3 /data/train.py
apptainer exec my.sif nvidia-smi
Если нужен пайп или несколько команд, оберните их в одну команду:
apptainer exec my.sif sh -c "fortune | cowsay | lolcat"
3. shell — интерактивная оболочка внутри контейнера, для отладки образа:
apptainer shell my.sif
Apptainer> whoami
<username>
Apptainer> python3 --version
Python 3.12.3
Apptainer> exit
* внутри контейнера вы остаетесь собой: тот же пользователь, те же права на файлы. Root внутри контейнера не появляется.
* расчеты на логин-сервере запрещены. Все три команды на логин-сервере используются только для проверки образа, а сами задачи запускаются через очередь.
Флаги запуска, overlay, sandbox
Основные флаги
Работают одинаково для run, exec и shell.
| Флаг | Что делает |
| --bind ХОСТ:КОНТЕЙНЕР | монтирует каталог кластера внутрь контейнера |
| --nv | проброс GPU NVIDIA: драйвер и утилиты с узла |
| --cleanenv | не наследовать переменные окружения хоста |
| --containall | максимальная изоляция: без $HOME, /tmp и переменных хоста |
| --writable-tmpfs | разрешить запись внутрь контейнера на время запуска |
| --overlay ФАЙЛ | подключить overlay с постоянными изменениями |
| --pwd ПУТЬ | рабочий каталог внутри контейнера |
| --fakeroot | права root внутри контейнера |
--bind, доступ к своим данным. Автоматически внутрь попадают домашний каталог, /tmp и текущий рабочий каталог. Остальное монтируется явно: слева путь на кластере, справа — путь внутри контейнера.
apptainer exec --bind /scratch/$USER/data:/data my.sif ls /data
Несколько путей перечисляются через запятую, суффикс :ro монтирует только для чтения:
apptainer exec --bind /scratch/$USER/in:/in:ro,/scratch/$USER/out:/out my.sif ./process.sh
--nv, видеокарты. Сам CUDA Toolkit должен быть внутри образа, с узла пробрасывается только драйвер:
apptainer exec --nv my.sif nvidia-smi
* версия CUDA в образе не должна быть новее драйвера на узле. Иначе может возникнуть ошибка вида CUDA driver version is insufficient.
--cleanenv, если контейнер ведет себя странно. Переменные окружения логин-сервера - активная conda, PYTHONPATH, LD_LIBRARY_PATH от загруженных модулей наследуются контейнером и могут повлиять на его собственный Python:
apptainer exec --cleanenv my.sif python3 -c "import sys; print(sys.path)"
Передать внутрь конкретную переменную можно через префикс APPTAINERENV_:
export APPTAINERENV_MY_VAR=42
apptainer exec my.sif printenv MY_VAR
Изменение готового образа
Файл .sif доступен только для чтения. Способ зависит от того, нужно ли сохранять изменения.
1. Разовые изменения — --writable-tmpfs. Запись идет в память, после завершения все исчезает. Подходит, когда софту нужно что-то дописать в свои каталоги:
apptainer exec --writable-tmpfs my.sif pip3 install somepackage
2. Постоянные изменения поверх образа — overlay. Сам .sif не меняется, все новое копится в отдельном файле:
apptainer overlay create --size 1024 my_overlay.img
apptainer exec --overlay my_overlay.img --fakeroot my.sif pip3 install somepackage
apptainer exec --overlay my_overlay.img my.sif python3 -c "import somepackage"
- размер указывается в мегабайтах и задается один раз при создании;
- overlay привязан к конкретному образу, переносить его между разными .sif нельзя;
- без флага --fakeroot запись в системные каталоги контейнера не пройдет.
3. Пересборка образа — через sandbox, распакованный образ в виде обычного каталога:
apptainer build --sandbox my_sandbox/ my.sif
apptainer exec --writable --fakeroot my_sandbox/ apt-get install -y vim
apptainer build my_new.sif my_sandbox/
Sandbox удобен, когда нужно перебрать содержимое образа руками, а не переписывать .def файл.
* sandbox — это десятки тысяч мелких файлов. На /home и /scratch это медленно и расходует квоту по числу файлов. Создавайте sandbox в /tmp вычислительного узла внутри задачи, а на общий диск кладите уже собранный .sif.
Что выбрать:
| Задача | Способ |
| образ нужен постоянно и другим людям | .def файл и apptainer build |
| доставить пару пакетов поверх готового образа | overlay |
| софту нужно писать внутрь себя во время работы | --writable-tmpfs |
| разобрать чужой образ и собрать свой | sandbox |
Нашли опечатку?
Выделите её, нажмите Ctrl+Enter и отправьте нам уведомление. Спасибо за участие!
Сервис предназначен только для отправки сообщений об орфографических и пунктуационных ошибках.