23.2e Union filesystems (overlay2): layered image architecture explained

📦 Nvidia Software Stack 📖 Containerization Fundamentals

🧭 Context Introduction

When you run a container, you're not copying an entire operating system into a new environment each time. Instead, containers use a clever trick called union filesystems to share common layers between images. This is what makes containers lightweight, fast to start, and efficient with disk space.

Think of it like a stack of transparent sheets — each sheet adds or modifies content, but the sheets underneath remain unchanged. The overlay2 driver is Docker's default way of implementing this layered architecture on modern Linux systems.


⚙️ What is a Union Filesystem?

A union filesystem allows multiple filesystem layers to be merged into a single, unified view. Each layer is read-only, except for the topmost layer where changes happen.

  • Each layer represents a set of file changes (additions, modifications, deletions)
  • Layers are stacked on top of each other
  • The final view shows all layers combined
  • Only the top layer is writable — all lower layers are shared and read-only

🧱 The Layered Image Architecture

Docker images are built from a series of layers. Each instruction in a Dockerfile creates a new layer.

How layers work:

  • Base layer: The starting point (e.g., Ubuntu, Alpine, or a minimal NVIDIA CUDA image)
  • Intermediate layers: Each command like apt-get install or COPY creates a new layer
  • Top layer (container layer): When you run a container, a thin writable layer is added on top
  • Sharing: If two images share the same base layer, that layer is stored only once on disk

🛠️ How overlay2 Works Under the Hood

The overlay2 driver uses two main directories:

  • Lower directory: Contains the read-only image layers
  • Upper directory: The writable container layer

When a file is read: - The system looks in the upper directory first - If not found, it looks through the lower directories in order - The first match is returned

When a file is modified: - The original file stays untouched in the lower layer - A copy is made to the upper layer (copy-on-write) - All changes happen in the upper layer only

When a file is deleted: - A special "whiteout" file is placed in the upper layer - This hides the file from the lower layer without actually deleting it


📊 Visual Representation: OverlayFS Stacked Layer Union

This diagram displays OverlayFS layers: combining read-only image layers with an active read-write layer to create the unified container view.

flowchart LR Upper["Upper Layer (Read-Write / Container modifications)"] --> Unified["Unified View (Active Container mount)"] Lower["Lower Layer (Read-Only Image layers)"] --> Unified classDef cpu fill:#eafaf1,stroke:#76b900,stroke-width:2px,rx:6px,ry:6px; classDef memory fill:#f0f7ff,stroke:#3498db,stroke-width:1.5px,rx:4px,ry:4px; classDef system fill:#f1f5f9,stroke:#64748b,stroke-width:1.5px; class Unified cpu; class Upper,Lower memory;

📊 Comparison: Traditional vs Layered Filesystem

Aspect Traditional Filesystem Layered (overlay2) Filesystem
Disk usage Full copy per container Shared layers, minimal duplication
Start time Slow (full copy needed) Fast (just add writable layer)
Updates Replace entire image Only changed layers are updated
Storage efficiency Low High
Image size Large Small (only differences stored)

🕵️ Copy-on-Write (CoW) Explained

Copy-on-Write is the magic behind overlay2's efficiency.

  • When a container tries to modify a file from a lower layer, the file is copied up to the writable layer
  • The original file in the lower layer remains unchanged
  • Multiple containers sharing the same base image each get their own writable layer
  • Each container sees its own modifications without affecting others

Example scenario:

  • Image has a 500MB Python library in a lower layer
  • Ten containers run from this image
  • Without CoW: 5GB of disk space used
  • With CoW: Only 500MB for the library + small writable layers for each container

🧩 Why This Matters for AI Workloads

AI and deep learning images are often very large — sometimes tens of gigabytes. The layered architecture is critical for:

  • Sharing NVIDIA CUDA base layers across multiple AI containers
  • Rapid iteration during model development (only changed layers are rebuilt)
  • Efficient deployment of models to production (pull only new layers)
  • Reducing storage costs in multi-tenant GPU clusters

🔍 Key Takeaways for New Engineers

  • overlay2 is the default and recommended storage driver for Docker on modern Linux
  • Layers are read-only — only the container's writable layer can be modified
  • Copy-on-Write prevents unnecessary duplication of data
  • Shared layers mean you can run hundreds of containers from the same image with minimal disk overhead
  • Image size ≠ container size — a large image can spawn many small containers
  • Layer caching speeds up builds — Docker reuses unchanged layers from previous builds

🧪 Practical Understanding Check

When you pull an image like nvidia/cuda:12.2-runtime-ubuntu22.04:

  • Docker downloads all layers that are not already cached locally
  • Each layer is stored in /var/lib/docker/overlay2/
  • When you run a container, overlay2 creates a merged view of all layers plus a new writable layer
  • If you run a second container from the same image, it reuses all existing layers — only a new writable layer is created

This layered approach is what makes containerized AI workflows practical at scale, especially when working with large GPU-accelerated environments.