Docker -- Part One

Posted on Mon 31 December 2018 in linux

Docker is an open-source virtualization software solution that operates on system level. It allows to run applications isolated from each other by using separated containers. Each container bundles the application itself, its dependencies as well as all required configuration files. The use of containers enables developers to build, manage and deploy critical software applications without technology or infrastructure lock-in effects. Easily, an automated supply chain can be setup to distribute dockerized applications on multiple target systems.

Technology

Docker builds on top of several existing Linux kernel features; such as control groups (cgroups), namespaces and the union mount overlay filesystem (OverlayFS); to allow the running of multiple isolated containers on the same Linux kernel instance. While the namespaces provide and isolated view on the operating system environment (including process trees, network interfaces, mounted file systems and user IDs), cgroups) enables the resource management, limiting the CPU and memory usage for individual containers. Apart from that the Red Hat developed SELinux has been adapted for Docker to protect the host system by enforcing additional security policies.

While earlier Docker versions accessed the Linux kernel functionality via the LXC interface, new versions (since 0.9) use libcontainer, a new abstraction layer that provides a standardized way to manage containers and to access system functionality. The latter also allows an easier porting to other platforms apart from Linux. Though, Docker builds on top of the Linux kernel, it can also be used on Windows and macOS using Hyper-V or VirtualBox correspondingly.

+-----------------------------------------------------+
|                      *Docker*                       |
+-----------------------------------------------------+
        |             |         |           |
   libcontainer      libvirt    LXC     systemd-nspawn
        |             |         |           |
        v             v         v           v
+-----------------------------------------------------+
|                   *Linux Kernel*                    |
|                                                     |
|    cgroups                             Netlink      |
|                      namespaces                     |
|              SELinux              Netfilter         |
|                           AppAmor                   |
+-----------------------------------------------------+

Although, the sharing of a single host computer is similar to virtual machines (VMs), there is a huge difference: While multiple VMs can run on the same host server, each VM requires a separate guest operating system. In contrast, Docker containers can run on the same host server as normal process, sharing the OS kernel of the host. As a result, containers require less space and are more lightweight than VMs.

Virtual Machines:

+---------------+  +---------------+  +---------------+
|      VM       |  |      VM       |  |      VM       |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| |   App A   | |  | |   App B   | |  | |   App C   | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Bins/Libs | |  | | Bins/Libs | |  | | Bins/Libs | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Guest OS  | |  | | Guest OS  | |  | | Guest OS  | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
+---------------+  +---------------+  +---------------+
+-----------------------------------------------------+
|                     Hypervisor                      |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                   Infrastructure                    |
+-----------------------------------------------------+

Docker Containers:

+---------------+  +---------------+  +---------------+
|   Container   |  |   Container   |  |   Container   |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| |   App A   | |  | |   App B   | |  | |   App C   | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Bins/Libs | |  | | Bins/Libs | |  | | Bins/Libs | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
+---------------+  +---------------+  +---------------+
+-----------------------------------------------------+
|                        Docker                       |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                       Host OS                       |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                   Infrastructure                    |
+-----------------------------------------------------+

Architecture and Components

The Docker daemon (dockerd) is a persistent process on the host system that manages all containers that are running on the host. To interact with the daemon the command-line interface docker can be used, which communicates via the Docker Engine API with the daemon.

Apart from that there are several components that often appear in the context of Docker. Those components are briefly discussed in the following:

  • Image: A read-only template that is used to build containers. The image includes the application itself as well as everything to run the application, such as the runtime environment, libraries, configuration files etc.
  • Container: A runtime instance of an image i.e. what happens when an image is executed. The container runs as discrete process on the host operating system. Multiple containers of the same image can be run on the host.
  • Layer: Part of an image consisting of a command or file. Each modification to the image will be stored as separate layer, providing a history of changes.
  • Dockerfile : The Dockerfile is a text file that describes the commands that are required to build the image. For each command that is executed, an additional layer will be created.
  • Repository: A repository is a set of the same image with different tags in different versions.
  • Registry: A registry is a repository for Docker images. It manages different Docker images and provides them to the user. Docker Hub is one of the most popular registry for container images.
  • Docker Compose A tool for defining and running multiple docker containers at the same time. The configuration of the different (dependent) containers is provided in YAML.
  • Docker Swarm A clustering functionality of docker containers that allows to run a group of docker engines as single virtual Docker engine.

Setup

To install a current Docker version on Debian, it is recommended to use the version from the official Docker Debian repository. This is strongly recommended, since the Docker development has a certain momentum, providing continuously new improvements.

First, make sure that you have the following basic tools installed from the official Debian repository:

apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common

Get the official Docker key and add it to the apt key chain:

curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

Add the Docker respository for the corresponding architecture:

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

Update the package index and install the Docker Community Edition (CE):

apt-get update
apt-get install docker-ce

After the installation, the Docker daemon will start automatically.

To make sure that everything is running as expected, run the following command:

docker info

In the next step, start the hello-world image:

docker run hello-world

This will download the image from the server and start a container instance of it.

The run hello-world image should appear in the list of executed images:

docker container ls --all