Lesson 1.3: Integration of Docker Daemon and Container Runtime
Now that we know how docker daemon runs a container let's take a look into the integration between the Docker Daemon and the container runtime, which is responsible for executing containers. Container runtime is a critical component of Docker architecture, responsible for managing the execution and lifecycle of containers. In Docker, the default container runtime is runc
, which operates in conjunction with containerd
, an intermediate layer that interfaces with the Docker Daemon dockerd
. When a user issues a command (e.g., docker run), the Docker Daemon processes the request and communicates with containerd to create and manage the container. The containerd layer handles the lower-level operations, such as pulling images and starting containers, while runc is responsible for creating the container's environment and executing its processes. This collaboration ensures that containers are isolated, resource-managed, and run efficiently, utilizing Linux kernel features like namespaces and cgroups.
Additionally, Docker supports alternative container runtimes, enabling users to customize their environment as needed. Overall, this architecture ensures efficient and secure execution of containerized applications while allowing for flexibility in runtime selection.
Images:
Let’s delve into the complete process of building, pulling, and storing images in Docker, focusing on how the Docker Daemon handles these operations when commands are executed. We will cover both the docker build and docker pull commands in detail
Building an Image
Let's consider the command:
docker build -t sample_image:latest .
This command builds a Docker image from a Dockerfile located in the current directory (denoted by .) and tags it as sample_image:latest
But what happens internally?
- Command Reception: When the docker build command is executed, the Docker client sends a request to the Docker Daemon via the Docker API to initiate the build process.
- Dockerfile Parsing: The Daemon retrieves the Dockerfile from the specified context (in this case, the current directory). It parses the Dockerfile to understand the instructions provided, such as FROM, RUN, COPY, and CMD.
- Base Image Retrieval: If the Dockerfile specifies a base image (e.g., FROM ubuntu), the Daemon checks if this base image is available locally. If it is not found, the Daemon pulls it from the Docker registry, following the process outlined in the previous section (checking the registry, downloading layers, etc.).
- Layer Creation: As the Daemon processes each instruction in the Dockerfile, it creates a new layer for each command. For example:
- RUN: Executes commands in a new layer and commits the changes.
- COPY: Copies files from the host into the image, creating another layer.
- ENV: Sets environment variables, which also results in a new layer.
- Layer Storage: Each layer created during the build process is stored in the Docker storage directory (e.g., /var/lib/docker). Docker uses a union filesystem (like
OverlayFS
) to manage these layers, allowing for efficient storage and retrieval. This approach is necessary because it minimizes duplication of data and enables quick access to the layers that make up an image. By stacking layers, Docker can efficiently manage changes and updates, saving both disk space and time during builds. - Image Metadata Update: After processing all instructions in the Dockerfile, the Daemon updates its internal metadata to reflect the new image, including its layers, tags, and configurations.
- Completion Notification: Finally, the Docker Daemon sends a message back to the Docker client, confirming that the image has been successfully built and is available for use.
Both the docker build and docker pull commands involve intricate processes managed by the Docker Daemon. When building an image, the Daemon parses the Dockerfile, retrieves any necessary base images, creates layers based on the specified instructions, and updates its metadata. In contrast, when pulling an image, the Daemon communicates with the Docker registry, downloads the required layers, and stores them in the local storage directory.