• A
  • A
  • A
  • АБВ
  • АБВ
  • АБВ
  • А
  • А
  • А
  • А
  • А
Обычная версия сайта

Запуск контейнеров на суперкомпьютере - 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 и отправьте нам уведомление. Спасибо за участие!
Сервис предназначен только для отправки сообщений об орфографических и пунктуационных ошибках.