Pular para conteúdo

Contêineres (Apptainer/Singularity)

Visão geral

Apptainer (anteriormente conhecido como Singularity) é uma plataforma de contêineres projetada especificamente para ambientes de computação de alto desempenho (HPC). Diferente do Docker, o Apptainer foi desenvolvido para executar contêineres de forma segura em sistemas compartilhados sem necessidade de privilégios de root.

Apptainer vs Singularity

Singularity foi renomeado para Apptainer em 2021. Os comandos e funcionalidades são os mesmos, e o Apptainer mantém compatibilidade total com imagens Singularity. No cluster, você pode usar tanto apptainer quanto singularity como comandos.

Por que usar contêineres no HPC?

  • Reprodutibilidade: Empacote todo o ambiente de software para garantir que funcione da mesma forma em qualquer lugar
  • Isolamento: Execute diferentes versões de bibliotecas sem conflitos
  • Portabilidade: Mova aplicações entre diferentes clusters e sistemas
  • Compatibilidade com Docker: Converta imagens Docker para Apptainer

Verificar disponibilidade

# Verificar se Apptainer está disponível
module avail apptainer

# Ou verificar Singularity
module avail singularity

# Carregar módulo
module load apptainer
# ou
module load singularity

# Verificar versão
apptainer --version

Usar imagens existentes

Imagens do Docker Hub

Você pode executar imagens Docker diretamente:

# Executar comando em contêiner Docker
apptainer exec docker://ubuntu:22.04 cat /etc/os-release

# Shell interativo
apptainer shell docker://ubuntu:22.04

Converter imagem Docker para SIF

Formato SIF (Singularity Image Format) é mais eficiente para uso em HPC:

# Criar arquivo .sif a partir de imagem Docker
apptainer build ubuntu.sif docker://ubuntu:22.04

# Usar a imagem convertida
apptainer shell ubuntu.sif

Repositório local de imagens

Consulte o NOC sobre imagens disponíveis no cluster em /scratch/singularity/ ou locais compartilhados.

Executar contêineres

Modo shell (interativo)

# Abrir shell dentro do contêiner
apptainer shell ubuntu.sif

Exemplo de sessão interativa:

# Solicitar nó de computação
srun --pty --time=01:00:00 --cpus-per-task=4 bash

# Executar contêiner
apptainer shell /scratch/projetos/<seu_projeto>/containers/ubuntu.sif

# Você está agora dentro do contêiner
Apptainer> python --version
Apptainer> exit

Modo exec (executar comando)

# Executar comando específico
apptainer exec ubuntu.sif python script.py

# Com argumentos
apptainer exec ubuntu.sif python script.py --input data.csv --output results.txt

Modo run (executar runscript)

# Executar script padrão do contêiner
apptainer run ubuntu.sif

Vincular diretórios (bind)

Por padrão, Apptainer monta automaticamente: - Seu diretório home ($HOME) - Diretório atual ($PWD) - /tmp

Para acessar outros diretórios, use --bind ou -B:

# Vincular diretório específico
apptainer shell --bind /scratch/projetos/<seu_projeto> ubuntu.sif

# Vincular múltiplos diretórios
apptainer shell --bind /scratch,/opt ubuntu.sif

# Vincular com caminho diferente no contêiner
apptainer shell --bind /scratch/projetos/<seu_projeto>:/data ubuntu.sif

Configurar bind permanente:

# Adicionar ao ~/.bashrc
export APPTAINER_BINDPATH="/scratch/projetos/<seu_projeto>,/opt"

Usar contêineres em jobs SLURM

Job simples

#!/bin/bash
#SBATCH --job-name=apptainer_job
#SBATCH --output=/scratch/projetos/<seu_projeto>/logs/job_%j.out
#SBATCH --time=02:00:00
#SBATCH --cpus-per-task=4
#SBATCH --mem=8G

# Carregar Apptainer se necessário
module load apptainer

# Executar script dentro do contêiner
apptainer exec /scratch/projetos/<seu_projeto>/containers/python.sif \
    python /scratch/projetos/<seu_projeto>/scripts/analise.py

Job com GPU

#!/bin/bash
#SBATCH --job-name=gpu_container
#SBATCH --partition=gpu
#SBATCH --gpus=1
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G
#SBATCH --time=04:00:00
#SBATCH --output=/scratch/projetos/<seu_projeto>/logs/gpu_%j.out

module load apptainer
module load cuda/11.8

# Usar --nv para acesso às GPUs NVIDIA
apptainer exec --nv \
    /scratch/projetos/<seu_projeto>/containers/pytorch.sif \
    python train_model.py

Job MPI

#!/bin/bash
#SBATCH --job-name=mpi_container
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --cpus-per-task=1
#SBATCH --time=02:00:00

module load apptainer
module load openmpi

# Executar aplicação MPI
mpirun apptainer exec \
    /scratch/projetos/<seu_projeto>/containers/mpi_app.sif \
    /opt/app/bin/mpi_program

Construir suas próprias imagens

Necessário privilégios de root

Para construir imagens, você precisa de acesso root em uma máquina Linux local ou usar serviços online como Sylabs Cloud.

Criar arquivo de definição

exemplo.def:

Bootstrap: docker
From: ubuntu:22.04

%post
    # Atualizar sistema
    apt-get update && apt-get install -y \
        python3 \
        python3-pip \
        git \
        vim

    # Instalar pacotes Python
    pip3 install numpy pandas scipy matplotlib

%environment
    export LC_ALL=C
    export PATH=/usr/local/bin:$PATH

%runscript
    echo "Contêiner pronto para uso!"
    exec /bin/bash "$@"

%labels
    Author seu_nome@email.com
    Version v1.0

Construir imagem (em máquina com root)

# Construir imagem SIF
sudo apptainer build minha_imagem.sif exemplo.def

# Transferir para o cluster
scp minha_imagem.sif usuario@cluster:/scratch/projetos/<seu_projeto>/containers/

Usar Sylabs Cloud (sem root)

# Fazer login
apptainer remote login

# Construir remotamente
apptainer build --remote minha_imagem.sif exemplo.def

Converter imagens Docker

Se você tem um Dockerfile ou imagem Docker:

# Converter imagem Docker local
apptainer build minha_app.sif docker-daemon://minha_app:latest

# Converter do Docker Hub
apptainer build tensorflow.sif docker://tensorflow/tensorflow:latest-gpu

# Converter com opções específicas
apptainer build --sandbox minha_app/ docker://minha_app:latest

Variáveis de ambiente

Definir variáveis para o contêiner

# Via linha de comando
apptainer exec --env VAR1=valor1,VAR2=valor2 ubuntu.sif env

# Via prefixo APPTAINERENV_
export APPTAINERENV_MYVAR="hello"
apptainer exec ubuntu.sif echo $MYVAR

Passar variáveis do host

# Limpar variáveis do host (padrão)
apptainer exec --cleanenv ubuntu.sif env

# Manter variáveis do host
apptainer exec --containall --env-file vars.env ubuntu.sif comando

Exemplo completo: ambiente Python científico

1. Criar estrutura de projeto:

mkdir -p /scratch/projetos/<seu_projeto>/containers
mkdir -p /scratch/projetos/<seu_projeto>/scripts

2. Baixar imagem Python científica:

cd /scratch/projetos/<seu_projeto>/containers
apptainer build python_cientifico.sif docker://continuumio/miniconda3:latest

3. Script Python (scripts/analise.py):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

print("Análise iniciada...")
# Seu código aqui

4. Job SLURM (submit_analise.sh):

#!/bin/bash
#SBATCH --job-name=analise
#SBATCH --output=/scratch/projetos/<seu_projeto>/logs/analise_%j.out
#SBATCH --time=01:00:00
#SBATCH --cpus-per-task=4

module load apptainer

apptainer exec \
    --bind /scratch/projetos/<seu_projeto>:/workspace \
    /scratch/projetos/<seu_projeto>/containers/python_cientifico.sif \
    python /workspace/scripts/analise.py

5. Submeter job:

sbatch submit_analise.sh

Boas práticas

1. Organização de imagens

/scratch/projetos/<seu_projeto>/
├── containers/
   ├── python_base.sif
   ├── tensorflow_gpu.sif
   └── custom_app.sif
├── scripts/
└── logs/

2. Usar imagens versionadas

# Bom: especificar versão
apptainer build python.sif docker://python:3.11

# Evitar: usar latest (pode mudar)
apptainer build python.sif docker://python:latest

3. Documentar suas imagens

Mantenha um arquivo README ou comentários no arquivo de definição:

# python_cientifico.txt
Imagem: python_cientifico.sif
Baseada em: continuumio/miniconda3
Pacotes: numpy, pandas, matplotlib, scipy
Criada em: 2024-01-15
Uso: Análises de dados científicos

4. Verificar tamanho das imagens

# Verificar tamanho
ls -lh /scratch/projetos/<seu_projeto>/containers/

# Inspecionar imagem
apptainer inspect python.sif

5. Testar localmente antes de submeter jobs

# Sempre teste interativamente primeiro
srun --pty bash
apptainer exec minha_imagem.sif python script.py

Problemas comuns

Erro: "No space left on device"

Problema: Cache do Apptainer lotou /tmp.

Solução:

# Definir cache em seu diretório
export APPTAINER_CACHEDIR=/scratch/projetos/<seu_projeto>/.apptainer_cache
mkdir -p $APPTAINER_CACHEDIR

# Limpar cache
apptainer cache clean

Erro: "Permission denied" ao acessar arquivos

Problema: Diretório não montado no contêiner.

Solução:

# Verificar binds ativos
apptainer exec ubuntu.sif mount | grep bind

# Adicionar bind necessário
apptainer exec --bind /scratch ubuntu.sif comando

GPU não detectada

Problema: Flag --nv não foi usada.

Solução:

# Sempre use --nv para GPUs NVIDIA
apptainer exec --nv pytorch.sif nvidia-smi

# Verificar CUDA dentro do contêiner
apptainer exec --nv pytorch.sif nvcc --version

Imagem muito grande

Problema: Imagem .sif muito grande para /home.

Solução:

# Construir em /scratch
cd /scratch/projetos/<seu_projeto>/containers
apptainer build --force grande_imagem.sif docker://imagem:tag

# Verificar e limpar camadas desnecessárias no Dockerfile

Apptainer vs Docker

Característica Apptainer Docker
Privilégios root Não necessário Requerido
Segurança HPC Projetado para HPC Não recomendado
Formato de imagem SIF (único arquivo) Camadas
Compatibilidade Lê imagens Docker Nativo
MPI/GPU Suporte nativo Limitado
Uso recomendado Clusters HPC Desenvolvimento local

Recursos adicionais

Suporte

Se você encontrar problemas ao usar Apptainer:

  1. Verifique os logs de erro do job
  2. Teste a imagem interativamente antes de submeter jobs
  3. Consulte a documentação oficial
  4. Entre em contato com o suporte ou envie email para hpc@fieb.org.br