Skip to content

Support the containerd ns query parameter for multi-registry mirroring #303

Description

@pinguinfuss

Support the containerd ns query parameter for multi-registry mirroring

The container handler currently routes /v2/ requests by path only: unprefixed names go to the default registry (upstream.oci_default), and named upstreams require the reserved upstream/{name}/ path prefix. containerd's hosts.toml mirror mechanism instead appends ?ns=<registry-host> to every request (see containerd hosts.md), which the handler ignores today. Multi-registry mirroring therefore needs one hosts.toml per registry with override_path = true pointing at the matching prefix; wildcard setups (certs.d/_default, k3s mirrors: "*") cannot work at all, because the mirror never learns which registry a request is for.

Add ns support so a single host entry can mirror every configured registry.

Requirements

  • Treat ns as a closed-world lookup key, never a dial target: resolve Docker Hub aliases (docker.io, index.docker.io, registry-1.docker.io) and the host of the configured oci_default to the default route, and hosts derived from the existing upstream.oci URLs to their named upstream. No new config keys. Host matching is case-insensitive and normalizes scheme-default ports.
  • Unknown ns returns an OCI-error 404 (NAME_UNKNOWN) so containerd falls back to its next host / server entry; requests without ns behave exactly as today.
  • When ns is present, the path is the verbatim upstream repository; reject the reserved upstream/ prefix on that route so ns-routed requests cannot mint cache keys belonging to the prefix route.
  • Strip ns before forwarding the tags-list query upstream (it currently leaks verbatim).
  • Cache identities are reused so an image pulled via ns, via upstream/{name}/, or unprefixed shares cache entries; manifest keys already include the resolved registry URL.
  • Auth needs no changes: configured credentials and Bearer-challenge tokens are keyed on the resolved upstream URL.

Implementation notes

  • Build the ns host index after NewContainerHandlerWithRegistry overrides the default registry URL, otherwise a custom oci_default host would 404.
  • Duplicate hosts across upstream.oci entries (or colliding with the default route) get a startup warning and a deterministic winner rather than a validation error.
  • Blob digest verification on ingest is tracked separately but recommended as a preparatory change, since shared cache identities make unverified ingest a cross-route concern.

Tests

  • containerd-style pulls for docker.io (client-normalized library/ names) and a named registry.
  • ns=<custom-default-host> with an overridden oci_default.
  • Unknown ns → 404 with no upstream contact.
  • Cache sharing across the three routes (default, upstream/{name}/, ns).
  • upstream/-prefix rejection under ns.
  • No ns leakage to upstreams.
  • README and docs/configuration.md instructions with a _default hosts.toml example.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions