Skip to main content

Command Palette

Search for a command to run...

Docker: The Docker Engine

Published
2 min read

What happend during a container creation?

Assuming we are creating a container using command below:

docker run --name=nginx -d nginx
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
04dfa0a3257e   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    nginx

Let’s break down the process:

  • The Docker client converts the command into API requests and sends it to the API exposed by the daemon.

  • The daemon can expose the API on a local socket or over the network. On Linux, the local socket is /var/run/docker.sock and on Windows it’s \pipe\docker_engine.

  • The daemon receives the request, interprets it as a request to create a new container, and passes it to containerd. Remember that the daemon no longer contains any code to create containers.

  • The daemon communicates with containerd via a CRUD-style API over gRPC.

  • Despite its name, even containerd cannot create containers. It converts the required Docker image into an OCI bundle and tells runc to use this to create a new container.

  • runc interfaces with the OS kernel to pull together all the constructs necessary to create a container (namespaces, cgroups, etc.). The container starts as a child process of runc, and as soon as the container starts, runc exits, a shim process becomes the container’s parent process then.

What is shim ?

In Docker, a shim acts as a lightweight process between containerd and the container itself. It enables daemonless containers, which allows the Docker daemon to be updated or restarted without affecting running containers. The shim forks a runc process to start the container but remains as the container’s parent process. It handles low-level tasks like managing STDIN/STDOUT streams and reporting the container's status. Shims also offer flexibility by allowing different low-level runtimes to replace runc.

How Docker is implemented on Linux

You can find these components in the /usr/bin/ directory:

/usr/bin/dockerd (the Docker daemon) 
/usr/bin/containerd 
/usr/bin/containerd-shim-runc-v2 
/usr/bin/runc

Also, you can find some clue with a combination of docker ps and ps -aux | grep <container_id> command:

# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
04dfa0a3257e   nginx     "/docker-entrypoint.…"   23 minutes ago   Up 23 minutes   80/tcp    nginx

# ps -aux | grep 04dfa0a3257e
root        2734  0.0  0.3 1237848 13664 ?       Sl   15:37   0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 04dfa0a3257eeecdc2c575446e0f6634b589a7791b1706b4a95c88aa0548752f -address /run/containerd/containerd.sock

Reference

Poulton, Nigel. Docker Deep Dive: Zero to Docker in a single book (English Edition) (p. 63). (Function). Kindle Edition.

6 views