2. Container
2.1. Introdução
A Open Container Initiative (OCI) é uma estrutura de governança aberta com o propósito expresso de criar padrões abertos da indústria em torno de formatos e runtimes de contêineres. A maioria dos containers são compatíveis com o padrão OCI.
O Docker é o sistema de gerenciamento de containers mais utilizado. Entretanto,
algumas mudanças na empresa Docker Inc gerou alguns problemas na comunidade.
O Kubernetes descontinuou o Docker e passou a usar o Container Runtime Interface
(CRI). As imagens produzidas pelo Docker continuam funcionando sem problemas,
pois fazem parte do OCI. Esse também foi um dos motivos que fez com que a RedHat
criasse o Podman.
Em relação a ambientes de HPC com multi-nó, o padrão adotado é o singularity,
também chamado de apptainer (nome do projeto do singularity na Linux
Foundation). O apptainer também é compatível com o padrão do OCI. Existem
diversos motivos para o uso do apptainer ao invés do docker em ambientes de
HPC, porém, isto não será tratado aqui.
O apptainer permite a importação dos containers diretamente do Docker Hub ou de outros repositórios.
2.2. Baixando imagens
2.2.1. Docker Hub
Usando as imagens oriundas do Docker Hub. Por exemplo, baixando um container Alpine.
[user1@sismom-1 containers]$ apptainer pull docker://alpine:latest
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
INFO: Fetching OCI image...
3.7MiB / 3.7MiB [=================================================================] 100 %0s
INFO: Extracting OCI image...
INFO: Inserting Apptainer configuration...
INFO: Creating SIF file...
[=================================================================================] 100 % 0s
[user1@sismom-1 containers]$ ls
alpine_latest.sif
2.2.2. NVIDIA NGC
Se for utilizar o pytorch, tensorflow recomenda-se utilizar as imagens otimizadas da
própria NVIDIA, através do link NGC. Se for outra
aplicação também recomenda-se a consulta no NGC para ver se já existe um container dela.
Por exemplo, baixando uma versão do pytorch diferente da disponível no cluster,
diretório /sw/containers.
[user1@sismom-1 containers]$ apptainer pull docker://nvcr.io/nvidia/pytorch:25.11-py3
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
INFO: Fetching OCI image...
...
INFO: Creating SIF file...
[user1@sismom-1 containers]$ ls -lh
total 8.3G
-rwxrwxr-x 1 user1 group1 8.2G Oct 8 11:31 pytorch_25.11-py3.sif
-rwxrwxr-x 1 user1 group1 3.7M Oct 8 10:57 alpine_latest.sif
Importante
Os containers mais comuns estão disponiveis no diretório /sw/containers no cluster Sismom.
Atenção
Repare que os containers possuem tamanhos de dezenas a milhares de MB. Se for trabalhar em equipe, recomenda-se o uso compartilhado, a fim de minimizar o consumo de espaço em disco. Por favor, evite de ter várias cópias do mesmo container.
Sugestão: crie um diretório compartilhado e coloque todos os containers nele. Por exemplo,
criar um diretório para o projeto1 no diretório /sw/containers/projeto1 onde o grupo
tenha permissão de leitura e escrita no diretório em questão.
2.3. Executando o container
2.3.1. Sessão iterativa
Segue uma breve descrição dos comandos abaixo.
aloca 1 nó de processamento e 1 GPU
identifica a versão do sistema operacional (S.O.) do nó
sismom-1executa o container no modo
SHELLidentifica a versão do S.O. do container que é diferente do S.O. do nó
mostra os filesystems que estão montados no container
[user1@sismom-1 containers]$ salloc
salloc: Granted job allocation 5
salloc: Nodes sismom-1 are ready for job
[user1@sismom-1 containers]$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Ubuntu 24.04.3 LTS"
[user1@sismom-1 containers]$ apptainer shell alpine_latest.sif
Apptainer> grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Alpine Linux v3.23"
Apptainer> df -h
Filesystem Size Used Available Use% Mounted on
overlay 64.0M 16.0K 64.0M 0% /
udev 62.7G 0 62.7G 0% /dev
tmpfs 62.8G 0 62.8G 0% /dev/shm
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /etc/localtime
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /etc/hosts
efivarfs 495.9K 185.9K 305.0K 38% /sys/firmware/efi/efivars
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /home/users/user1
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /tmp
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /var/tmp
tmpfs 64.0M 16.0K 64.0M 0% /etc/resolv.conf
tmpfs 64.0M 16.0K 64.0M 0% /etc/passwd
tmpfs 64.0M 16.0K 64.0M 0% /etc/group
Apptainer> exit
exit
[user1@sismom-1 containers]$
Nota
Observe que a área de usuário $HOME é montada, por padrão, dentro
do container. Caso necessário, as demais áreas deverão ser montadas
através do parâmetro -B <diretório externo>:<diretório interno>
ou --bind <diretório externo>:<diretório interno> do comando
apptainer.
[user1@sismom-1 containers]$ apptainer shell -B /data1:/mnt alpine_latest.sif
Apptainer> df -h
Filesystem Size Used Available Use% Mounted on
overlay 64.0M 16.0K 64.0M 0% /
udev 62.7G 0 62.7G 0% /dev
tmpfs 62.8G 0 62.8G 0% /dev/shm
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /etc/localtime
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /etc/hosts
efivarfs 495.9K 185.9K 305.0K 38% /sys/firmware/efi/efivars
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /home/users/users1
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /tmp
/dev/mapper/ubuntu--vg-ubuntu--lv
97.9G 90.0G 2.9G 97% /var/tmp
tmpfs 64.0M 16.0K 64.0M 0% /etc/resolv.conf
tmpfs 64.0M 16.0K 64.0M 0% /etc/passwd
tmpfs 64.0M 16.0K 64.0M 0% /etc/group
/dev/mapper/mpatha-part3
90.7T 1.7T 89.0T 2% /mnt
Apptainer> exit
exit
[user1@sismom-1 containers]$
2.3.2. Sessão iterativa com GPU
Nestes comandos é chamado o Pytorch dentro do container e verifica a quantidade de
GPUs que o container identificou.
[user1@sismom-1 containers]$ salloc -N1 --gpus=1
salloc: Granted job allocation 4475
salloc: Nodes gpu01 are ready for job
[user1@gpu01 containers]$ apptainer shell --nv pytorch_25.11-py3.sif
Apptainer> python
Python 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.device_count()
1
>>>
2.3.3. Executando o container
Para executar um container deve usar o comando apptainer run ou apptainer exec.
[user1@sismom-1 containers]$ apptainer run pytorch_25.11-py3.sif
=============
== PyTorch ==
=============
NVIDIA Release 25.11 (build 231036167)
PyTorch Version 2.10.0a0+b558c98
Container image Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Copyright (c) 2014-2024 Facebook Inc.
All rights reserved.
Failed to detect NVIDIA driver version.
Apptainer>
Importante
Repare na mensagem de erro Failed to detect NVIDIA driver version na execução
do container. Isso se deve porque o suporte a qualquer GPU é desabilitado por
padrão.
Para habilitar basta acrescentar o parâmetro --nv, para GPUs da NVIDIA, como
mostrado abaixo.
[user1@sismom-1 containers]$ apptainer run --nv pytorch_25.11-py3.sif
=============
== PyTorch ==
=============
NVIDIA Release 25.11 (build 231036167)
PyTorch Version 2.10.0a0+b558c98
Container image Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
All rights reserved.
Apptainer> python
Python 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.is_available()
True
>>> torch.cuda.device_count()
8
>>> exit()
Apptainer>
2.4. Criando uma nova imagem
A fim de ilustrar a criação de uma nova imagem, será usada como base a imagem
docker://python:alpine. Essa imagem não tem instalada o pacote numpy.
Pode-se observar que dá erro ao tentar executar o script python que utiliza o numpy.
[user1@sismom-1 containers]$ apptainer run python_alpine3.19.sif python numpy-test.py
Traceback (most recent call last):
File "/home/users/user1/userguide/numpy-test.py", line 3, in <module>
import numpy as np
ModuleNotFoundError: No module named 'numpy'
Semelhante ao Dockerfile do gerenciador Docker, o apptainer usa um arquivo
definition com as informações dos comandos necessários para instalar todas as
dependências necessárias. Por exemplo, foi criado um arquivo numpy.def com o seguinte
conteúdo.
# image
Bootstrap: docker
From: python:alpine
%post
# upgrading pip
pip install --upgrade --no-cache-dir pip setuptools
# installing new packages
pip install --no-cache-dir numpy
O cabeçalho define o formato Docker e a imagem From: python:alpine e depois o trecho
%post define os comandos que serão executados para instalação dos pacotes, bibliotecas, etc.
Nota
Os comandos do arquivo definition irão variar com base no sistema operacional da imagem
utilizada, por exemplo: Ubuntu, Rocky Linux, Red Hat Universal Base Image (ubi),
etc.
Criando uma nova imagem chamada
numpy.sif
[user1@sismom-1 containers]$ apptainer build numpy.sif numpy.def
INFO: Starting build...
...
Writing manifest to image destination
...
INFO: Running post scriptlet
+ pip install --upgrade --no-cache-dir pip setuptools
...
+ pip install --no-cache-dir numpy
...
INFO: Creating SIF file...
INFO: Build complete: numpy.sif
Executando o script python, que possui a dependência do numpy, sem nenhum erro.
[user1@sismom-1 containers]$ apptainer run numpy.sif python numpy-test.py
Maximo: 0.7051411895679115
Nota
No caso do container utilizar GPUs, recomenda-se o uso das imagem da NVIDIA NGC
que já inclui todas as dependências, além de já estarem otimizadas.