What happens between naming an image reference and having its layers on a host that never held them?
answer
- a name in, bytes out
- resolve first, transfer second
- authorise before the manifest
- the manifest is the shopping list
- ask only for missing digests
basics
~20 sThe reference is parsed and resolved at the registry to a manifest and its digest, the client proves it may read that repository, the manifest is read for the blobs it lists, and only the digests the host lacks are fetched, checked and expanded.
solid answer
~40 sFour things happen in order. First the reference is parsed into a registry, a repository and a selector — a movable pointer or a digest. Second the client obtains read authorisation for that repository, typically by exchanging a configured credential for a short-lived, narrowly scoped one. Third it fetches the manifest for that selector; the registry returns the document and the digest of that document, and if what came back selects per platform, the client picks the entry matching the host and fetches that manifest by digest. Fourth it walks the blob list — the configuration blob and each layer, every one with a digest and a size — skips the digests it already holds, fetches the rest, checks each against its digest, and expands the layers onto disk.
code
pseudocode · 18 linespull(reference):
registry, repository, selector = parse(reference)
credential = readCredentialFor(registry) # short-lived, scoped to read
manifest = registry.getManifest(repository, selector, credential)
if manifest.selectsPerPlatform:
entry = manifest.entryMatching(host.architecture, host.operatingSystem)
manifest = registry.getManifest(repository, entry.digest, credential)
for blob in [manifest.configBlob] + manifest.layerBlobs:
if localStore.holds(blob.digest):
continue # nothing crosses the network
bytes = registry.getBlob(repository, blob.digest, credential)
if digestOf(bytes) != blob.digest:
fail("transferred bytes do not match the digest that named them")
localStore.put(blob.digest, bytes)
expandToDisk(manifest.layerBlobs)go deeper
Know the order: resolve the name, prove you may read, read the list, fetch what is missing. Being able to say the four steps in sequence is the bar here.
Explain why resolution comes first and why everything after it is expressed as digests, and why that makes the local skip decision safe and purely local.
Bring in the operational consequence: which start-up policy is configured decides whether a registry outage stops replacements, and whether a moved pointer is ever picked up.
Weigh the estate-wide choice — resolving every time keeps pointers honest but couples every start to the registry's availability, and that coupling is a design decision, not a default to inherit.
## The steps, in order 1. **Parse the reference.** A reference carries three things: which registry to talk to, which repository inside it, and a selector — either a movable pointer or a digest. 2. **Get read authorisation.** Registries generally answer an unauthorised request with a challenge naming where authorisation comes from; the client exchanges whatever credential it was configured with for a short-lived one, scoped to reading that one repository. Public repositories may skip this, and anonymous access is usually the more tightly limited path. 3. **Fetch the manifest.** The registry resolves the selector and returns the manifest document along with **its** digest. From here on the host is working with a fixed identity, whatever the selector was. 4. **Choose a platform, if the document selects one.** If the returned document is an index over several per-platform manifests, the client picks the entry matching the host's processor architecture and operating system and fetches that manifest by digest. 5. **Diff against the local store.** The manifest lists the configuration blob and each layer, every entry carrying a digest and a size. The host asks its content store, per digest, whether it already holds that blob, and builds a request set out of the misses only. 6. **Transfer, check, expand.** Missing blobs are fetched, each checked against the digest that named it, and the layers written out in expanded form. Only now can a runtime build a filesystem view and start a process. ## Everything after resolution is by digest Step 3 is the hinge of the whole sequence. Before it, the host has a **name**; after it, the host has a **content-derived identity** and works only in those terms. That is why the steps that follow can be answered locally and cached safely: a digest cannot mean two different byte sequences, so "do I hold this?" is a decidable local question, and a blob once held never needs re-checking against the source. It is also why the expensive part of a pull is skippable. The host does not need to ask the registry what it is missing — it already knows, from the manifest, before it opens a single blob request. ## When the host already holds the image A host that holds every blob still has a decision to make: does it resolve the reference again, or use what it has? Platforms expose this as a policy rather than fixing it, because the two choices fail differently. | Policy | On start-up | If the registry is unreachable | |---|---|---| | resolve the reference every time | contacts the registry, picks up a moved pointer | the start is blocked at step 2 or 3 | | use the local copy when present | starts immediately from the store | unaffected — nothing is requested | The first is what you want when the reference is a pointer that is expected to move. The second is what keeps a fleet serving through a registry outage, at the price of hosts quietly running whatever they happen to hold. Knowing which one is configured is usually the difference between predicting an incident and being surprised by one. ## What the transfer proves, and what it does not Checking a blob against the digest that named it proves one thing: **the bytes received are the bytes the manifest asked for**. Corruption in transit, a truncated response and a substituted blob all fail that check. It says nothing about whether the manifest itself came from a publisher you should trust — that is a separate question, decided by a separate mechanism, and conflating the two is a common interview stumble. ## Why the order matters in practice - **The manifest is the list.** Until it is read, the host cannot know what to request or what it already has, so nothing is fetched in parallel with resolution. - **Authorisation is needed before any bytes.** The credential is not presented at the end to unlock what arrived; it gates the manifest request itself. - **The per-platform choice happens before any layer moves.** A host with no matching entry fails at selection, having transferred no layer at all. - **Sizes are known in advance.** Because the manifest carries each blob's size, the host can report progress and reason about disk before the first byte lands. - **The sequence is the same everywhere.** Products differ in what they call the puller and where the credential comes from, but resolve, authorise, read the list, fetch the misses, verify and expand is the shape underneath all of them.
- Why is the manifest fetched before any layer?Because it is the list. It names the configuration blob and every layer by digest and size, so until the host has read it, it does not know what to ask for, what it already holds, or how much disk the result needs. Layers cannot be requested speculatively — their digests are not knowable from the reference.
- The host already holds the image. Does it still contact the registry?That depends on configured policy. Under a resolve-every-time policy it re-resolves the reference on each start, so a moved pointer is picked up and an unreachable registry blocks the start. Under a use-local-copy policy it starts from the store and asks for nothing. Platforms expose this as a choice rather than fixing it.
- What does checking a blob against its digest actually prove?That the bytes that arrived are the bytes the manifest named — an integrity check over the transfer. It catches corruption, truncation and substitution of a blob. It makes no claim about who published the image or whether the manifest should be trusted; that is decided by a different mechanism entirely.
saying these in an interview costs you the question
- Thinks the registry sends one image file rather than a list of blobs
- Believes the credential is presented after the layers arrive
- Assumes a movable pointer is never resolved server-side
- Thinks blobs are requested before any manifest is read
- Confuses checking a blob's digest with trusting its publisher
- Assumes every host re-contacts the registry on every start