The-Ramadhan

Docker Engine

Docker engine is the server-side components of Docker. It functions is to run and manage containers.

Docker Client (the CLI) communicate with Docker Engine via Unix Socket at /var/run/docker.sock.

![[Excalidraw/docker-engine.excalidraw|docker-engine]]

Components of Docker Engine:

  • Docker Daemon
  • containerD
  • runc
  • shim

Docker Daemon

Docker Daemon used to be the on that manged everything about container. Now it is just serving API.

It receive API call from Docker Client and then make request via grpc CRUD-style API call to containerD.

containerD

containerD is where execution logic happens. containerD manage the container lifecycle. containerD convert Docker image into OCI bundle and tell runc to run it.

It often refer as high-level runtime.

runc

runc is a lightweight-wrapper CLI around libcontainer. runc is the OCI-Compliant runtime-spec. runc interfacing with kernel to pull all necessary os construct to create container (e.g. cgroups, namespace, etc.). runc is the OCI-layer of Docker Engine.

Container start as child-process of runc. After container started, runc quit immediately.

It often refer as low-level runtime.

shim

shim enables daemonless-container and makes OCI-layer pluggable. shim become’s container parent-process after runC exit. shim communicate with containerD.

shim reports container status and keeps STDIN and STDOUT streams open.

Container Creation Process

  1. Docker Client make API call via var/run/docker.sock to Docker Engine.
  2. Docker Daemon receive the request and pass the request to containerD using CRUD-style grpc API.
  3. containerD convert the Docker image into OCI bundle and pass it to runC
  4. runc pull all necessary OS-construct to run container and run the container.
  5. After container run, runc exit
  6. shim become container parent-process and keep STDIN and STDOUT stream open also reporting container status to containerD