Objectifs du chapitre
- Define what a container is and how it differs from a virtual machine.
- Know the advantages, limitations and DevOps role of containers.
- Know the history of containerization and the Linux isolation mechanisms it relies on: namespaces and cgroups.
- Understand the Docker platform: its architecture (dockerd, containerd, runc) and its alternatives.
- Distinguish Docker images from containers, and know the image/container lifecycle, the Dockerfile and the build workflow.
- Know the role of container orchestration and the main solutions available.
1. Containerization
Every application brings its own libraries and dependencies, which conflict when several applications share one OS. The solution: each service is packaged with its libraries and dependencies and runs on a shared container engine.
A container is a lightweight, isolated execution environment for one application or service. It packages the application code with its runtime, libraries, tools and configuration, and shares the host operating-system kernel instead of booting a full guest OS. Its key properties are isolation (processes, filesystems, network interfaces and users are separated), portability (the same image runs on any compatible environment) and efficiency (fast start, fewer resources than VMs). Containers serve the same purpose as VMs, but are implemented at the operating-system level.
| Criterion | Virtual machines | Containers |
|---|---|---|
| Operating system | Full guest OS per VM (own kernel, drivers, libraries). | Shared host kernel; common libraries shared. |
| Isolation | Hardware level (virtual CPU, RAM, disk): strong. | OS level (namespaces, cgroups): weaker. |
| Performance | Hypervisor overhead. | Near-native performance. |
| Resource usage | Often over-allocated; gigabytes per VM. | Roughly the memory of its processes; megabytes. |
| Startup time | Seconds to minutes (full OS boot). | Milliseconds to seconds (no OS to boot). |
| Multi-OS | Windows and Linux on the same host. | Same kernel family as the host. |
| Deployment | Heavier, slower. | Lightweight and fast. |
| Use case | Multi-OS, legacy applications. | Microservices, CI/CD, cloud-native apps. |
| License / cost | Free (KVM) or commercial (VMware). | Mostly open source. |
1.1 Advantages and limitations
| Advantages | Limitations |
|---|---|
| Lightweight: share the host kernel, no guest OS to boot. | Shared kernel: weaker isolation than VMs; a kernel flaw affects every container. |
| Fast: start and stop in seconds. | OS dependency: Linux containers need a Linux kernel (a VM is used on Windows / macOS). |
| Portable: build once, run anywhere a compatible engine exists. | Ephemeral data: lost when the container is removed unless stored outside it. |
| Consistent: the same image from development to production. | Security risks: excessive privileges, vulnerable images. |
| Scalable: replicas added or removed automatically. | Operational complexity: many containers require monitoring and orchestration. |
| Efficient: high density of applications per host. |
1.2 Containers: the bridge to DevOps
The challenge: ensure an application works consistently across different environments, passes testing and quality assurance, deploys without unexpected configuration issues, and does not require rewriting or environment-specific fixes. Containers package the application together with its dependencies and configuration, providing a consistent and portable environment from development to production.
2. Containerization Principles
Containerization did not start with Docker: it results from progressive Unix and Linux isolation mechanisms.
| Year | Milestone | What it brought |
|---|---|---|
| 1979 | chroot | Filesystem isolation. |
| 2000 | FreeBSD Jails | Isolated system environments. |
| 2005-2007 | OpenVZ / cgroups | Resource accounting and limits. |
| 2008 | LXC | Linux containers using namespaces + cgroups. |
| 2013 | Docker | Build, ship, run workflow; Docker Hub (2014). |
| 2015-2017 | OCI / CNCF | OCI image/runtime specs; containerd joins CNCF. |
Linux containers combine isolation mechanisms (namespaces) and resource control mechanisms (cgroups). Docker (2013) made containers popular by making them easy to build, share (Docker Hub) and run. Modern containers follow open standards, mainly the OCI runtime and image specifications.
2.1 Linux Containers (LXC)
LXC is an operating-system-level virtualization technology for running isolated Linux environments. It relies on namespaces for isolation and cgroups for resource control; an LXC container can run several processes and behaves like a lightweight Linux system. Typical use cases: training environments, Linux labs, system-level testing and sandboxing, and as a lightweight alternative to VMs when full hardware virtualization is not required. Important distinction: LXC provides Linux system containers, while Docker provides application containers and developer workflows.
2.2 Namespaces
A namespace gives a group of processes an isolated view of one system resource, so each process sees its own view of the system without being aware of the underlying isolation.
| Namespace | Isolates |
|---|---|
| PID | Processes. |
| NET | Network interfaces. |
| MNT | Filesystem / mount points. |
| USER | Users / groups. |
| IPC | IPC resources. |
| UTS | Hostname. |
The same process has different PIDs depending on the namespace it is observed from: on the host, dockerd (PID 1240) starts a container init (host PID 1832) which runs nginx (host PID 1850); inside the container’s own PID namespace, that same init is PID 1 and nginx is PID 12. The host sees every process; the container sees only its own process tree.
2.3 Control groups (cgroups)
A Linux kernel mechanism to limit, prioritize, monitor and account for resource usage; rules apply to a group of processes, not a single process. Container engines use cgroups so that one container cannot exhaust the whole host. In a container platform, namespaces answer “what can this process see?” and cgroups answer “how much can this process use?”; together they give isolation and predictable performance. Cgroups govern CPU (shares / quota), memory (hard / soft limits), disk I/O (read/write throttling), network (priority / bandwidth) and PIDs (process count limit). Container isolation overall is namespaces + cgroups + filesystem + security profiles.
3. Containerization Platform: Docker
Docker is a containerization platform that enables developers to build, package, deploy and run applications in lightweight, isolated containers. It makes containers usable at scale by adding tooling, image management and simple commands. Important clarification: Docker is not the Linux kernel mechanism itself; it orchestrates container creation using lower-level components (containerd, runc) and kernel features. A Docker container is a process isolated by Linux mechanisms and managed through Docker tooling.
Docker’s architecture is a client-server model: the client (Docker CLI) sends commands (build, pull, run); the REST API is the interface between client and daemon; the server (dockerd) builds images and manages containers; a registry (such as Docker Hub) stores and distributes images. Docker Engine = client (CLI) + REST API + daemon.
3.1 From command to container
docker run nginx goes through several layers:
- The CLI sends the request to the Docker API.
dockerd(daemon and API server; manages images and containers) checks whether the image is available.- The image is pulled from the registry if needed.
dockerdaskscontainerd(high-level runtime: lifecycle, images, snapshots; also used by Kubernetes) to create and start the container.containerdinvokesrunc(low-level OCI runtime: namespaces, cgroups, starts the process) with the OCI bundle.runcconfigures namespaces and cgroups on the Linux kernel, then starts the process.
In short: dockerd decides, containerd manages, runc creates. History: Docker first relied on LXC, then on libcontainer (Docker 0.9, 2014), which became runc, the OCI reference runtime (2015).
3.2 Alternatives to Docker
Thanks to the OCI standards, an image built with Docker can be run by other engines and runtimes: Podman (daemonless engine, Red Hat; no central daemon, rootless by default, Docker-compatible CLI, groups containers into pods); containerd + nerdctl (the industry-standard runtime used directly by Kubernetes via CRI, with a Docker-like nerdctl CLI); CRI-O (implements only the Kubernetes CRI, the default runtime of OpenShift); LXC / Incus (system containers that run a full Linux distribution, managed like lightweight VMs, Incus being a community fork of LXD). All share Linux namespaces + cgroups and the OCI image and runtime specifications (runc, crun).
| Criterion | Docker | Podman | containerd + nerdctl | CRI-O | LXC / Incus |
|---|---|---|---|---|---|
| Container type | Application | Application | Application | Application | System (full OS) |
| Architecture | Client + daemon (dockerd) | Daemonless | Daemon (runtime service) | Daemon for Kubernetes only | Daemon for system containers |
| Rootless mode | Supported (optional) | Default | Supported | Limited | Unprivileged containers |
| CLI | docker | podman (Docker-compatible) | ctr / nerdctl | crictl (debugging) | lxc / incus |
| Image build | Yes (BuildKit) | Yes (Buildah) | Via nerdctl + BuildKit | No | No (distribution images) |
| Typical use | Development, CI/CD, single hosts | Secure hosts, RHEL / Fedora | Kubernetes nodes, inside Docker | OpenShift / Kubernetes nodes | Labs, lightweight VMs |
4. Docker Images and Containers
A Docker image is a read-only template used to create containers: it includes the application code, runtime, libraries, environment variables and configuration files. Images are pulled from a registry (such as Docker Hub) or built from a Dockerfile.
An image is a stack of layers; each layer records a set of filesystem changes and depends on the ones below it (base OS files, runtime, dependencies, app files). A union filesystem (OverlayFS) presents the layers as one filesystem, and layers are shared between images for less disk space and faster builds; only modified layers are rebuilt.
4.1 Images vs. containers
Creating a container from an image adds a new writable layer on top of the image layers, the container layer. All changes made in a running container (creating, modifying or deleting files) are written to this layer; the image layers stay read-only and can be shared by many containers. The main difference between a container and an image is this top writable layer.
4.2 Container lifecycle
docker run = docker create + docker start. A container moves from Image (read-only template) to Created (docker create), to Running (docker start), to Paused (docker pause / docker unpause) or Stopped (docker stop / docker kill or process exit, with docker start / docker restart returning to Running), to Removed (docker rm).
- Observe:
docker ps(running containers),docker ps -a(all states),docker logs/docker inspect. - Interact:
docker exec -it <container> shruns a command inside a running container. - Remember: stop keeps the writable layer;
docker rmdeletes it, with its data.
4.3 Dockerfile
A Dockerfile is a text file containing the instructions required to build a Docker image automatically: it specifies the base image, languages, environment variables, files, network ports and the start command, making image creation repeatable and auditable.
FROM python:3.12-slim
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "app.py"]
docker build -t myapp:1.0 .
5. Container Orchestration
Container orchestration automates the deployment, scaling, networking and management of containers across a cluster of hosts. A control plane (orchestrator) holds the desired state (for example “web x 3 replicas”); scheduling places containers on the best node; scaling adds or removes replicas under load; self-healing restarts failed containers (if a node fails, its container is rescheduled on another node to restore the desired state); rolling updates deploy new versions without downtime. This matters because it gives high availability (failed containers are replaced automatically), efficient use of cluster resources, and faster, safer releases (DevOps, CI/CD).
| Criterion | Kubernetes | Docker Swarm | Nomad | Managed Kubernetes |
|---|---|---|---|---|
| What it is | Open-source standard (CNCF); distributions: OpenShift, k3s | Clustering mode built into Docker Engine | Single-binary scheduler (HashiCorp) | Kubernetes run by the cloud provider (EKS, AKS, GKE) |
| Complexity | High | Low | Medium | Medium |
| Scalability | Very high | Moderate | Very high | Very high |
| Best for | Production at any scale | Small clusters, learning | Mixed workloads (containers, VMs, binaries) | Teams that do not want to run clusters |
Kubernetes has become the de facto standard: most other platforms are built on it or integrate with it.