Page MenuHomec4science

containers.html
No OneTemporary

File Metadata

Created
Thu, Jul 3, 17:17

containers.html

<!DOCTYPE html>
<html>
<head>
<title>Working with Containers</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/linux_1.css">
</head>
<body>
<textarea id="source">
class: center, middle
# Working with Containers
Please open this in your browser to follow along:
`https://goo.gl/hhkKSP`
---
# Agenda
1. The problem we're solving
2. Virtual machines vs containers
3. History of containers
4. Docker vs Singularity
5. Singularity workflow
6. Installing and testing Singularity
7. Creating and working with containers
8. Writing a Singularity definition file
9. Using host resources
10. Distributing Singularity containers
11. Docker <-> Singularity interoperability
12. Extra credits (if time allows)
---
class: center, middle
# The Problem
---
# Problem (for developers)
Suppose you're writing some software.
It works great on your machine.
However, eventually it has to leave your machine: has to run on your colleague's machine,
or deployed in its production environment.
It can be a completely different flavour of OS, with a different set of libraries
and supporting tools.
It can be difficult to test if you accounted for all those variations
on your own development system.
You may have things in your environment you're not even aware of that make a difference.
Your users could also be less technically inclined to deal with dependencies.
You may wish to decrease this friction.
---
# Problem (for users)
Suppose you want to run some piece of software.
First off, you really would like some sort of turn-key solution.
Of course there's none, there's only the source code.
The build instuctions indicate 5-years-old out of date libraries
on top of a similarly old OS distribution.
And no, the original developer is most certainly no longer available.
You also don't trust this software fully not to mess up your OS.
Or, you want to run it on a remote server for which you don't
even have the privileges to comfortably install all the dependencies.
---
# Problem (for researchers)
Suppose you have a piece of scientific software you used
to obtain some result.
Then someone half across the globe tries to reproduce it,
and can't get it to run, or worse - is getting different
results for the same inputs. What is to blame?
Or, even simpler: your group tries to use your software a couple
of years after you left, and nobody can get it to work.
For a reproducible way to do science with the help of software,
packaging just the source code might not be enough;
the environment should also be predictable.
---
# Problem (for server administrators)
Suppose you have a hundred of users, each requesting certain software.
Some of it needs to be carefully built from scratch,
as there are no prebuilt packages.
Some of the software works with mutually-incompatible library versions.
Possibly even known-insecure ones.
Any such software change has to be injected in
a scheduled maintenance window, but users want it yesterday.
And finally, _you most certainly don't_ trust any of this software
not to mess up your OS. From experience.
---
# What would be a solution?
* **A turnkey solution**
A recipe that can build a working instance of your software, reliably and fast.
* **BYOE: Bring Your Own Environment**
A way to capture the prerequisites and environment together with the software.
* **Mitigate security risks**
Provide a measure of isolation between the software running on a system.
No security is perfect, but some is better than none.
---
class: center, middle
# The Solution(s)
---
# Solution: Virtual Machines?
A virtual machine is an isolated instance of a .highlight[whole other "guest" OS] running
under your "host" OS.
A .highlight[hypervisor] is responsible for handling the situations where this isolation
causes issues for the guest.
From the point of view of the guest, it runs under its own, dedicated hardware.
Hence, it's called .highlight[hardware-level virtualization].
Most<sup>*</sup> guest/host OS combinations can run: you can run Windows on Linux,
Linux on Windows, etc.
------
\* MacOS being a complicated case due to licensing.
---
# Virtual Machines: the good parts
* **The BYOE principle is fully realized**
Whatever your environment is, you can package it fully, OS and everything.
* **Security risks are truly minimized**
Very narrow and secured bridge between the guest and the host means little
opportunity for a bad actor to break out of isolation
* **Easy to precisely measure out resources**
The contained application, together with its OS, has restricted access to
hardware: you measure out its disk, memory and alotted CPU.
---
# Virtual Machines: the not so good parts
* **Operational overhead**
For every piece of software, the full underlying OS has to be run,
and corresponding resources allocated.
* **Setup overhead**
Starting and stopping a virtual machine is not very fast,
and/or requires saving its state.
Changing the allocated resources can be hard too.
* **Hardware availability**
The isolation between the host and the guest can hinder access to
specialized hardware on the host system.
---
# Solution: Containers (on Linux)?
If your host OS is Linux and your software expects Linux, there's
a more direct and lightweight way to reach similar goals.
Recent kernel advances allow to isolate processes from the rest
of the system, presenting them with their own view of the system.
You can package entire other Linux distributions, and with the exception
of the host kernel, all the environment can be different for the process.
From the point of view of the application, it's running on the same hardware
as the host, hence containers are sometimes called
.highlight[operating system level virtualization].
---
# Containers: the good parts
* **Lower operational overhead**
You don't need to run a whole second OS to run an application.
* **Lower startup overhead**
Setup and teardown of a container is much less costly.
* **More hardware flexibility**
You don't have to dedicate a set portion of memory to your VM
well in advance, or contain your files in a fixed-size filesystem.
Also, the level of isolation is up to you. You may present devices
on the system directly to containers if you so desire.
---
# Containers: the not so good parts
* **Kernel compatibility**
Kernel is shared between the host and the container,
so there may be some incompatibilties.
Plus, container support is (relatively) new, so it needs a recent kernel
on the host.
* **Security concerns**
The isolation is thinner than in VM case, and kernel of the host OS
is directly exposed.
* **Linux on Linux**
Containers are inherently a Linux technology. You need a Linux host
(or a Linux VM) to run containers, and only Linux software can run.
---
# History of containers
The idea of running an application in a different environment is not new to UNIX-like systems.
Perhaps the first effort in that direction is the `chroot` command and concept (1982):
presenting applications with a different view of the filesystem (a different root directory `/`).
This minimal isolation was improved in in FreeBSD with `jail` (2000),
separating other resources (processes, users)
and restricting how applications can interact with each other and the kernel.
Linux developed facilities for isolating and controlling access to some processes
with namespaces (2002) and cgroups (2007).
Those facilities led to creation of solutions for containerization, notably LXC (2008),
Docker (2013) and Singularity (2016).
---
# Docker
Docker came about in 2013 and since has been on a meteoric rise
as the golden standard for containerization technology.
A huge amount of tools is built around Docker to build, run,
orchestrate and integrate Docker containers.
Many cloud service providers can directly integrate Docker containers.
Docker claims x26 resource efficiency improvement at cloud scale.
Docker encourages splitting software into microservice chunks
that can be portably used as needed.
---
# Docker concerns
Docker uses a pretty complicated model of images/volumes/metadata,
orchestrating swarms of those containers to work together,
and it not always very transparent with how those are stored.
Also, isolation features require superuser privileges;
Docker has a persistent daemon running with those privileges
and many container operations require root as well.
Both of those issues make Docker undesirable in applications
where you don't wholly own the computing resource - HPC environments.
Out of those concerns, and out of scientific community, came Singularity.
---
# Singularity
Singularity is quite similar in principles to Docker. In fact,
it's pretty straightforward to convert a Docker container
to a Singularity image.
Singularity uses a monolithic, image-file based approach.
Instead of dynamically overlaid "layers" of Docker, you have
a single file you can build once and simply copy over to the target system.
---
# Singularity and root privileges
The privilege problem was a concern from the ground-up, and solved by having a
`setuid`-enabled binary that can accomplish container startup - and drop
privileges completely as soon as practical.
Privilege elevation inside a container is impossible: `setuid` mechanism
is disabled inside the container, so to be root inside,
you have to be root outside. And users don't need explicit root
access to operate containers (at least after the initial build).
---
# Singularity and HPC
Thanks to the above improvements over Docker, HPC cluster operators
are much more welcoming to the idea of Singularity support.
As a result of a joint Pipeline Interoperability project between Swiss Science IT groups,
we have a [set of guidelines](https://goo.gl/hHHYLL)
for Singularity deployment and use by scientific community.
Also as part of this effort, the UniBE Linux cluser UBELIX started support Singularity.
Once your software is packaged in Singularity, it should work across
all Science IT platforms supporting the technology.
---
# Singularity workflow
.minusmargin[
![:scale 100%](assets/singularity-2.4-flow.png)
]
1. Interactively develop steps to construct a container
2. Describe the steps in a recipe.
2. Build an immutable container on own machine.
3. Deploy this container in the production environment.
---
class: center, middle
# Working with Singularity
---
# Installing Singularity
Installing Singularity from source is probably preferred,
as it's still a relatively new piece of software.
Instructions at: https://www.sylabs.io/guides/2.6/user-guide/installation.html#install-a-specific-release
(7 lines of shell commands, use `VER=2.6.0`)
On Ubuntu, packages required are: `build-essential squashfs-tools libarchive-dev`.
.exercise[
If you want to try installing Singularity on your Linux system, follow the build instructions.
You will need root access!
If you're using the remote training machine, skip this step.
]
---
# Using Singularity
If you followed build instructions, you should now have `singularity`
available from the shell.
```
user@host:~$ singularity --version
2.6.0-dist
```
The general format of Singularity commands is:
```
singularity [<global flags>] <command> [<command flags>] [<arguments>]
```
Singularity is pretty sensitive to the order of those.
Use `singularity help [<command>]` to check built-in help.
You can find the configuration of Singularity under `/etc/singularity`
if you used the default prefixes.
---
# Container images
A Singularity image is, for practical purposes, a filesystem tree
that will be presented to the applications running inside it.
A Docker container is built with a series of _layers_ that are
stacked upon each other to form the filesystem. Singularity
collapses those into a single, portable file.
A container needs to be somehow bootstrapped to contain a base
operating system before further modifications can be made.
---
# Pulling Docker images
The simplest way of obtaining a working Singularity image
is to pull it from either Docker Hub or Singularity Hub.
Let's try it with CentOS 6:
```
user@host:~$ singularity pull docker://centos:6
```
This will download the layers of the Docker container to your
machine and assemble them into an image.
---
# Pulling Docker images
```
user@host:~$ singularity pull docker://centos:6
WARNING: pull for Docker Hub is not guaranteed to produce the
WARNING: same image on repeated pull. Use Singularity Registry
WARNING: (shub://) to pull exactly equivalent images.
Docker image path: index.docker.io/library/centos:6
Cache folder set to /home/ubuntu/.singularity/docker
Importing: base Singularity environment
Exploding layer: sha256:1c8f9aa56c90ab24207ff5ca6b853bdbffb40b7801055d0b9c934cb16b5b43dd.tar.gz
Exploding layer: sha256:b98c5d595dc1be386927f4f6e75dc3801f043e38902dcdd7235abf0c79b404b3.tar.gz
WARNING: Building container as an unprivileged user. If you run this container as root
WARNING: it may be missing some functionality.
Building Singularity image...
Singularity container built: ./centos-6.simg
Cleaning up...
```
Note that this .highlight[does not require `sudo` or Docker]!
.exercise[
Pull the CentOS 6 image from Dockerhub with the above command
]
---
# Entering shell in the container
To test our freshly-created container, we can invoke an interactive shell
to explore it with .highlight[`shell`]:
```
user@host:~$ singularity shell centos-6.simg
Singularity: Invoking an interactive shell within container...
Singularity centos-6.simg:~>
```
At this point, you're within the environment of the container.
We can verify we're "running" CentOS:
```
Singularity centos-6.simg:~> cat /etc/centos-release
CentOS release 6.9 (Final)
```
---
# User/group within the container
Inside the container, we are the same user:
```
Singularity centos-6.simg:~> whoami
user
Singularity centos-6.simg:~> exit
user@host:~$ whoami
user
```
We will also have the same groups. That way, if any host resources are mounted
in the container, we'll have the same access privileges.
---
# Root within the container
If we launched `singularity` with `sudo`, we would be `root` inside the container.
```
user@host:~$ sudo singularity shell centos-6.simg
Singularity: Invoking an interactive shell within container...
Singularity centos-6.simg:~> whoami
root
```
Note that the `pull` command complained that building without root does not guarantee
that `root` inside will work as expected.
**Most importantly:** `setuid` mechanism will not work within the container.
Once launched as non-root, no command can elevate your privileges.
---
# Default mounts
Additionally, by default:
* our home folder,
* `/tmp`,
* `/dev`,
* the folder we've invoked Singularity from
are accessible inside the container:
```
user@host:~$ singularity shell centos-6.simg
Singularity centos-6.simg:~> ls ~
[..lists home folder..]
Singularity centos-6.simg:~> touch ~/test_container
Singularity centos-6.simg:~> exit
user@host:~$ ls ~/test_container
/home/user/test_container
```
The current working directory inside the container is the same
as outside at launch time.
---
# Running a command directly
Besides the interactive shell, we can execute any command
inside the container directly with .highlight[`exec`]:
```
user@host:~$ singularity exec centos-6.simg cat /etc/centos-release
CentOS release 6.9 (Final)
```
.exercise[
Invoke the `python` interpreter with `exec`.
Compare the version with the host system.
]
---
# STDIO with container processes
Standard input/output are processed as normal by Singularity.
You can redirect them:
```
ubuntu@host:~$ singularity exec centos-6.simg echo Boo > ~/test_container
ubuntu@host:~$ singularity exec centos-6.simg cat < ~/test_container
Boo
```
You can use containers in pipelines:
```
$ singularity exec centos-6.simg echo Boo | singularity exec centos-6.simg cat
Boo
```
.exercise[
Count the number of words in host's `ls /etc`'s output using container's copy of `wc`,
then the other way around. Hint:
```
ls /etc | wc -w
```
]
---
# Modifying the container
Let's try to install some software in the container. We will need root:
```
user@host:~$ sudo singularity shell centos-6.simg
Singularity centos-6.simg:~> whoami
root
Singularity centos-6.simg:~> fortune
bash: fortune: command not found
```
We cannot appeal to the wisdom of `fortune`, and that will not do! Let's install it.
```
Singularity centos-6.simg:~> yum -y --enablerepo=extras install epel-release
[...]
Singularity centos-6.simg:~> yum -y install fortune-mod
[...]
Singularity centos-6.simg:~> fortune
[a random fortune cookie text]
```
---
# Modifying the container
Perfect! Let's exit the container.
```
Singularity centos-6.simg:~> exit
exit
user@host:~$
```
We should now be able to use fortune at will:
```
user@host:~$ singularity exec centos-6.simg fortune
```
.exercise[
Try the above!
]
---
# Modifying the container?..
Perfect! Let's exit the container.
```
Singularity centos-6.simg:~> exit
exit
user@host:~$
```
We should now be able to use fortune at will:
```
user@host:~$ singularity exec centos-6.simg fortune
/.singularity.d/actions/exec: line 9: exec: fortune: not found
```
Wait, what?
```
user@host:~$ singularity shell centos-6.simg
Singularity centos-6.simg:~> fortune
bash: fortune: command not found
```
What happened to our modifications?
---
# Images and overlays
The image Singularity creates is normally read-only.
While any changes that happen to bind-mounted folders from the host will persist,
any changes to the container's filesystem itself are not saved.
Before 2.4, Singularity would just produce write errors; now, it .highlight[temporarily]
applies the changes (as an "overlay"), which are then discarded when your session ends.
---
# Writing to the image
`shell` and `exec` have a `--writable` flag.
Looks like what we need! Let's try again:
```
user@host:~$ sudo singularity shell --writable centos-6.simg
```
---
# Writing to the image?..
`shell` and `exec` have a `--writable` flag.
Looks like what we need! Let's try again:
```
user@host:~$ sudo singularity shell --writable centos-6.simg
ERROR : Unable to open squashfs image in read-write mode: Read-only file syst
em
ABORT : Retval = 255
```
Well, that didn't work either.
Why? And how _do_ we write to an image?
---
# Mutable vs immutable containers
Since 2.4, Singularity has 2 types of containers:
1. Mutable containers. Those are either loose collections of files in a directory,
or ext3-formatted images (deprecated).
2. Immutable containers. Those are compressed, read-only squashfs images.
The purpose of mutable containers is to interactively develop a "recipe" for a container,
that will be then converted to an immutable "final" form.
`pull` will create immutable containers; for mutable ones, we need `build`.
---
# Creating a writable container
Let's remove our immutable container and build a sandbox container:
```
$ rm centos-6.simg
$ sudo singularity build --sandbox centos-writable docker://centos:6
```
This is just a collection of files in `./centos-writable` folder
that represents the root of the filesystem:
```
user@host:~$ ls centos-writable/
bin dev environment etc home lib lib64 lost+found media mnt opt
proc root sbin selinux singularity srv sys tmp usr var
```
---
# Writing to a container, finally:
We should now be able to enter it **in writable mode** and install software
(fortune, and text editors for the next step):
```
user@host:~$ sudo singularity shell --writable centos-writable
Singularity centos-writable:~> yum -y --enablerepo=extras install epel-release
[...]
Singularity centos-writable:~> yum -y install fortune-mod vim nano
[...]
Singularity centos-writable:~> exit
user@host:~$ singularity exec centos-writable fortune
[some long-awaited wisdom of a fortune cookie]
```
---
# Giving container purpose
A container can have a "default" command which is run without specifying it.
Inside the container, it's `/singularity`. Let's try modifying it:
```
user@host:~$ sudo singularity exec -w centos-writable vim /singularity
```
By default you'll see the following:
```bash
#!/bin/sh
exec /bin/bash "$@"
```
This is a script that will pass all arguments to `/bin/bash`.
---
# Giving container purpose
We installed `fortune`, so let's use that instead:
```bash
#!/bin/sh
exec /usr/bin/fortune "$@"
```
.exercise[
Make the same modification to your container.
]
Now we can invoke it with .highlight[`run`]:
```
user@host:~$ singularity run centos-writable
[..some wisdom or humor..]
```
---
# Converting to final container
One way to produce a "final" container is to convert it from the sandbox version:
```
user@host:~$ sudo singularity build fortune.simg centos-writable
[...]
```
Now we can test our container:
```
user@host:~$ singularity run fortune.simg
[..some more wisdom..]
```
---
# Running a container directly
Note that the container file is executable:
```
user@host:~$ ls -lh fortune.simg
-rwxr-xr-x 1 root root 99M Feb 30 13:37 fortune.simg
```
If we run it directly, it's the same as invoking `run`:
```
user@host:~$ ./fortune.simg
[..a cracking joke..]
```
This does require to have `singularity` installed on the host, however, and is just a convenience.
---
# Making the container reproducible
Instead of taking some base image and making changes to it by hand,
we want to make this build process reproducible.
This is achieved with definition files called .highlight[Recipes].
Let's try to retrace out steps to obtain a fortune-telling CentOS.
.exercise[
Open a file called `fortune.def` in an editor, and prepare to copy along.
]
---
# Bootstrapping
The definition file starts with a header section.
The key part of it is the `Bootstrap:` configuration,
which defines how we obtain the "base" image.
There are 3 currently types of bootstrap methods:
* using `yum`/`apt`/`pacman` etc. on the host system to bootstrap a similar one
* pull an image: `docker` (from Docker Hub) or `shub` (from Singularity Hub)
* `localimage` to base off another image on your computer
We'll be using the Docker method.
```
Bootstrap: docker
From: centos:6
```
---
# Setting up the container
There are 2 sections for setup commands (essentially shell scripts):
1. .highlight[`%setup`] for commands to be executed .highlight[outside the container].
You can use `$SINGULARITY_ROOTFS` to access the container's filesystem,
as it is mounted on the host during the build.
2. .highlight[`%post`] for commands to be executed .highlight[inside] the container.
This is a good place to set up the OS, such as installing packages.
---
# Setting up the container
Let's save the name of the build host and install `fortune`:
```
Bootstrap: docker
From: centos:6
%setup
hostname -f > $SINGULARITY_ROOTFS/etc/build_host
%post
yum -y --enablerepo=extras install epel-release
yum -y install fortune-mod
```
---
# Adding files to the container
An additional section, .highlight[`%files`], allows to copy files or folders to the container.
**We won't be using it here**, but the format is very similar to `cp`,
with sources being outside and the final destination beiong inside the container:
```
%files
some/file /some/other/file some/path/
some/directory some/path/
```
Note that this happens _after_ `%post`. If you need the files earlier, copy them manually in `%setup`.
---
# Setting up the environment
You can specify a script to be sourced when something is run in the container.
This goes to the .highlight[`%environment`] section. Treat it like `.bash_profile`.
```
%environment
export HELLO=World
```
Note that by defaut, the host environment variables are passed to the container.
To disable it, use `-e` when running the container.
---
# Setting up the runscript
The runscript (`/singularity`) is specified in the `%runscript` section.
Let's use the file we copied at `%setup` and run `fortune`:
```
%runscript
read host < /etc/build_host
echo "Hello, $HELLO! Fortune Teller, built by $host"
exec /usr/bin/fortune "$@"
```
---
# Testing the built image
You can specify commands to be run at the end of the build process inside the container
to perform sanity checks.
Use `%test` section for this:
```
%test
test -f /etc/build_host
test -x /usr/bin/fortune
```
All commands must return successfully or the build will fail.
---
# The whole definition file
```
Bootstrap: docker
From: centos:6
%setup
hostname -f > $SINGULARITY_ROOTFS/etc/build_host
%post
yum -y --enablerepo=extras install epel-release
yum -y install fortune-mod
%environment
export HELLO="World"
%runscript
read host < /etc/build_host
echo "Hello, $HELLO! Fortune Teller, built by $host"
exec /usr/bin/fortune "$@"
%test
test -f /etc/build_host
test -x /usr/bin/fortune
```
.exercise[
Check that your `fortune.def` is the same as above.
]
---
# Building a container from definition
To fill a container using a definition file, we invoke `build`:
```
user@host:~$ rm fortune.simg
user@host:~$ sudo singularity build fortune.simg fortune.def
[...]
```
.exercise[
1. Bootstrap the image as shown above.
2. Test running it directly.
]
---
# Inspecting a container
If a container was built from a Recipe, it has some metadata you can read:
```
user@host:~$ singularity inspect fortune.simg
{
"org.label-schema.usage.singularity.deffile.bootstrap": "docker",
"vendor": "CentOS",
"name": "CentOS Base Image",
[...]
```
You can inspect the original Recipe:
```
user@host:~$ singularity inspect -d fortune.simg
Bootstrap: docker
From: centos:6
%setup
hostname -f > $SINGULARITY_ROOTFS/etc/build_host
[...]
```
See `singularity help inspect` for more options, and `/.singularity.d/`
inside the container to see how it's all stored.
---
# Host resources
A container can have more host resources exposed.
For providing access to more directories,
one can specify bind options at runtime with `-B`:
```
$ singularity run -B source[:destination[:mode]] container.simg
```
where .highlight[source] is the path on the host,
.highlight[destination] is the path in a container (if different)
and .highlight[mode] is optionally `ro` if you don't want to give write access.
Of course, more than one bind can be specified.
Note that you can't specify this configuration in the container!
System administrators may specify binds that apply to all containers (e.g. `/scratch`).
---
# Host resources
Additionally, devices on the host can be exposed, e.g. the GPU; but you need to make
sure that the guest has the appropriate drivers. One solution is to bind the drivers on the container.
For Nvidia CUDA applications specifically, Singularity supports the `--nv` flag, which looks for
specific libraries on the host and binds them in the container.
-----
OpenMPI should also work, provided the libraries on the host and in the container are sufficiently close.
If set up correctly, it should work normally with `mpirun`:
```
$ mpirun -np 20 singularity run mpi_job.simg
```
---
# Fuller isolation
By default, a container is allowed a lot of "windows" into the host system (dictated by Singularity configuration).
For an untrusted container, you can further restrict this with options like `--contain`, `--containall`.
In this case, you have to manually define where standard binds like the home folder or `/tmp` point.
See `singularity help run` for more information.
---
exclude: true
# TODO: Lightweight OSes for containers
---
# Distributing the container
Using the container after creation on another Linux machine is simple:
you simply copy the image file there.
Note that you can't just run the image file on a host without Singularity installed!
.exercise[
Test the above, by trying to run `fortune.simg` inside itself.
]
You can easily integrate Singularity with the usual scheduler scripts (e.g. Slurm).
---
# Using Singularity Hub
Singularity Hub allows you to cloud-build your containers from Bootstrap files,
which you can then simply `pull` on a target host.
This requires a GitHub repository with a `Singularity` definition file.
After creating an account and connecting to the GitHub account,
you can select a repository and branches to be built.
Afterwards, you can pull the result:
```
user@host:~$ singularity pull shub://kav2k/fortune
[...]
Done. Container is at: /home/user/kav2k-fortune-master.simg
user@host:~$ ./kav2k-fortune-master.simg
Hello, World! Fortune Teller, built by shub-builder-1450-kav2k-fortune-[...]
```
---
# Running on UBELIX
From a practical standpoint, we want to use the container technology on UBELIX.
Let's try with our toy container:
```
user@host:~$ ssh username@submit.unibe.ch
username@submit01:~$ singularity pull shub://kav2k/fortune
username@submit01:~$ sbatch -J fortune-test -t 00:00:10
--mem-per-cpu 100M --cpus 1 --wrap "./kav2k-fortune-master-latest.simg"
```
---
# Docker and Singularity
Instead of writing a Singularity file, you may write a `Dockerfile`,
build a Docker container and convert that.
Pros:
* More portable: for some, using Docker or some other container solution is preferable.
* Easier private hosting: private version of Singularity Hub, `sregistry`, is still not mature.
Cons:
* Blackbox: Singularity understands less about the build process, in terms of container metadata.
* Source of bugs: Sadly, Docker pull is not perfect and may result in bugs.
* Complexity: Extra tool to learn if you don't know Docker.
---
# Docker -> Singularity
If you have a Docker image you want to convert to Singularity,
you have at least two options:
1. Upload the image to a Docker Registry (such as Docker Hub)
and `pull`/`Bootstrap` from there.
2. Use a local copy of a Docker registry to not rely on external services
---
class: center, middle
# "Extra credit" topics
---
# Reducing container size
Using traditional Linux distributions, even in minimal configurations,
can still be an overkill for running a single application.
One can reduce container size by clearing various artifacts of the build
process, such as package manager caches.
Alternatively, one can use minimal Linux distributions, such as Alpine Linux,
as a base for containers, though compatibility needs extra testing.
```
$ ll -h
-rwxr-xr-x 1 user group 66M Jun 25 15:04 centos-6.simg*
-rwxr-xr-x 1 user group 2.0M Jun 25 16:08 alpine.simg*
```
---
# Singularity Instances
Running daemon-like persistent services with Singularity (such as a web server)
can conveniently be done with the concept of Instances.
A `%startscript` section of the recipe describes what service to launch,
which subsequently works with `instance.*` commands:
```
$ singularity instance.start nginx.simg web
$ singularity instance.list
INSTANCE NAME PID CONTAINER IMAGE
web 790 /home/mibauer/nginx.simg
$ singularity instance.stop web
```
While an instance is running, the standard commands like `shell` and `exec`
work with an `instance://` namespace.
---
# Persistent Overlays
As was shown before, once you create a "final" image it can no longer be changed,
and all writes go to a temporary overlay.
If needed, such changes can be persisted in a separate permanent overlay file:
```
$ singularity image.create my-overlay.img
$ sudo singularity shell --overlay my-overlay.img ubuntu.simg
[ changes made will persist if launched with the same --overlay ]
```
---
# SCI-F
One of the approaches for building scientific pipelines is bundling several tools
in a single "toolset" container.
SCI-F is a proposed standard for discovering and managing tools within
such modular containers.
Definition file can have several sections, e.g.:
```
%appenv foo
BEST_GUY=foo
export BEST_GUY
%appenv bar
BEST_GUY=bar
export BEST_GUY
%apprun foo
echo The best guy is $BEST_GUY
%apprun bar
echo The best guy is $BEST_GUY
```
---
# SCI-F
You can then discover the apps bundled and run them:
```
$ singularity apps foobar.simg
bar
foo
$ singularity run --app bar foobar.simg
The best guy is bar
```
More sections can be made app-specific, including providing a `help` description:
```
$ singularity help --app fortune moo.simg
fortune is the best app
```
---
# Singularity Checks
A container check is a utility script that can verify a container.
Example uses:
* Making sure no leftover artifacts from the build process remains (e.g. root's bash history)
* Testing for common vulnerabilities
* Custom checks for your specific environment
```
$ singularity check --tag clean ubuntu.img
```
---
class: center, middle
# Questions?
---
exclude: true
# Runner script
We have developed a small runner script that allows to specify
a lot of "external" metadata (like bind commands or image size)
in a single configuration file alongside other bootstrap files,
as well as scripts to run on the host to run/validate the container.
You can install it with `pip install singularity-pipeline`
Documentation and samples available at https://c4science.ch/diffusion/2915/browse/master/UniBe/
Consider it still in alpha, but it helps writing down the metadata
for a scientific pipeline.
</textarea>
<script src="js/vendor/remark.min.js"></script>
<script src="js/vendor/jquery-3.2.1.min.js"></script>
<script src="js/terminal.language.js"></script>
<script src="js/common.js"></script>
<script src="js/linux_1.js"></script>
</body>
</html>

Event Timeline