containers</em>. Container platforms for Linux are built on top of
<em>namespaces</em> and <em>control groups</em>, the low-level kernel
features which implement abstraction and isolation of processes. We
-look at both concepts in some detail. One of the earliest container
-platforms for Linux is <em> LXC </em> (Linux containers) which is
-discussed in a dedicated section.
+look at both concepts in some detail. The final section discusses
+<em>micoforia</em>, a minimal container platform.
»)
flexibility. It is simply not an option if some of the VMs must run
different operating systems than the host.
-Examples: LXC, Singularity, Docker.
+Examples: LXC, Micoforia, Singularity, Docker.
EXERCISES()
»)
-SECTION(«Linux Containers (LXC)»)
+SECTION(«Linux Containers»)
-Containers provide resource management through control groups and
+<p> Containers provide resource management through control groups and
resource isolation through namespaces. A <em> container platform </em>
is thus a software layer implemented on top of these features. Given a
directory containing a Linux root file system, starting the container
created namespaces exits, the namespaces disappear and the parent
process removes the cgroup. The details are a bit more complicated,
but the above covers the essence of what the container startup command
-has to do.
-
-Many container platforms offer additional features not to be discussed
-here, like downloading and unpacking a file system image from the
-internet, or supplying the root file system for the container by other
-means, for example by creating an LVM snapshot of a master image.
-LXC is a comparably simple container platform which can be used to
-start a single daemon in a container, or to boot a container from
-a root file system as described above. It provides several <code>
-lxc-* </code> commands to start, stop and maintain containers.
-LXC version 1 is much simpler than subsequent versions, and is still
-being maintained, so we only discuss this version of LXC here.
-
-An LXC container is defined by a configuration file in
-the format described in <code> lxc.conf(5)</code>. A <a
-href="#minimal_lxc_config_file"> minimal configuration </a> which
-defines a network device and requests CPU and memory isolation has
-as few as 10 lines (not counting comments). With the configuration
-file and the root file system in place, the container can be started
-by running <code> lxc-start -n $NAME</code>. One can log in to the
-container on the local pseudo terminal or via ssh (provided the sshd
-package is installed). The container can be stopped by executing
-<code> halt </code> from within the container, or by running <code>
-lxc-stop </code> on the host system. <code> lxc-ls </code> and
-<code> lxc-info</code> print information about containers, and <code>
-lxc-cgroup </code> changes the settings of the cgroup associated with
-a container.
-
-The exercises ask the reader to install the LXC package from source,
-and to set up a minimal container running Ubuntu-18.04.
+has to do. </p>
+
+<p> Many container platforms offer additional features not to
+be discussed here, like downloading and unpacking a file system
+image from the internet, or supplying the root file system
+for the container by other means, for example by creating an
+LVM snapshot of a master image. In this section we look at <a
+href="http://people.tuebingen.mpg.de/maan/micoforia/">micoforia</a>,
+a minimalistic container platform to boot a container from an existing
+root file system as described above. </p>
+
+<p> The containers known to micoforia are defined in the single
+<code>~/.micoforiarc</code> configuration file whose format is
+described in <code>micoforia(8)</code>. The <code>micoforia</code>
+command supports various subcommands to maintain containers. For
+example, containers are started with a command such as <code>micoforia
+start c1</code> where <code>c1</code> is the name of the
+container. One can execute a shell running within the container
+with <code>micoforia enter c1</code>, log in to a local pseudo
+terminal with <code>micoforia attach c1</code>, or connect via ssh
+with <code>ssh c1</code>. Of course the latter command only works
+if the network interface and the DNS record get configured during
+container startup and the sshd package is installed. The container can
+be stopped by executing <code>halt</code> from within the container,
+or by running <code>micoforia stop c1</code> on the host system. The
+commands <code>micoforia ls</code> and <code>micoforia ps</code>
+print information about containers and their processes. </p>
+
+<p> The exercises ask the reader to install the micoforia package from
+source, and to set up a minimal container running Ubuntu Linux. </p>
EXERCISES()
<ul>
+ <li> Clone the micoforia git repository from
+ <code>git://git.tuebingen.mpg.de/micoforia</code> and compile the
+ source code with <code>./configure && make</code>. Install with
+ <code>make install</code>. </li>
+
+ <li> Download a minimal Ubuntu root file system
+ with a command like <code>debootstrap --download-only
+ --include isc-dhcp-client bionic /var/lib/micoforia/c1/
+ http://de.archive.ubuntu.com/ubuntu</code>. </li>
+
+ <li> Set up an ethernet bridge as described
+ in <code>micoforia(8)</code>. Consult the <a
+ href="./Networking.html#link_layer">Link Layer</a> section of the
+ chapter on networking if you would like to understand what you are
+ doing. </li>
- <li> Clone the LXC git repository from <code>
- https://github.com/lxc/lxc</code>, check out the <code> stable-1.0
- </code> tag. Compile the source code with <code> ./autogen.sh </code>
- and <code> ./configure && make</code>. Install with <code> sudo make
- install</code>. </li>
+ <li> Add the following lines to <code>/etc/fstab</code> to configure
+ the cgroup filesystems, create corresponding directories and run
+ <code>mount -a</code> to mount them. </li>
- <li> Download a minimal Ubuntu root file system with a command like
- <code> debootstrap --download-only --include isc-dhcp-client bionic
- /media/lxc/buru/ http://de.archive.ubuntu.com/ubuntu</code>. </li>
+ <pre>
+ none /var/cgroup cgroup devices 0 0
+ none /var/cgroup2 cgroup2 defaults 0 0
+ </pre>
- <li> Set up an ethernet bridge as described in the <a
- href="./Networking.html#link_layer">Link Layer</a> section of the
- chapter on networking. </li>
+ <li> Define a minimal container named <code>c1</code> with <code>echo
+ container c1 > ~/.micoforiarc</code>. This container will have a
+ single network device and neither CPU nor memory isolation will be
+ enforced for the processes of the container. </li>
+
+ <li> Start the container in foreground mode with <code>micoforia --
+ start -F c1</code>. </li>
- <li> Examine the <a href="#minimal_lxc_config_file"> minimal
- configuration file </a> for the container and copy it to <code>
- /var/lib/lxc/buru/config</code>. Adjust host name, MAC address and
- the name of the bridge interface. </li>
+ <li> Run <code>micoforia stop c1</code> to stop the container,
+ edit <code>~/.micoforiarc</code> and add the following two lines to
+ configure memory and CPU limits.
- <li> Start the container with <code> lxc-start -n buru</code>. </li>
+ <pre>
+ cpu-cores c1:1
+ memory-limit c1:1
+ </pre>
- <li> While the container is running, investigate the control files of the
- cgroup pseudo file system. Identify the pseudo files which describe the
- CPU and memory limit. </li>
+ Start the container and run suitable commands which show that the
+ newly configured limits are in effect. </li>
- <li> Come up with a suitable <code> lxc-cgroup </code> command
- to change the cpuset and the memory of the container while it is
- running. </li>
+ <li> While the container is running, investigate the control files
+ of the cgroup pseudo file systems. Identify the pseudo files which
+ control the CPU and memory limit of the container. </li>
+
+ <li> Come up with suitable commands to change the CPU and memory
+ limits of the container while it is running. </li>
<li> On the host system, create a loop device and a file system on
it. Mount the file system on a subdirectory of the root file system
- of the container. Note that the mount is not visible from within the
- container. Come up with a way to make it visible without restarting
- the container. </li>
-
+ of the container. Note that the mount is not visible from within the
+ container. Come up with a way to make such mounts visible without
+ restarting the container. </li>
</ul>
-HOMEWORK(«Compare the features of LXC versions 1, 2 and 3.»)
-
SUPPLEMENTS()
SUBSECTION(«UTS Namespace Example»)
</code>
</pre>
-SUBSECTION(«Minimal LXC Config File»)
-<pre>
- <code>
- # Employ cgroups to limit the CPUs and the amount of memory the container is
- # allowed to use.
- lxc.cgroup.cpuset.cpus = 0-1
- lxc.cgroup.memory.limit_in_bytes = 2G
-
- # So that the container starts out with a fresh UTS namespace that
- # has already set its hostname.
- lxc.utsname = buru
-
- # LXC does not play ball if we don't set the type of the network device.
- # It will always be veth.
- lxc.network.type = veth
-
- # This sets the name of the veth pair which is visible on the host. This
- # way it is easy to tell which interface belongs to which container.
- lxc.network.veth.pair = buru
-
- # Of course we need to tell LXC where the root file system of the container
- # is located. LXC will automatically mount a couple of pseudo file systems
- # for the container, including /proc and /sys.
- lxc.rootfs = /media/lxc/buru
-
- # so that we can assign a fixed address via DHCP
- lxc.network.hwaddr = ac:de:48:32:35:cf
-
- # You must NOT have a link from /dev/kmsg pointing to /dev/console. In the host
- # it should be a real device. In a container it must NOT exist. When /dev/kmsg
- # points to /dev/console, systemd-journald reads from /dev/kmsg and then writes
- # to /dev/console (which it then reads from /dev/kmsg and writes again to
- # /dev/console ad infinitum). You've inadvertently created a messaging loop
- # that's causing systemd-journald to go berserk on your CPU.
- #
- # Make sure to remove /var/lib/lxc/${container}/rootfs.dev/kmsg
- lxc.kmsg = 0
-
- lxc.network.link = br39
-
- # This is needed for lxc-console
- lxc.tty = 4
- </code>
-</pre>
-
SECTION(«Further Reading»)
<ul>
<li> <a href="https://lwn.net/Articles/782876/">The creation of the