|
| 1 | +## Hour 2 (Building and Running Containers) |
| 2 | + |
| 3 | +In the second hour we will build the preceding container from scratch. |
| 4 | + |
| 5 | +Simply typing `singularity` will give you an summary of all the commands you can use. Typing `singularity help <command>` will give you more detailed information about running an individual command. |
| 6 | + |
| 7 | +### Building a basic container |
| 8 | + |
| 9 | +To build a singularity container, you must use the `build` command. The `build` command installs an OS, sets up your container's environment and installs the apps you need. To use the `build` command, we need a **recipe file** (also called a definition file). A Singularity recipe file is a set of instructions telling Singularity what software to install in the container. |
| 10 | + |
| 11 | +The Singularity source code contains several example definition files in the `/examples` subdirectory. Let's copy the ubuntu example to our home directory and inspect it. |
| 12 | + |
| 13 | +``` |
| 14 | +$ mkdir ../lolcow |
| 15 | +
|
| 16 | +$ cp examples/ubuntu/Singularity ../lolcow/ |
| 17 | +
|
| 18 | +$ cd ../lolcow |
| 19 | +
|
| 20 | +$ nano Singularity |
| 21 | +``` |
| 22 | + |
| 23 | +Edit it until it looks like this: |
| 24 | + |
| 25 | +``` |
| 26 | +BootStrap: debootstrap |
| 27 | +OSVersion: xenial |
| 28 | +MirrorURL: http://us.archive.ubuntu.com/ubuntu/ |
| 29 | +
|
| 30 | +
|
| 31 | +%runscript |
| 32 | + echo "This is what happens when you run the container..." |
| 33 | +
|
| 34 | +
|
| 35 | +%post |
| 36 | + echo "Hello from inside the container" |
| 37 | + sed -i 's/$/ universe/' /etc/apt/sources.list |
| 38 | + apt-get update |
| 39 | + apt-get -y install vim |
| 40 | + apt-get clean |
| 41 | +
|
| 42 | +``` |
| 43 | + |
| 44 | +See the [Singularity docs](http://singularity.lbl.gov/docs-recipes) for an explanation of each of these sections. |
| 45 | + |
| 46 | +Now let's use this recipe file as a starting point to build our `lolcow.img` container. Note that the build command requires `sudo` privileges, when used in combination with a recipe file. |
| 47 | + |
| 48 | +``` |
| 49 | +$ sudo singularity build --sandbox lolcow Singularity |
| 50 | +``` |
| 51 | + |
| 52 | +The `--sandbox` option in the command above tells Singularity that we want to build a special type of container for development purposes. |
| 53 | + |
| 54 | +Singularity can build containers in several different file formats. The default is to build a [squashfs](https://en.wikipedia.org/wiki/SquashFS) image. The squashfs format is compressed and immutable making it a good choice for reproducible, production-grade containers. |
| 55 | + |
| 56 | +But if you want to shell into a container and tinker with it (like we will do here), you should build a sandbox (which is really just a directory). This is great when you are still developing your container and don't yet know what should be included in the recipe file. |
| 57 | + |
| 58 | +When your build finishes, you will have a basic Ubuntu container saved in a local directory called `lolcow`. |
| 59 | + |
| 60 | +### Using `shell` to explore and modify containers |
| 61 | + |
| 62 | +Now let's enter our new container and look around. |
| 63 | + |
| 64 | +``` |
| 65 | +$ singularity shell lolcow |
| 66 | +``` |
| 67 | + |
| 68 | +Depending on the environment on your host system you may see your prompt change. Let's look at what OS is running inside the container. |
| 69 | + |
| 70 | +``` |
| 71 | +Singularity lolcow:~> cat /etc/os-release |
| 72 | +NAME="Ubuntu" |
| 73 | +VERSION="16.04 LTS (Xenial Xerus)" |
| 74 | +ID=ubuntu |
| 75 | +ID_LIKE=debian |
| 76 | +PRETTY_NAME="Ubuntu 16.04 LTS" |
| 77 | +VERSION_ID="16.04" |
| 78 | +HOME_URL="http://www.ubuntu.com/" |
| 79 | +SUPPORT_URL="http://help.ubuntu.com/" |
| 80 | +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" |
| 81 | +UBUNTU_CODENAME=xenial |
| 82 | +``` |
| 83 | + |
| 84 | +No matter what OS is running on your host, your container is running Ubuntu 16.04! |
| 85 | + |
| 86 | +Let's try a few more commands: |
| 87 | + |
| 88 | +``` |
| 89 | +Singularity lolcow:~> whoami |
| 90 | +dave |
| 91 | +
|
| 92 | +Singularity lolcow:~> hostname |
| 93 | +hal-9000 |
| 94 | +``` |
| 95 | + |
| 96 | +This is one of the core features of Singularity that makes it so attractive from a security standpoint. The user remains the same inside and outside of the container. |
| 97 | + |
| 98 | +Let's try installing some software. I used the programs `fortune`, `cowsay`, and `lolcat` to produce the container that we saw in the first demo. |
| 99 | + |
| 100 | +``` |
| 101 | +Singularity lolcow:~> sudo apt-get update && sudo apt-get -y install fortune cowsay lolcat |
| 102 | +bash: sudo: command not found |
| 103 | +``` |
| 104 | + |
| 105 | +Whoops! |
| 106 | + |
| 107 | +Singularity complains that it can't find the `sudo` command. But even if you try to install `sudo` or change to root using `su`, you will find it impossible to elevate your privileges within the container. |
| 108 | + |
| 109 | +Once again, this is an important concept in Singularity. If you enter a container without root privileges, you are unable to obtain root privileges within the container. This insurance against privilege escalation is the reason that you will find Singularity installed in so many HPC environments. |
| 110 | + |
| 111 | +Let's exit the container and re-enter as root. |
| 112 | + |
| 113 | +``` |
| 114 | +Singularity lolcow:~> exit |
| 115 | +
|
| 116 | +$ sudo singularity shell --writable lolcow |
| 117 | +``` |
| 118 | + |
| 119 | +Now we are the root user inside the container. Note also the addition of the `--writable` option. This option allows us to modify the container. The changes will actually be saved into the container and will persist across uses. |
| 120 | + |
| 121 | +Let's try installing some software again. |
| 122 | + |
| 123 | +``` |
| 124 | +Singularity lolcow:~> apt-get update && apt-get -y install fortune cowsay lolcat |
| 125 | +``` |
| 126 | + |
| 127 | +Now you should see the programs successfully installed. Let's try running the demo in this new container. |
| 128 | + |
| 129 | +``` |
| 130 | +Singularity lolcow:~> fortune | cowsay | lolcat |
| 131 | +bash: lolcat: command not found |
| 132 | +bash: cowsay: command not found |
| 133 | +bash: fortune: command not found |
| 134 | +``` |
| 135 | + |
| 136 | +Drat! It looks like the programs were not added to our `$PATH`. Let's add them and try again. |
| 137 | + |
| 138 | +``` |
| 139 | +Singularity lolcow:~> export PATH=/usr/games:$PATH |
| 140 | +
|
| 141 | +Singularity lolcow:~> fortune | cowsay | lolcat |
| 142 | +perl: warning: Setting locale failed. |
| 143 | +perl: warning: Please check that your locale settings: |
| 144 | + LANGUAGE = (unset), |
| 145 | + LC_ALL = (unset), |
| 146 | + LANG = "en_US.UTF-8" |
| 147 | + are supported and installed on your system. |
| 148 | +perl: warning: Falling back to the standard locale ("C"). |
| 149 | + ________________________________________ |
| 150 | +/ Keep emotionally active. Cater to your \ |
| 151 | +\ favorite neurosis. / |
| 152 | + ---------------------------------------- |
| 153 | + \ ^__^ |
| 154 | + \ (oo)\_______ |
| 155 | + (__)\ )\/\ |
| 156 | + ||----w | |
| 157 | + || || |
| 158 | +``` |
| 159 | + |
| 160 | +We're making progress, but we are now receiving a warning from perl. However, before we tackle that, let's think some more about the `$PATH` variable. |
| 161 | + |
| 162 | +We changed our path in this session, but those changes will disappear as soon as we exit the container just like they will when you exit any other shell. To make the changes permanent we should add them to the definition file and re-bootstrap the container. We'll do that in a minute. |
| 163 | + |
| 164 | +Now back to our perl warning. Perl is complaining that the locale is not set properly. Basically, perl wants to know where you are and what sort of language encoding it should use. Should you encounter this warning you can probably fix it with the `locale-gen` command or by setting `LC_ALL=C`. Here we'll just set the environment variable. |
| 165 | + |
| 166 | +``` |
| 167 | +Singularity lolcow:~> export LC_ALL=C |
| 168 | +
|
| 169 | +Singularity lolcow:~> fortune | cowsay | lolcat |
| 170 | + _________________________________________ |
| 171 | +/ FORTUNE PROVIDES QUESTIONS FOR THE \ |
| 172 | +| GREAT ANSWERS: #19 A: To be or not to | |
| 173 | +\ be. Q: What is the square root of 4b^2? / |
| 174 | + ----------------------------------------- |
| 175 | + \ ^__^ |
| 176 | + \ (oo)\_______ |
| 177 | + (__)\ )\/\ |
| 178 | + ||----w | |
| 179 | + || || |
| 180 | +``` |
| 181 | + |
| 182 | +Great! Things are working properly now. |
| 183 | + |
| 184 | +Although it is fine to shell into your Singularity container and make changes while you are debugging, you ultimately want all of these changes to be reflected in your recipe file. Otherwise if you need to reproduce it from scratch you will forget all of the changes you made. |
| 185 | + |
| 186 | +Let's update our definition file with the changes we made to this container. |
| 187 | + |
| 188 | +``` |
| 189 | +Singularity lolcow:~> exit |
| 190 | +
|
| 191 | +$ nano Singularity |
| 192 | +``` |
| 193 | + |
| 194 | +Here is what our updated definition file should look like. |
| 195 | + |
| 196 | +``` |
| 197 | +BootStrap: debootstrap |
| 198 | +OSVersion: xenial |
| 199 | +MirrorURL: http://us.archive.ubuntu.com/ubuntu/ |
| 200 | +
|
| 201 | +
|
| 202 | +%runscript |
| 203 | + echo "This is what happens when you run the container..." |
| 204 | +
|
| 205 | +
|
| 206 | +%post |
| 207 | + echo "Hello from inside the container" |
| 208 | + sed -i 's/$/ universe/' /etc/apt/sources.list |
| 209 | + apt-get update |
| 210 | + apt-get -y install fortune cowsay lolcat |
| 211 | + apt-get clean |
| 212 | +
|
| 213 | +%environment |
| 214 | + export PATH=/usr/games:$PATH |
| 215 | + export LC_ALL=C |
| 216 | +``` |
| 217 | + |
| 218 | +Let's rebuild the container with the new definition file. |
| 219 | + |
| 220 | +``` |
| 221 | +$ sudo singularity build lolcow.simg Singularity |
| 222 | +``` |
| 223 | + |
| 224 | +Note that we changed the name of the container. By omitting the `--sandbox` option, we are building our container in the standard Singularity squashfs file format. We are denoting the file format with the (optional) `.simg` extension. A squashfs file is compressed and immutable making it a good choice for a production environment. |
| 225 | + |
| 226 | +Singularity stores a lot of [useful metadata](http://singularity.lbl.gov/docs-environment-metadata). For instance, if you want to see the recipe file that was used to create the container you can use the `inspect` command like so: |
| 227 | + |
| 228 | +``` |
| 229 | +$ singularity inspect --deffile lolcow.simg |
| 230 | +BootStrap: debootstrap |
| 231 | +OSVersion: xenial |
| 232 | +MirrorURL: http://us.archive.ubuntu.com/ubuntu/ |
| 233 | +
|
| 234 | +
|
| 235 | +%runscript |
| 236 | + echo "This is what happens when you run the container..." |
| 237 | +
|
| 238 | +
|
| 239 | +%post |
| 240 | + echo "Hello from inside the container" |
| 241 | + sed -i 's/$/ universe/' /etc/apt/sources.list |
| 242 | + apt-get update |
| 243 | + apt-get -y install fortune cowsay lolcat |
| 244 | + apt-get clean |
| 245 | +
|
| 246 | +%environment |
| 247 | + export PATH=/usr/games:$PATH |
| 248 | + export LC_ALL=C |
| 249 | +``` |
0 commit comments