Docker was born in 2013 and popularized the concept of containers, so that most people still equate the concept of containers with "Docker containers".

As the first person to eat crabs, Docker sets the standards that new entrants must abide by. For example, Docker has a large system mirror library. All alternatives must use the same image format while attempting to change one or more parts of the entire stack on which Docker is based.

During this period, new container standards emerged, and the container ecosystem developed in different directions. In addition to Docker, there are many ways to use containers.

In this article, we will introduce the following:

  1. Use Chroot, cgroups, and namespaces as the technical foundation of containers
  2. Define the software stack on which Docker is based
  1. Explain the standards that Docker and Kubernetes need to adhere to and comply with
  1. Introduce alternative solutions that try to replace the original Docker container with better and more secure components.

The software stack of the container

Linux features like Chroot calls, cgroups, and namespaces help the container to run in isolation from all other processes, thus ensuring runtime security.

Chroot

All Docker-like technologies originated from the root directory of a Unix operating system (OS). Above the root directory is the root file system and other directories.

In the long run, this is very dangerous, because any unwanted deletion in the root directory will affect the entire operating system. This is why there is a system call chroot(). It creates additional root directories, such as one for running legacy software, another for containing databases, and so on.

For all these environments, chroot seems to be a real root directory, but in fact, it just adds the path name to any name that starts with /. The real root directory still exists, and any process can refer to any location other than the specified root directory.

Linux cgroups

Since version 2.6.24 in 2008, Control groups (cgroups) has been a feature of the Linux kernel. Cgroup will simultaneously limit, isolate and measure the system resources (memory, CPU, network and I/O) usage of multiple processes.

Suppose we want to prevent users from sending large amounts of emails from the server. We created a cgroup with a memory limit of 1GB and a CPU usage of 50%, and added the processid of the application to the group. When these limits are reached, the system will limit the email sending process. It may even terminate the process, depending on the hosting strategy.

Namespaces

The Linux namespace is another useful abstraction layer. Namespaces allow us to have many process levels, each with its own nested "subtree." A namespace can use global resources and present them to its members as if it were its own resources.

Specifically, the process identifier (PID) of the Linux system at the beginning is 1, and all other processes will be included in its tree. The PID namespace allows us to span a new tree, which has its own PID 1 process. Now there are two PIDs with a value of 1. Each namespace can generate its own namespace, and several PIDs can be attached to the same process.

A process in the child namespace will not know the existence of the parent's process, and the parent namespace will have access to the entire child namespace.

There are seven types of namespaces: cgroup, IPC, network, mount, PID, user, and UTS.

Network Namespace

Some resources are scarce. By convention, some ports have predefined roles and should not be used for any other purpose: port 80 only serves HTTP calls, port 443 only serves HTTPS calls, and so on. In a shared hosting environment, two or more sites can listen for HTTP requests from port 80. The first site to obtain the port does not allow any other applications to access the data on the port. The first application is visible on the Internet, while all other applications will not be visible.

The solution is to use network namespaces, through which internal processes will see different network interfaces.

In one network namespace, the same port can be open, and in another network namespace, the port can be closed. To this end, we must use additional "virtual" network interfaces, which belong to multiple namespaces at the same time. There must also be a router process in the middle, which connects the request to the physical device to the corresponding name space and the process in it.

Is it complicated? This is why Docker and similar tools are so popular. Now let us introduce Docker and its alternatives.

Docker: a container for everyone

Before containers ruled the cloud computing world, virtual machines were very popular. If you have a Windows machine but want to develop mobile applications for iOS, you can buy a new Mac or install its virtual machine on Windows hardware. Virtual machines can also be cumbersome, they often swallow unnecessary resources, and they are usually slow to start (up to a minute).

The container is a standard software unit with everything needed to run the program: operating system, database, image, icon, software library, code, and other required components. The operation of the container is also isolated from all other containers, and even from the operating system itself. Compared with virtual machines, containers are lightweight, so they can be started quickly and easily replaced.

To run isolation and protection, containers need to be based on Chroot, cgroups, and namespaces.

The image of a container is a template for forming an application on an actual machine. It can create as many containers as possible from a single image. A text file named Dockerfile contains all the information needed to assemble the image.

The real revolution brought by Docker was the creation of the Docker mirror warehouse and the development of the Docker engine. These mirrors were run in the same way everywhere. As the first widely adopted container mirror, it formed an unwritten world standard. All entrants must pay attention to it.

CRI and OCI

The full name of OCI is the Open Container Initiative, which publishes specifications for images and containers. It was initiated by Docker in 2015 and was accepted by Microsoft, Facebook, Intel, VMWare, Oracle and many other industry giants.

OCI also provides an implementation of the specification, called runc, which can directly use containers, create and run them, etc.

The Container Runtime Interface (CRI) is a Kubernetes API that defines how Kubernetes interacts with the container runtime. It is also standardized, so we can choose which CRI implementation to use.

Software stack of containers for CRI and OCI

Linux is the most basic part of the software stack for running containers:

在这里插入图片描述

Please note that both Containerd and CRI-O adhere to the CRI and OCI specifications. For Kubernetes, this means that it can use Containerd or CRI-O, and users will not notice the difference. It can also use any of the other alternatives we are going to mention now-this is the goal of the creation and adoption of software standards such as OCI and CRI.

Docker software stack

Docker's software stack includes:

docker-cli, Docker command line interface for developers

containerd, originally written by Docker and later started as an independent project; it implements the CRI specification

runc, which implements the OCI specification

Containers (using chroot, cgroups, namespaces, etc.)

The software stack of Kubernetes is almost the same; Kubernetes uses CRI-O instead of Containerd, which is an implementation of CRI created by Red Hat/IBM and others.

containerd

在这里插入图片描述

containerd runs as a daemon on Linux and Windows. It loads the image, executes it as a container, supervises the underlying storage, and is responsible for the running time and life cycle of the entire container.

Containerd was born in 2014. It started as a part of Docker. It became a project of the Cloud Native Computing Foundation (CNCF) in 2017 and graduated in early 2019. If you want to know some tips for using Containerd, please check the following article:

Complete guide to configure containerd mirror warehouse

runc

runc is the reference implementation of the OCI specification. It creates and runs the container and the processes in it. It uses lower-level Linux features, such as cgroups and namespaces.

Alternatives to runc include Kata-Runtime, GVisor and CRI-O.

Kata-Runtime uses hardware virtualization as a separate lightweight VM to implement the OCI specification. Its runtime is compatible with OCI, CRI-O and Containerd, so it can work seamlessly with Docker and Kubernetes.

在这里插入图片描述

Google's gVisor creates a container containing its own kernel. It implements OCI through a project called runsc, which integrates with Docker and Kubernetes. A container with its own kernel is safer than a container without a kernel, but it is not a panacea, and this method has a cost in resource usage.

在这里插入图片描述

CRI-O is a container stack designed purely for Kubernetes and the first implementation of the CRI standard. It extracts images from any container mirror repository and can be used as a lightweight alternative to using Docker.

Today it supports runc and Kata Containers as container runtimes, but it can also plug in any other OC compatible runtime (at least in theory).

It is a CNCF incubation project.

Podman

Podman is an alternative to Docker without a daemon. Its commands are intentionally compatible with Docker as much as possible, so that you can create an alias in the CLI interface and start using the word "Docker" instead of "podman".

Podman's goal is to replace Docker, so it makes sense to stick to the same command set. Podman tried to improve two problems in Docker.

First of all, Docker always uses an internal daemon to execute. The daemon is a single process running in the background. If it fails, the entire system will fail.

Second, Docker runs as a background process and has root privileges, so when you give a new user access, you actually give access to the entire server.

Podman is a remote Linux client that can run containers directly from the operating system. You can also run them in rootless mode. It downloads images from DockerHub and runs them in exactly the same way as Docker, with exactly the same commands.

Podman runs commands and images as a user other than root, so it is more secure than Docker. On the other hand, there are many tools developed for Docker that are not available on Podman, such as Portainer and Watchtower. Getting rid of Docker means abandoning the workflow you established earlier.

The directory structure of Podman is similar to buildah, skopeo and CRI-I. Its Pod is also very similar to KubernetesPod.

Linux containers: LXC and LXD

LXC (LinuX Containers) was launched in 2008 and is the first upstream kernel container on Linux. The first version of Docker used LXC, but in later developments, because runc has been implemented, LXC was removed.

The goal of LXC is to use a Linux kernel to run multiple isolated Linux virtual environments on a control host. To this end, it uses the cgroups function without starting any virtual machines; it also uses a namespace to completely isolate the application from the underlying system.

LXC is designed to create system containers, almost as if you are in a virtual machine-but the hardware overhead is small because the hardware is virtualized.

LXC does not simulate hardware and software packages, but only contains the required applications, so it executes almost at bare metal speed. Instead, a virtual machine contains the entire operating system and then simulates hardware such as hard disks, virtual processors, and network interfaces.

Therefore, LXC is small and fast, while virtual machines are big and slow. On the other hand, the virtual environment cannot be packaged into a ready-made, quickly deployable machine, and it is difficult to manage through the GUI management console. LXC requires technicians to have a high technical level, and the optimized machine may not be compatible with other environments.

LXC VS Docker

LXC is like a supercharged chroot on Linux, it produces "small" servers that start faster and require less RAM. However, Docker provides more features:

  • Portable deployment across machines: Objects created with one version of Docker can be transferred and installed on any other Linux host that supports Docker.
  • Version control: Docker can track versions in a git-like way-you can create new versions of containers, roll them back, etc.
  • Reuse components: With Docker, you can stack the already created packages into new packages. If you want a LAMP environment, you can install its components once and reuse them as pre-made LAMP images.
  • Docker image archive: hundreds of thousands of Docker images can be downloaded from a dedicated site, and new images can be easily uploaded to such a mirror repository.

LXC is for system administrators, while Docker is more for developers. This is why Docker is more popular.

LXD

LXD has a privileged daemon that exposes the REST API through the local UNIX socket and network (if enabled). You can access it through command line tools, but it always communicates using REST API calls. Whether the client is on the local machine or on the remote server, its function is the same.

LXD can scale from a local machine to thousands of remote machines. Similar to Docker, it is based on mirroring, which can be used by all the more popular Linux distributions. Ubuntu's company Canonical is funding the development of LXD, so it will always run on the latest version of Ubuntu and other similar Linux operating systems. LXD can seamlessly integrate with OpenNebula and OpenStack standards.

Technically speaking, LXD is standing on the shoulders of LXC (both use the same liblxc library and Go language to create containers), but the goal of LXD is to improve the user experience.

Will Docker exist forever?

Docker has 11 million developers, 7 million applications, and 13 billion image downloads per month. It would be an understatement to just say that Docker is still the leader. However, in this article, we have seen that there are now many products that can replace one or more parts of the Docker software stack, and there are usually no compatibility issues. And compared with the services provided by Docker, the main goal of other software is security.

Original link:

https://community.suse.com/posts/beyond-docker-a-look-at-alternatives-to-container-management-14411837


Rancher
1.2k 声望2.5k 粉丝

Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云+本地数据中心的集中部署与管理。Rancher一向因操作体验的直观、极简备受用户青睐,被Forrester评为“2020年多云容器开发平台领导厂商...