fivenines
9/40
Lesson 9 · Images

Union Filesystems

In one sentence: A union (overlay) filesystem stacks read-only layer directories under one thin writable directory and presents the merged result as a single filesystem — so a container can "modify" an immutable image without copying it.

You already know

  • From Lesson 7: an image is an ordered list of layer archives.
  • From Lesson 8: layers are immutable — different bytes would mean a different digest.
  • From Lesson 4: the MNT namespace needs a root filesystem to give the container.

Stacking transparencies

Think of each layer as a transparency sheet: lower sheets show through wherever upper sheets are blank. An overlay mount takes the image's layers as read-only lowerdirs (in manifest order), adds one empty writable upperdir, and exposes a merged view that the container mounts as /. Reads search top-down and return the first hit. Writes never touch the lowers — they land in the upper. Ten containers from one image share every read-only sheet and differ only in their thin upper layers.

Architecture — one overlay mount, seen from the container
flowchart TB
  V["merged view — the container's /
(what the process sees)"] U["upperdir (writable, per-container)
changed: /etc/app.conf"] L3["lowerdir: app layer (RO)
/app/server"] L2["lowerdir: runtime layer (RO)
/usr/bin/python"] L1["lowerdir: base layer (RO)
/bin, /lib, /etc/app.conf"] V --- U U --- L3 L3 --- L2 L2 --- L1 style U fill:#fff8ec,stroke:#f2ddb0

Reads resolve top-down

The read path is the whole algorithm: check the upper, then each lower in order, first match wins. A file "modified" by the container exists twice — original in a lower, changed copy in the upper — and the upper always shadows:

Sequence — two reads through the stack
sequenceDiagram
  participant P as Container process
  participant O as Overlay driver
  participant U as upperdir
  participant L as lowerdirs (top → bottom)
  P->>O: read /etc/app.conf
  O->>U: exists here?
  U-->>O: yes (container changed it)
  O-->>P: upper copy — shadows the original
  P->>O: read /usr/bin/python
  O->>U: exists here?
  U-->>O: no
  O->>L: search layers top-down
  L-->>O: found in runtime layer
  O-->>P: read-only original, shared by all containers
    

Anchor these

  • Overlay = ordered read-only lowers + one writable upper + a merged view.
  • Reads: top-down, first hit wins. The upper shadows every lower.
  • N containers from one image share all lowers; each pays only for its upper.
Next step

See what actually stuck.

Take the practice scenarios now.