skip to content

An image is a stack of read-only layers merged into one view — what does a process see when two layers hold the same path?

level: juniorimportance: must knowfreq 76%

answer

  1. one tree, many stacked layers
  2. lookup walks the stack downward
  3. upper copy shadows the lower one
  4. files shadow, directories merge
  5. deletion marker hides, never removes

basics

~20 s

A union filesystem stacks the layers and serves one merged tree: for any path the highest layer that mentions it wins, so an upper layer's copy hides the identical path in every layer beneath it. The lower bytes remain in the image.

solid answer

~40 s

An image is an ordered stack of read-only layers, each recording the filesystem changes made at one build step — files added, files written over a path an earlier layer used, and paths marked removed. At run time a union filesystem merges them and presents one root filesystem, so the process inside sees an ordinary tree and cannot tell how many layers produced it. Lookup is top-down: the topmost layer that mentions a path decides the outcome. An upper layer's file shadows the lower one, which stays stored in the image but is unreachable through the merged view. If the topmost mention is a deletion marker, the path reads as absent while the file below it is untouched. Directories are the exception — their entries are merged from every layer rather than replaced wholesale.

code

pseudocode · 15 lines
pseudocode
resolve(path):
    mergedEntries = empty set
    for layer from topmost down to lowest:
        entry = layer.lookup(path)
        if entry is missing:
            continue
        if entry is deletionMarker:
            return NOT_FOUND            # highest mention wins, path is gone
        if entry is file:
            return entry.content        # first file found wins, stop here
        if entry is directory:
            mergedEntries.add(entry.children)   # keep scanning lower layers
    if mergedEntries is not empty:
        return mergedEntries
    return NOT_FOUND

go deeper

for a junior

Be able to say it plainly: an image is a stack of read-only layers, something merges them into one filesystem, and the highest layer holding a path is the one you read.

for a middle

Explain the resolution rule and its exceptions: files shadow, directories merge entries, a deletion marker hides a path that still exists below, and the container's own writable layer sits at the very top of the same stack.

for a senior

Connect the rule to what you have measured — shadowed copies inflating stored and transferred size, deep stacks costing lookup work, and a replaced file that a diagnostic tool still finds in a lower layer.

for a principal

Frame it as the trade the format makes: cheap start-up and cross-image reuse are bought with an append-only stack, so image hygiene must be enforced when layers are produced rather than repaired afterwards.

## One tree assembled from many layers A container image is an **ordered stack of read-only layers**. Each layer records the filesystem changes made at one step of the build: files added, files written at a path an earlier layer already used, and paths marked as removed. No single layer is a complete filesystem, and none of them can be edited after the fact. Only the stack, read together, describes a root filesystem. When a container starts, the runtime hands that stack to a **union filesystem** — a filesystem that mounts several directory trees at one point and serves them as one. The process inside sees an ordinary root: directories it can list, files it can open. Nothing in the normal filesystem interface tells it how many layers produced that tree, or which layer supplied any given file. That is deliberate. Layering is a storage and distribution technique, and the running program is meant to be unaware of it. ## Top-down resolution decides every path The layers are ordered, and lookup walks them from the top down. For any path: - If the topmost layer that mentions the path holds a **file**, that file is what the process reads. The same path in every lower layer is **shadowed** — unreachable through the merged view, though its bytes are still stored in the image. - If the topmost mention is a **deletion marker** — a record meaning "from this layer upward, this path is gone" — the path resolves as absent. The marker does not modify the layer below it; the file down there is intact and still shipped with the image. - If no layer mentions the path at all, it simply does not exist. So "which layer wins" has a one-line answer: **the highest layer that says anything about the path**. Replacing a configuration file in a later layer does not edit the earlier copy — it buries it. ## Files shadow, directories merge The one place where plain shadowing does not apply is directories. A directory is not replaced wholesale: the union filesystem merges the entries contributed by every layer that holds that directory, so a lower layer's ten files and an upper layer's one new file appear together as eleven entries. Some implementations additionally support marking a directory as replacing everything beneath it, and platforms differ in how they express that; it is the deliberate exception, not the default behaviour. | What the topmost layer holds at the path | What the merged view shows | What happens to the lower copy | |---|---|---| | A file | That layer's file | Stored, shadowed, unreachable | | A deletion marker | Nothing at that path | Stored, hidden, still shipped | | A directory | Its entries merged with every lower layer's entries | Visible alongside the upper entries | | Nothing at all | Whatever the next layer down holds | Served directly from below | ## Where the container's own writes sit The stack a running container sees has one more entry than the image does: a **writable layer on top**, into which everything the process writes is recorded. The same top-down rule explains its effect — a file the container creates or modifies sits above the image's copy and therefore shadows it, which is why a running container can appear to change an image that is, by construction, read-only. The image itself is never touched. ## Why the shape was chosen, and what it costs 1. **Assembly is cheap.** Starting a container copies no image data anywhere; the union filesystem composes layers that are already on disk, which is why start-up does not scale with image size. 2. **Read-only lower layers can be shared.** Because no container may modify them, one stored copy of a layer can serve many containers, and many images, on the same host. 3. **Only the changed part has to move.** A change confined to an upper layer leaves the lower ones byte-identical, so a host that already has them needs nothing new for those. The costs are real as well: - A path several layers mention must be resolved through them; deeper stacks do more lookup work, and implementations cache that resolution differently. - A file replaced in a later layer exists twice in the stored image, and the hidden copy is paid for on every transfer. - The merged view's apparent size is always smaller than the image's stored size whenever anything is shadowed or marked deleted. ## Answering it in an interview Say three things in order: an image is an ordered stack of read-only layers; a union filesystem merges them into one tree for the process; lookup is top-down, so the topmost layer mentioning a path wins and everything under it is hidden rather than removed. Then add the consequence that shows you have actually shipped images — hiding is not deleting, which is why an image never gets smaller just because a later layer removed something.

  • What does the merged view show when the topmost mention of a path is a deletion marker?
    Nothing — the path resolves as absent, and a process inside the container gets the same result as for a path that was never created. The marker only records the absence from that layer upward; the file that an earlier layer added is unchanged, still stored in the image, and still transferred with it.
  • Does the number of layers in an image change what the process inside sees?
    No. Two images whose merged trees are identical look the same to the process regardless of how many layers produced them. Layer count affects storage bookkeeping, how much can be reused between images, and how much work path resolution does; platforms also set a ceiling on how many layers they will stack. None of that is visible through ordinary file operations.
  • An upper layer adds one file to a directory an earlier layer already populated. What is listed?
    Both sets of entries. Directories merge rather than shadow, so the listing contains the earlier layer's files and the new one together. Only a same-path collision on an individual file shadows, and only an explicit marker declaring the directory a wholesale replacement hides the lower entries.

Stacked sheets of tracing paper: you look down through the pile and see one picture, and wherever the highest sheet has ink, that is what you see. The marks on the sheets underneath are still there, just hidden.

saying these in an interview costs you the question

  • Thinks the runtime copies every layer into one real directory at start-up
  • Says the lowest layer wins when two layers hold the same path
  • Believes writing a file in an upper layer deletes the lower copy
  • Assumes an upper layer's directory hides the lower directory's other entries
  • Claims the process inside can see layer boundaries rather than one tree