Skip to content

UDocker: CESGA user's guide

victorsndvg edited this page Feb 24, 2017 · 1 revision

Udocker

User guide (Cesga)

Introduction

As we can see in the official documentation:

  • uDocker is a basic user tool able to execute containers in user space without requiring root privileges.
  • A Docker installation is not required, so it is useful in systems where the installation is not possible due to system requirements like kernel version.
  • uDocker allow us download and execute docker containers by non-privileged users.

Usage in Finis Terrae II Supercomputer

In this section we aboard the basic usage in the CESGA main supercomputation infraestructure. We can summarize the main points in the following list,

  • Load udocker as a module

    [pdiaz@fs6801 ~]$ module load udocker/1.0.0
    udocker/1.0.0 loaded
  • Once loaded the module, the acces to the main manual page can be displayed using the --help option

    [pdiaz@fs6801 ~]$ udocker.py --help
  • We can list the CESGA local images repository with the imagescommand

    [pdiaz@fs6801 ~]$ udocker.py images
    REPOSITORY
    tensorflow/tensorflow:latest                                 .
    tensorflow/tensorflow:0.12.0-rc0                             .
    tensorflow/tensorflow:latest-gpu                             .
  • And which containers are avaible in the local repo using the pscommand

    [pdiaz@fs6801 ~]$ udocker.py ps
    CONTAINER ID                         P M NAMES              IMAGE
    ce6ea3b4-7a3e-3b49-a6db-cb55f64575d0 . R ['tf']             tensorflow/tensorflow:latest
    4fa3d9f1-6198-30e4-8681-cbc00b904d25 . R ['tf2']            tensorflow/tensorflow:0.12.0-rc0
    54253cfe-5bce-3b0a-8e87-ac31db761a84 . R ['tf-gpu']         tensorflow/tensorflow:latest-gpu
  • We can deploy a container in one of the login-nodes or in a interactive session using the command run as in the following example (e.g. in the fs6801 login node):

    [pdiaz@fs6801 ~]$ udocker.py run [options] <container-id-or-name>

    The list of available options of the run command can be displayed using the [command] --helpoption

    [pdiaz@fs6801 ~]$ udocker.py run --help
    run: execute a container
    run [options] <container-id-or-name>
    --rm                       :delete container upon exit
    --workdir=/home/userXX     :working directory set to /home/userXX
    --user=userXX              :run as userXX
    --user=root                :run as root
    --volume=/data:/mnt        :run mounting host directory /data in /mnt
    --novol=/proc              :remove /proc from list of volumes to mount
    --env="MYTAG=xxx"          :set environment variable
    --hostauth                 :bind the host /etc/passwd /etc/group ...
    --nosysdirs                :do not bind the host /proc /sys /run /dev
    --nometa                   :ignore container metadata
    --dri                      :bind directories relevant for dri graphics
    --hostenv                  :pass the host environment to the container
    --cpuset-cpus=<1,2,3-4>    :pass the host environment to the container
    --name=<container-name>    :set or change the name of the container
    --bindhome                 :bind the home directory into the container
    --location=<path-to-dir>   :use root tree outside the repository
    --kernel=<kernel-id>       :use this Linux kernel identifier
Using containers not available in the local repo

By default, the udocker installation point to a local repo managed by CESGA admins, you can see this path viewing the UDOCKER_DIR env variable

[pdiaz@fs6801 ~]$ echo $UDOCKER_DIR 
/opt/cesga/udocker/localrepo

this repo does not have write permissions for our users, so if you want to create your local repository in your own home do the following steps:

  • With mkrepowe can create a new user repository

    [pdiaz@fs6801 ~]$ udocker.py mkrepo $HOME/repo_local
    

    It would be interesting use $LUSTRE filesystem

    $ udocker.py --repo=$HOME/repo_local ps
    Info : installing udockertools ...
    CONTAINER ID P M NAMES IMAGE
    
  • Point the UDOCKER_DIRenv variable to this directory

    [pdiaz@fs6801 ~]$ export UDOCKER_DIR=/home/cesga/pdiaz/.udocker
    

    At this point is important to focus that udocker cannot see two repositories simultaneously, so the UDOCKER_DIR variable must point to one directory at time.

  • Now we can see the contents of our local repository, by default this repo is empty, this is a example case with some image examples

    [pdiaz@fs6801 ~]$ udocker.py images
    REPOSITORY
    ubuntu:latest                                                .
    centos:latest                                                .
    mopac/docker-whale:latest                                    .
    nvidia/cuda:latest                                           .
    fedora:latest                                                .
    
  • And list our own created containers with the ps command, this is an example case,

    [pdiaz@fs6801 ~]$ udocker.py ps
    CONTAINER ID                         P M NAMES              IMAGE
    843a601f-158a-3734-ab7c-2036e7bb37a4 . W ['test01']         ubuntu:latest
    01ef1238-1d8a-39da-9686-e1af5f4b0e34 . W ['test02']         centos:latest
    815e9555-2f7f-3c1c-89b7-a16b10e8a8c4 . W ['mopacmachine']   mopac/docker-whale:latest
    4d67976d-8379-3edb-abdf-fa695ffc775e . W ['nvidiatest']     nvidia/cuda:latest
    7f2de619-ac59-3dc1-b851-704a297fa8bf . W ['fedora24']       fedora:latest
    
How to search for container images in the docker-hub
[pdiaz@fs6801 ~]$ udocker.py search [OPTIONS] REPO/IMAGE:TAG
[pdiaz@fs6801 ~]$ udocker.py search fedora
[pdiaz@fs6801 ~]$ udocker.py search ubuntu
How to pull an image from the docker-hub
[pdiaz@fs6801 ~]$ udocker.py pull [OPTIONS] REPO/IMAGE:TAG
[pdiaz@fs6801 ~]$ udocker.py pull fedora
[pdiaz@fs6801 ~]$ udocker.py pull ubuntu:latest
How to list images in the local repository

Once created our private repository,

[pdiaz@fs6801 ~]$ udocker.py images
How to create a container from a image

We can use with the command create the option --name= to choose a easier name than the default given by udocker, for example, for a previously pulled ubuntu image

[pdiaz@fs6801 ~]$ udocker.py create --name=test01 ubuntu
[pdiaz@fs6801 ~]$ udocker.py ps
CONTAINER ID                         P M NAMES       IMAGE
843a601f-158a-3734-ab7c-2036e7bb37a4 . W [’test01’]  ubuntu:latest

In the previous box we can see the CONTAINER ID given by udocker and the easier name given by us through the --name= option

How to delete a previously pulled image from our local repository
[pdiaz@fs6801 ~]$ udocker.py rmi REPO/IMAGE:TAG
[pdiaz@fs6801 ~]$ udocker.py rmi ubuntu:latest
How to delete containers from our local repo

We can delete it through the CONTAINER-ID or using the name given by us

udocker.py rm CONTAINER-ID
udocker.py rm NAME

e.g.

udocker.py rm 843a601f-158a-3734-ab7c-2036e7bb37a4
udocker.py rm test01
How to view the metadata of a container
udocker.py inspect CONTAINER-ID or NAME

With the -p option we can see the path to the /root directory,

[pdiaz@fs6801 ~]$ udocker.py inspect -p tf
/opt/cesga/udocker/localrepo/containers/ce6ea3b4-7a3e-3b49-a6db-cb55f64575d0/ROOT
Rename containers

We can add more than one name to a given container,

[pdiaz@fs6801 ~]$ udocker.py name CONTAINER-ID NAME

To delete a name, the syntax is the same, without the CONTAINER-ID field

[pdiaz@fs6801 ~]$ udocker.py rmname NAME
Create a local repository in a specific directory

The syntax is,

udocker.py mkrepo DIRECTORY

This command creates a udocker local repository in a specific directory different than the default one which is set when the udocker module is loaded. This option can be used to place containers in another filesystem in which the regular users have write permissions. By default, the UDOCKER_DIR env variable points to a private repository managed by the CESGA staff, which does not have write permissions for regular users due to technical reasons. The created repository can be accessed with udocker.py --repo=DIRECTORY COMMAND

Container execution

The following steps are the default udocker options, but we strongly recommend use the script run_udocker.sh developed by the CESGA applications staff.

Default (with udocker.py)

As we can see in previous examples, the execution of containers is done through CONTAINER-ID or the given NAME. Also we can deploy a container starting from its image, dispensing the create command,

udocker.py run [OPTIONS] CONTAINER-ID|CONTAINER-NAME
udocker.py run [OPTIONS] REPO/IMAGE:TAG

The run command can be used with the following options,

  • --rm Deletes the container after the execution.
  • --workdir=PATH Specifies the working directory within the container
  • --volume=DIR:DIR Map an host file or directory to appear inside the container
  • --novol=DIR Excludes the host file or directory from being mapped inside the container
  • --env="VAR=VAL" To set environment variables
  • --hostenvPass the user host environment to the container
  • --name=NAME To set or change the name of the container, useful when running from an image
  • --kernel=KERNELID use a specific kernel id to emulate useful when the host kernel is too old
  • --location=DIR Execute a container in a certain directory

More options in the official documentation at [https://github.com/indigo-dc/udocker]

Usage of run_udocker.sh script (RECOMMENDED OPTION)

This script maps automatically several filesystems which belongs to us, also maps our user inside the container, for other purposes (access as root to make an installation, for example) use the udocker.py run option

$ export UDOCKER_DIR=$HOME/repo_local
$ run_udocker.sh test01

Note: only export the UDOCKER_DIR variable if you want to use your own repository set in the $HOME/repo_local path

Examples

Make an installation inside a container

Access to the container as --user=root without discovering host directories or select workig directory

$ udocker.py run --user=root test01
[...]
01ef1238[~]# yum search firefox
01ef1238[~]# yum install hostname.x86_64
Executing a container mounting several directories as a specific user
[pdiaz@fs6801 ~]$ udocker.py run --volume=/opt --volume=/home/cesga/pdiaz
--workdir=/home/cesga/pdiaz --user=pdiaz test01 /bin/bash
Warning: non-existing user will be created
******************************************************************************
*                                                                            *
*              STARTING 01ef1238-1d8a-39da-9686-e1af5f4b0e34                 *  
*                                                                            * 
******************************************************************************
executing: bash
01ef1238[pdiaz]$ ls -l
total 240
drwxr-xr-x 2 pdiaz pdiaz 1024 Oct 24 07:51 MPI
drwxr-xr-x 3 pdiaz pdiaz 80 Sep 27 10:57 TRAINING
drwxr-xr-x 6 pdiaz pdiaz 1024 Jul 4 11:42 benchmarks
-rwxr-xr-x 1 pdiaz pdiaz 534 Oct 11 09:27 drain_nodes.sh
-rwxr-xr-x 1 pdiaz pdiaz 164 Oct 25 15:28 interactive_udocker.sh
-rwx------ 1 pdiaz pdiaz 247 Oct 18 10:28 parse.sh
drwxr-xr-x 5 pdiaz pdiaz 1024 Oct 26 14:40 udocker
01ef1238[pdiaz]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
Using containers in the Finis Terrae II job scheduling system

Finis Terrae II uses the Slurm job scheduling system. It is possible the execution of a container in a compute node using Slurm, as we can see in the following example, where the $UDOCKER_DIR value was changed to point the user local repository

#!/bin/bash
#SBATCH -N 1             #(request 1 node)
#SBATCH -n 1             #(1 task)
#SBATCH -t 00:03:00      #(3 min time execution)
#SBATCH -p thinnodes     #(Parititon)

module load udocker

#To point to our local repository
export UDOCKER_DIR=$HOME/repo_local

run_udocker.sh test01 /bin/bash script_with_commands.sh

In the file script_with_commands.sh we put all the commands which we want to run inside the container, for example,

srun --cpu-freq=High <some_application> <some_input> > output.txt