The Buildah tool can build OCI container images directly on Eiger and Piz Daint. Buildah can only run in rootless mode on the systems: rootless mode relies on Linux user namespaces, which are enabled on the compute nodes. Please refer to the official Buildah documentation for more information on the tool.

The command buildah on Eiger is available directly on /usr/bin, while on Piz Daint you need to load the module Buildah as shown below, after you have accessed a compute node:

module load daint-gpu  # or daint-mc for multicore nodes
module load Buildah

Limitations

The gpfs and lustre file systems cannot store the image layers: In order to circumvent this problem, an ext4 partition is mounted on the compute node allocated using the contbuild

Slurm constraint.

Buildah service disruption on Eiger

After February 28th the buildah and stackinator tools on Eiger won't be available until further notice

Using Buildah

The first step in order to use Buildah is to create a valid storage configuration file $HOME/.config/containers/storage.conf, following the minimal template provided below:

[storage]
  driver = "vfs"
  runroot = "/dev/shm/<username>/runroot"
  graphroot = "/dev/shm/<username>/containers/storage"

In the example above  the vfs  storage driver is used. Furthermore, the file system /dev/shm is used for both runroot and graphroot, since the underlying filesystem has to support user namespaces. Using /dev/shm  will result in better performance when building the container image. You can then login directly to a compute node to build the container image:

srun -A <account> -C mc --pty bash   # or "-C gpu" to access a GPU node on Piz Daint   

By default only one node is requested, since building container images is not supported with multiple nodes. On Piz Daint, you need to load the default module Buildah:

module load daint-mc   # or daint-gpu for GPU nodes
module load Buildah

Then it is pretty straightforward to build an image from a Dockerfile using the following commands:

# Change to the directory containing the your Dockerfile
cd <context_dir>

# Build using Dockerfile
buildah bud --tag <image_tag> .

# Build an image using Dockerfile and the docker format
buildah bud --format=docker --tag <image_tag> .

# Build an image using the docker format and a custom name for the Dockerfile
buildah bud --format=docker -f <custom_dockerfile> -t <image_tag> .

The image created can be exported as a docker-archive to be loaded later by a container runtime environment (e.g.: Sarus):

Export Container Image
# Create the docker-archive (preferably on /dev/shm for better performance)
buildah push <image_tag> docker-archive:/dev/shm/<username>/<archive_name.tar>

# Copy the image to $SCRATCH to make it available after the job allocation ends
cp /dev/shm/<username>/<archive_name.tar> $SCRATCH

The image can be then easily loaded and used with Sarus with the command sarus load $SCRATCH/<archive_name.tar> <image_name>.

Once the job allocation on the compute node has completed, the images created are deleted. Therefore, please make sure to either push your images to a container registry or export them to an archive before exiting the job allocation

Spawning Containers from Images

It is possible to spawn a container from a container image using the command buildah from:

# Create container from a given image
buildah from --name <container_name> <image_name>

It is then possible to run interactively inside the spawned container:

buildah run -t <container_name> bash

Commiting a container as a new image

To commit a container (including any changes that may have been made in it) as a container image you can use the command buildah commit:

buildah commit <container_name> <image_tag

Exporting Container Images

Buildah allows exporting container images to a number of different formats. You can export the image with tag <image_tag> using the following command:

buildah push <image_tag> docker-archive:/<my_path>/<archive_name.tar>

The docker-archive format of the example above can be used to import the image using either Sarus or Singularity.

Interacting with Container Registries

Interacting with container registries using Buildah for pulling or pushing container images is straightforward. Buildah uses a registries.conf configuration file which controls the interaction with container registries as well as a policy.json defining the trust policy for container images. Default registries.conf and policy.json files are provided on Piz Daint allowing interaction with DockerHub. Custom configuration files can always be used via the --registries-conf and --signature-policy command line options.

Pulling images

In order to pull container images, use the command buildah pull, which takes one of the following forms:

buildah pull imagename:imagetag

OR

buildah pull myregistry/myrepository/imagename:imagetag

You might have to login to your container registry before being able to pull images. This is performed with one of the following options:

buildah login <registry_url>   # Login by passing the username/password interactively

OR 

buildah login -u <username> -p <password> <registry_url>   # Login by passing username/password as cli options

For instance, in order to login interactively on your personal DockerHub registry where you are registered with <username>, you should run the command below: 

buildah login docker.io/<username> 

Please have a look at the additional options available for buildah login.

Pushing images

In order to push an image to a container registry, you first need to login to it. Afterwards, you should tag the image you want to push according to the name of your container registry and the corresponding repository. This is performed using the command buildah tag and the procedure is similar to docker tag. Then you should use the command buildah push to push the image to the container registry, similarly to docker push.