Containers
==========
.. contents:: Table of Contents
Containers are a type of software virtualization. Using a directory
structure that contains an entire operating system (typically referred
to as a chroot), containers can easily spin up and utilize system
resources without the overhead of full hardware allocation. It is not
possible to use separate kernels with this approach.
Images
------
`Docker Hub `__ is a container registry that provides a central location to find, download, and upload container images. Here is a list of common operating system images for each family of distributions:
- Arch Linux
- archlinux
- Fedora
- centos:8
- fedora:31
- Debian
- debian:10
- ubuntu:20.04
- openSUSE
- opensuse/leap:15.2
- opensuse/tumbleweed
More containers can be found `here `__.
Bootstrap an Operating System
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using a package manager and the main operating system repositories, it is possible to bootstrap an operating system. It installs all of the operating system packages into a directory. It can then be used as a chroot or for a container image. This can be done on different operating systems but the relevant package manager has to be installed. Arch Linux is one of the few distributions that ships all of the most popular package managers.
**Arch Linux**
.. code-block:: sh
$ mkdir -p archlinux_bootstrap/var/lib/pacman
$ cd archlinux_bootstrap
$ sudo pacman -r . -Syy
$ sudo pacman -r . -S base
If not using Arch Linux with ``pacman`` installed, `download `__ the ``archlinux-bootstrap--x86_64.tar.gz`` tarball from one of the HTTP Direct Downloads mirror.
**CentOS 8**
.. code-block:: sh
$ sudo cat < /etc/yum/repos.d/centos8.repo
[centos8]
name=centos8
baseurl=http://mirror.centos.org/centos-8/8/BaseOS/x86_64/os/
enabled=1
EOF
$ mkdir ${HOME}/centos8_bootstrap
$ sudo yum install centos-release dnf @base --installroot=${HOME}/centos8_bootstrap
**Debian 10**
.. code-block:: sh
$ mkdir debian10_bootstrap
$ sudo debootstrap --arch amd64 buster ./debian10_bootstrap/ https://deb.debian.org/debian/
**Fedora 31**
.. code-block:: sh
$ mkdir ${HOME}/fedora31_bootstrap
$ sudo dnf install --installroot=${HOME}/fedora31_bootstrap --releasever=31 --nogpgcheck fedora-release
$ sudo dnf groupinstall --installroot=${HOME}/fedora31_bootstrap --releasever=31 --nogpgcheck minimal-environment
**RHEL 8**
.. code-block:: sh
$ sudo mount rhel-8.0-x86_64-dvd.iso /mnt
$ sudo cat < /etc/yum/repos.d/rhel8.repo
[rhel8]
name=rhel8
baseurl=file:///mnt/
enabled=1
EOF
$ sudo yum clean all
$ mkdir ${HOME}/rhel8_bootstrap
$ sudo yum groupinstall base --installroot=${HOME}/rhel8_bootstrap
**Ubuntu 20.04**
.. code-block:: sh
$ mkdir ubuntu2004_bootstrap
$ sudo debootstrap --no-check-gpg --arch amd64 focal ./ubuntu2004_bootstrap/ http://archive.ubuntu.com/ubuntu
[12]
Registries
----------
A container registry stores Open Container Initiative (OCI) formatted images. These can universally be used across any modern cloud-native platform.
Here are a list of different container registries that exist [22]:
- Amazon Elastic Container Registry (ECR)
- Docker Hub
- Docker Trusted Registry (DTR)
- Harbor
- JFrog Artifactory
- Nexus Repository
- Pulp Container Registry
- Quay
By default, the ``docker`` command manages container images on the `Docker Hub `__ registry.
.. code-block:: sh
$ docker login
$ docker push /:
Other registries can also be used by specifying the fully qualified domain name of the registry.
.. code-block:: sh
$ docker login
$ docker push //:
Registries:
- registry.redhat.io = Red Hat customer.
- quay.io = Red Hat Quay.
It may be required to first create a new image with a name of the alternative registry.
.. code-block:: sh
$ docker tag //:
$ docker push //:
[21]
Insecure
~~~~~~~~
The docker daemon strictly enforces verified certificates. If a certificate for a container registry cannot be validated, then the docker client will refuse to connect to it. These are workarounds for connecting to registries with untrusted and/or broken certificates.
**Add a Certificate Authority**
Create a directory in ``/etc/docker/certs.d/`` or ``~/.docker/certs.d/`` named ``:``. Place the certificate authority certificate and public key there. Normally a "ca.crt" file would contain both of those but may also be provided separately as "ca.cert" and "ca.key" files. On Linux, a restart of the docker daemon is not required. [23]
On macOS, local certificates will be synced to from ``~/.docker/certs.d/`` to ``/etc/docker/certs.d/`` in the back-end virtual machine after restarting the Docker Desktop app. [24]
.. code-block:: sh
$ osascript -e 'quit app Docker'
$ open -a Docker
**Ignore Certificates**
If a certificate has a common name of something other than the domain or IP address of the container registry then it will not work. In this case, the certificate should be ignored entirely by being listed as an insecure registry. This can also be used as an alternative to providing a certificate authority.
Edit the docker daemon configuration file and add a list of registries to ignore invalid or self-signed certificates.
- Linux: ``/etc/docker/daemon.json``
- macOS: ``~/.docker/daemon.json`` or navigate to Docker Desktop > Preferences > Docker Engine.
.. code-block:: json
{
"insecure-registries": [
":",
":"
]
}
Restart the docker daemon:
- Linux:
.. code-block:: sh
$ sudo systemctl restart docker
- macOS:
.. code-block:: sh
$ osascript -e 'quit app Docker'
$ open -a Docker
Container Runtimes
------------------
Container runtimes handle launching, stopping, and removing containers. Typically a container runtime will be used as a library for implementing a CRI and optionally a Container Engine on-top of the CRI. End-users do not need to interact directly with a container runtime. [13]
An OCI compliant container runtime reads metadata about a container from a config.json file. This describes everything about the container. It will then handle overlay mounts, creating cgroups for process isolation, configuring AppArmor or SELinux, and starting the container process. [20]
runC and crun
~~~~~~~~~~~~~
runC was originally developed by Docker as one of the first modern container runtimes and is written in Go. crun is developed by Red Hat as a re-implementation of runC in the C programming language. It is twice as fast as runC. [14] Legacy container runtimes that are no longer maintained include railcar and rkt. Both runC and crun follow the Open Container Initiative (OCI) for providing a standardized container runtime. [13]
Container Runtime Interfaces (CRIs)
-----------------------------------
CRIs are wrappers around container runtimes that provide a standard API for Kubernetes and other container management platforms to interact with. [13]
containerd (docker)
~~~~~~~~~~~~~~~~~~~
containerd is a cross-platform (Linux and Windows) CRI built on-top of runC. It is what the Docker Engine uses in the back-end. [15]
Installation
^^^^^^^^^^^^
Supported operating systems:
- CentOS/RHEL >= 7
- Debian >= 9
- Ubuntu >= 16.04
- Windows
Debian and Ubuntu:
- Install the required dependencies:
.. code-block:: sh
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
- Add the repository and its GPG key.
.. code-block:: sh
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | awk '{print tolower($0)}') $(lsb_release -cs) stable"
$ curl -fsSL https://download.docker.com/linux/$(lsb_release -is | awk '{print tolower($0)}')/gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -
- Install containerd.
.. code-block:: sh
$ sudo apt-get update
$ sudo apt-get install containerd.io
- Pick to either use containerd by itself or the Docker Engine.
- containerd:
- Create default configuration file and restart containerd to reload the new configuration file.
.. code-block:: sh
$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml
$ sudo systemctl restart containerd
- Docker Engine:
- Install the Docker Engine.
.. code-block:: sh
$ sudo apt-get install docker-ce docker-ce-cli
- Configure it.
.. code-block:: sh
$ cat <= 7
- Debian Testing or Unstable (currently Debian 11)
- Fedora
- openSUSE Tumbleweed
- Ubuntu >= 18.04
Debian and Ubuntu:
- Install the required dependencies:
.. code-block:: sh
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
- Add the CRI-O repository and its GPG key.
.. code-block:: sh
$ export OS="xUbuntu_20.04" # Or use "Debian_Testing" for Debian.
$ cat <
$ sudo systemctl restart docker
Dockerfile
^^^^^^^^^^
docker containers are built by using a template called ``Dockerfile``. This file contains a set of instructions on how to build and handle the container when it's started.
**Dockerfile Instructions**
- **FROM** : = The original container image to copy and use as a base for this new container.
- ADD