Docker Engine vs Docker Runtime

 

Docker Engine vs Docker Runtime

Purpose, Design, Internals — With cgroups & namespaces explained in context


📑 Table of Contents

  1. What Is Docker?

  2. High-Level Docker Architecture

  3. Docker Engine: Purpose, Components & Design

  4. Docker Runtime: containerd, runc, and the OCI

  5. How Docker Uses cgroups & Namespaces

  6. Docker Lifecycle Internals

  7. Hands-On Commands to Trace Execution

  8. FAANG-Level Interview Q&A

  9. Visual Diagram & Cheat Sheet


🐳 1. What Is Docker?

Docker is an open-source platform that enables:

  • Building images from code and dependencies

  • Running containers from images

  • Managing the lifecycle of containers (start, stop, restart, remove)

  • Resource isolation using Linux primitives


🧱 2. High-Level Docker Architecture

 

        +-----------------------------+
          |     Docker CLI / REST API   |
          +-------------+---------------+
                        ↓
              +--------+--------+
              |   Docker Engine |
              +--------+--------+
                        ↓
              +--------+--------+
              |      containerd |
              +--------+--------+
                        ↓
                    +--+--+
                    |runc|
                    +--+--+
                        ↓
                Linux Kernel (cgroups, namespaces)



⚙️ 3. Docker Engine

✅ What is Docker Engine?

The Docker Engine is the core daemon (dockerd) that manages the complete lifecycle of containers, from building images to managing running instances.

🧩 Components of Docker Engine:

Component

Role

dockerd

Docker daemon, handles container lifecycle

docker CLI

User-facing command-line interface

REST API

Used internally and by external systems

Image builder

Builds layered filesystem images

Networking

Sets up bridges, overlays, port forwarding


🛠️ 4. Docker Runtime

✅ What is Docker Runtime?

The Docker Runtime is the lower-level component responsible for executing containers. Docker uses a layered runtime architecture:

🧱 Breakdown:

Layer

Component

Purpose

Runtime

containerd

High-level container lifecycle manager

OCI runtime

runc

Actually creates container process

Spec

OCI

Open standard for runtimes/images


🔁 Flow: From CLI to Kernel

docker run nginx


  1. docker CLI sends command to dockerd

  2. dockerd uses containerd to manage container

  3. containerd calls runc (OCI runtime)

  4. runc:

    • Uses namespaces to isolate the container

    • Uses cgroups to limit CPU/memory

    • Starts the container process

  5. Linux kernel enforces all constraints


🧠 5. How Docker Uses cgroups and namespaces

Kernel Feature

Docker Behavior

pid ns

Container sees only its own process tree

net ns

Separate veth pair for container networking

mnt ns

Mount a new root FS from image layers

ipc ns

Isolate inter-process comm (shm, msg queues)

user ns

Map root in container to unprivileged UID

cgroups

CPU, memory, IO limits per container

👇 Internally:

  • When you run:

docker run -it --memory="256m" ubuntu


Docker:

  • Creates a cgroup under /sys/fs/cgroup/memory/docker/<id>

  • Sets memory.limit_in_bytes = 256MB

  • Uses runc to launch process inside namespaces


🔍 6. Docker Lifecycle Internals

🔄 Example: docker run ubuntu

  1. CLI sends REST request to dockerd

  2. dockerd:

    • Pulls image from registry (if not available)

    • Creates filesystem from layers (OverlayFS)

    • Sets up networking (bridge, IP assignment)

    • Creates cgroups and namespaces

  3. containerd spawns a container task

  4. runc executes the container:

    • clone() system call with namespace flags

    • pivot_root() to new root FS

    • execve() to run the container's init process


🧪 7. Hands-On CLI Tracing

🔎 Trace components

ps -ef | grep dockerd       # Docker daemon
ps -ef | grep containerd    # Container runtime
ps -ef | grep runc          # OCI runtime (on container start)


🧪 Show namespaces of a container:

docker run -d --name test alpine sleep 1000
ls -l /proc/$(docker inspect --format '{{.State.Pid}}' test)/ns


🧪 Show cgroups:

cat /proc/$(docker inspect --format '{{.State.Pid}}' test)/cgroup



🎯 8. FAANG-Level Interview Q&A

❓Q1: What's the difference between Docker Engine and Runtime?

Docker Engine

Docker Runtime

High-level management

Low-level execution

Provides CLI, REST API

Provides interface to start tasks

Builds images

Launches containers

Includes networking

Interacts with kernel features


❓Q2: Why is Docker moving to containerd?

  • containerd is a standalone CRI-compliant runtime

  • More modular and lightweight

  • Docker now uses containerd as its runtime backend


❓Q3: Can you run Docker containers without Docker?

Yes, via containerd directly or runc:

ctr image pull docker.io/library/alpine:latest

ctr run -t --rm docker.io/library/alpine:latest demo /bin/sh


Or using runc:

  1. Create a rootfs

  2. Write a config.json

  3. Run: runc run <id>


🧮 9. Visual Diagram

            [docker CLI]
                  ↓
            [dockerd daemon]
                  ↓
            [containerd daemon]
                  ↓
                  [runc]
                  ↓
      [Linux Kernel: namespaces, cgroups]
                  ↓
            [Isolated Container Process]



📌 10. Cheat Sheet Summary

Component

Tool

Role

Engine

Docker

CLI + Image Build + Lifecycle

Runtime

containerd

Manages containers/tasks

OCI Runtime

runc

Actual container exec

Namespace

Kernel

Process/FS/Net isolation

cgroup

Kernel

Resource limits per container


✅ Final Takeaway

Docker Engine is the orchestrator;
Docker Runtime (containerd + runc) is the executor.
Together, they use Linux namespaces & cgroups to run secure, resource-controlled containers.


Ref: 

https://blog.purestorage.com/purely-educational/containerd-vs-docker-whats-the-difference/

https://www.cloudraft.io/blog/container-runtimes



Distributed by Gooyaabi Templates | Designed by OddThemes