Apptainer¶
✨ Introduction¶
Apptainer ( former Singularity ) is a container solution fully OCI compliant specifically designed for HPC.
Images can be created as directories or as a single .img file, making it convenient to copy them around.
The single-file image can be made executable and treated as a regular executable (./my-app-container.img) with all dependencies self-contained.
- Easy to use
- SIF a unique single file container encapsulation format
- encapsulate OCI and Docker containers into a single file
- Approved for HPC
- Convert Docker containers to SIF format
- Singularity Hub,
- Run directly to Docker Hub, Syslabs, etc
- Infiniband access, network and GPU share
- Limit user's privileges ( inside user == outside user )
- No root access - To be root inside the container you must first be root outside of the container.
- Data is shared between container and host as if contained applications where running natively in the host.
- Execution of containers can be limited to only valid keys ( pgp signed )
- Absolute mobility from laptop to HPC, cloud, etc
- Under active development
Apptainer executes the images directly without an intermediate daemon and uses SUID permissions on its executable. The privilege escalation is only used in parts of the code that really need it.
Installing¶
See Installing Apptainer for system requirements, limitations, install for source or setuid installation, etc
Debian¶
$ sudo apt update
$ sudo apt install -y wget
$ cd /tmp
$ wget https://github.com/apptainer/apptainer/releases/download/v1.1.5/apptainer_1.1.5_amd64.deb
$ sudo apt install -y ./apptainer_1.1.5_amd64.deb
Ubuntu¶
$ sudo apt update
$ sudo apt install -y software-properties-common
$ sudo add-apt-repository -y ppa:apptainer/ppa
$ sudo apt update
$ sudo apt install -y apptainer
RedHat, RockyLinux, AlmaLinux¶
$ sudo yum -y update
$ sudo yum -y wget install epel-release
$ sudo yum -y apptainer
⚙️ Running a first container¶
Running from a repository of images¶
For the case running a container getting an image directly from the syngularity container library
$ apptainer run library://godlovedc/funny/lolcow
INFO: Using cached image
________________________________________
/ You will be winged by an anti-aircraft \
\ battery. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Or you can do the same thing running directly from the Docker hub
$ apptainer run docker://godlovedc/lolcow
We are using containers from:
- The Singularity Container Library, developed and maintained by Sylabs
- Docker Hub, developed and maintained by Docker
There are other places to find pre-build containers
Getting the image and run locally¶
First we recover a image to disk with the "pull" or "build" singularity commands.
Ex:
$ apptainer pull library://juanca/default/lolcow
INFO: Downloading library image
1.4GiB / 1.4GiB [=========] 100 %
This container is saved as lolcow_latest.sif, "latest" is the Default Tag of the latest version.
You can run locally
$ apptainer run lolcow_latest.sif
_______________________________________
/ A visit to a strange place will bring \
\ fresh work. /
---------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
You can also execute commands as
$ apptainer exec lolcow_latest.sif date
Fri Aug 21 15:28:53 CEST 2020
📥 Download pre-built containers¶
There are containers in lots of places. Singularity can convert and run containers in many different formats, including those built by Docker.
- The Singularity Container Library, developed and maintained by Sylabs
- The Docker Hub, developed and maintained by Docker
Here are some of the more popular ones:
- Singularity Hub, an early collaboration between Stanford University and the Singularity community
- Quay.io, developed and maintained by Red Hat
- NGC, developed and maintained by NVIDIA
- BioContainers, develped and maintained by the Bioconda group
- Cloud providers like Amazon AWS, Microsoft Azure, and Google cloud also have container registries that can work with Singularity
🔢 Building a Basic Container¶
A build cycle¶
- Write a definition file
- Create a writable container
- Shell into the container with the **--writable** option and tinker with it interactively
- Record changes that we like in our definition file
- Rebuild the container from the definition file if we break it
- Fix and repeat until we are happy with the result
- Build the container from the final definition file as a read-only singularity image format (SIF) image for use in production
Optionally you could
- sign the container
- push the container file in a repository
Write a definition file¶
You need write a definition file
Ex: tp0.def
BootStrap: library
From: alpine:latest
%runscript
echo "This is what happens when you run the container..."
%post
echo "Hello from inside the container"
apk update
apk add vim
Bootstrap agents¶
The Bootstrap keyword is always mandatory. It describes the bootstrap module to use.
Most people build containers from existing containers on the Container Library or on Docker Hub.
For instance, to use an existing Debian container from the Container library your header would look like this:
BootStrap: library
From: debian
The same thing but this time from a debian Docker Hub would be look like this.
Bootstrap: docker
From: debian
Use the debootstrap module to specify a base for a Debian-like container. You must also specify the OS version and a URI for the mirror you would like to use.
BootStrap: debootstrap
OSVersion: stable
MirrorURL: http://ftp.us.debian.org/debian/
The module yum allows you to build a Red Hat/CentOS/Scientific Linux style container from a mirror URI.
Bootstrap: yum
OSVersion: 7
MirrorURL: http://mirror.centos.org/centos-%{OSVERSION}/{OSVERSION}/os/$basearch/
Include: yum
See this list of “bootstrap agents” in the Singularity docs.
Building the sandbox¶
Building the tp0 sandbox
$ apptainer build --sandbox --force tp0 tp0.def
Goto into the TP0 sandbox and check the new environment ex: pwd,os,hostname and user.
$ apptainer shell tp0
Singularity>
Singularity> pwd
/home/centos/TP
Singularity> cat /etc/os-release | grep NAME
NAME="Alpine Linux"
PRETTY_NAME="Alpine Linux v3.11"
Singularity> hostname -f
test-sym.cppm-cloud.in2p3.fr
Singularity> echo $USER
centos
Any modification to the image contained in the sandbox forces to open a shell using the --writable option. The shell command must be called from sudo.
$ sudo apptainer shell --writable tp0
WARNING: Skipping mount /etc/localtime [binds]: /etc/localtime doesn't exist in container
Singularity> apk add figlet
(1/1) Installing figlet (2.2.5-r0)
Executing busybox-1.31.1-r9.trigger
OK: 36 MiB in 20 packages
As soon as you are sure of the changes to be made. You can edit the definition file.
%runscript
fortune
%post
echo "Hello from inside the container"
apk update
apk add vim fortune figlet
%environment
export PATH=$PATH:/usr/games
export LC_ALL=C
$ apptainer build --sandbox --force tp0 tp0.def
And test, first the runscript record
$ apptainer run tp1
No animal should ever jump on the dining room furniture unless
absolutely certain he can hold his own in conversation.
-- Fran Lebowitz
Build a final image¶
Once you've verified your sandbox container, you can save a final image in Read Only Singularity Format (SIF).
The build command is always used from sudo.
$ sudo apptainer build tp0.sif tp0
INFO: Starting build...
INFO: Creating SIF file...
INFO: Build complete: tp1.sif
$ echo 'hello' | singularity exec tp1.sif 'figlet'
_ _ _
| |__ ___| | | ___
| '_ \ / _ \ | |/ _ \
| | | | __/ | | (_) |
|_| |_|\___|_|_|\___/
The sandbox can be deleted
$ sudo rm -rf tp0
🔄 Container Interaction¶
Execute commands¶
You can execute commands as
$ apptainer exec anaconda_latest.sif date
Fri Aug 21 15:28:53 CEST 2020
Run a shell¶
To run a interactive shell into
$ apptainer shell anaconda_latest.sif
Singularity> id
uid=1001(carranza) gid=1001(carranza) groups=1001(carranza)
Start a instance from a singularity image¶
This case is adapted when you run services into
$ sudo apptainer instance start --writable-tmpfs nginx.sif web
INFO: instance started successfully
$ apptainer instance list
INSTANCE NAME PID IP IMAGE
web 1224 /home/centos/nginx.sif
$ curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
...
Enter to a Instance¶
$ apptainer shell instance://my_anaconda
Singularity>
Manage files on the host system¶
Is possible to create and modify files on the host system from within the container.
Apptainer bind or mounts several directories into your container by default. These include:
- /home/$USER
- /tmp
- /proc
- /sys
- /dev
Other directories to bind can be specify using
-
the --bind option
-
the SINGULARITY_BINDPATH variable in the environment
Ex :
Supose we want to access a directory called locally '/data' from within our container. For this example, we first need to create this new directory with some data on our host system.
$ sudo mkdir /data
$ sudo chown $USER:$USER /data
$ fortune > /data/fortune.txt
List the contents of /data
within the container without bind mounting /data
on the host system to it.
$ apptainer exec lolcow.sif ls -l /data
ls: cannot access '/data': No such file or directory
Using the --bind option a /data
directory wil be created in the container and it will be bind mounted to the /data
directory on the host system.
$ apptainer exec --bind /data lolcow.sif ls -l /data
total 4
-rw-rw-r-- 1 centos centos 17 Mar 2 00:51 fortune.txt
Example¶
From the idea that the current directory is shared. All changes that affecting this path will be kept.
$ apptainer shell anaconda_latest.sif ls -l /data
Singularity>
Singularity> conda init bash
....
Singularity> source ~/.bashrc
(base) Singularity
(base) Singularity> conda activate myenv
(myenv) Singularity>
(myenv) Singularity> conda info --envs
conda environments:
myenv * /home/centos/.conda/envs/myenv
base /opt/anaconda3
At this time you can install some things in your private space
(myenv) Singularity>conda install matplotlib
(myenv) Singularity> python
Python 3.8.1 (default, Jan 8 2020, 22:29:32)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib as np
Leave now the instance and stop it
(myenv) Singularity> exit
$ singularity instance stop my_anaconda
INFO: Stopping my_anaconda instance of share/local/singularity/Anaconda_2020.02.simg (PID=165453)
Even after we exited the container, the conda environment will be present. All changes that you have done will be preserved.
$ ls .conda/envs
myenv
Singularity and Openstack playing together¶
Separating roles can be the best strategie to profit from containers and cloud tecnology. Let the Openstack cloud infrastructure take the role of resource provider and use the "apptainer/singularity" software the role of provisioning the software.
Getting a ressource from the cloud¶
First create une openstack instance and install apptainer ( singularity ) software into.
$ openstack server create --flavor m1.large
--image CentOS-8-x86_64 --nic net-id=$OS_NET
--security-group default --key-name your-key
--user-data anaconda.txt
your_instance
Provisioning software with singularity¶
This should start a jupyter notebook server the server and give you an html address with a security token to use for the connection.
$ singularity exec --bind /tmp:/run/user
anaconda_latest.sif jupyter notebook
Running Apptainer ( or singularity ) in a openstack instance needs to do some network configuration to make things work properly. You probably need to set up an ssh tunnel in a new terminal to access the notebook server.
$ ssh -i your_priv_key -N -L 8889:localhost:8888 centos@your_instance
After that, you can connect to the given html address but using localhost or 127.0.0.1 and the redirected port
¶
Links |
---|
Apptainer User Guide |
GPU Support |
Videos |
---|
Containers for Science, Reproducibility, and HPC |
Singularity - Container Workflows for Compute. |