feat(registry): optionally push images to and mirror pulls through a local registry - #3
Draft
tdakkota wants to merge 2 commits into
Draft
feat(registry): optionally push images to and mirror pulls through a local registry#3tdakkota wants to merge 2 commits into
tdakkota wants to merge 2 commits into
Conversation
…local registry E2E_REGISTRY=host:port makes the suite docker push what it builds instead of kind loading it, and points every node's containerd at the same host as a pull-through mirror for docker.io, ghcr.io, quay.io and registry.k8s.io. Unset — the default — nothing changes: images are side-loaded and the nodes pull from upstream. The hosts.toml is modelled on tdakkota/nixfra modules/registry-mirrors.nix, which is the config running on a real cluster. Two of its details are load-bearing and asserted in a test so they cannot regress: docker.io's fallback must be registry-1.docker.io (docker.io is a website, and containerd caches the HTML it serves as a manifest), and override_path must be true (the mirror lives under /v2/<domain>, so containerd would otherwise double the /v2 prefix). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records the three things that cost real debugging time: the docker.io-is-a-website content-store poisoning (and how to evict the poisoned blob), the override_path requirement, and the fact that a pull-through mirror may re-digest manifests, so digest-pinned pulls cannot be satisfied from one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an opt-in local-registry path to the suite:
E2E_REGISTRY=host:portmakes itdocker pushthe images it builds instead ofkind loading them, and points every kind node's containerd at the same host as a pull-through mirror fordocker.io,ghcr.io,quay.ioandregistry.k8s.io.Default is unchanged. With
E2E_REGISTRYunset,cfg.inRegistryleaves the image tags bare,build.BinaryImagetakes thekind loadbranch exactly as before,configureRegistry()returns immediately, and nothing is written to/etc/containerd/certs.d. The only unconditional change iskind.yamlsetting containerd'sconfig_pathto that directory — inert while the directory is empty. CI and anyone without a registry are unaffected.Why this is worth having
On a machine that already runs a pull-through cache, a suite run stops hitting the internet for the kind node image, the dev etcd, and the operator's dependencies, and the built images move over the LAN rather than through
kind load's tar-per-node side-load.The hosts.toml is copied, not invented
It is modelled on the containerd config running on a real cluster —
tdakkota/nixfra,modules/registry-mirrors.nix— because two of its details are load-bearing, non-obvious, and very easy to "simplify" back into a broken state. Both are asserted ininternal/registry/registry_test.goso a future cleanup fails the build rather than the cluster.docker.io's upstream must behttps://registry-1.docker.io.https://docker.iois a website. containerd follows the fallback, gets HTML, and caches it in the content store as if it were a manifest. Every later pull of that image fails withunexpected media type text/html for sha256:..., and it stays broken across containerd restarts until the poisoned blob is evicted by hand:override_path = trueis required. The mirror is addressed as<registry>/v2/<domain>; without it containerd appends its own/v2/<repo>and requests.../v2/docker.io/v2/library/alpine/manifests/3.21, which 404s.A third property is documented but not configurable: a pull-through mirror may re-digest what it caches (Zot serves an
alpineindex digest that differs from Docker Hub's), so pulls pinned to an upstream digest rather than a tag are inherently fragile through one.Verification
Everything below ran against a Zot at
10.42.0.44:5000.Full suite, role pools enabled, all four images pushed to and pulled from the registry:
Kubelet confirms the pull path rather than a side-load:
The exact
hosts.tomlthis branch generates was then re-verified on a throwaway single-node cluster. Before writing any of it, the default path pulls fine; after writing it, a cold tag demonstrably routes through the mirror:quay.io/coreos/etcd:v3.5.17(the dev etcd) and a registry-hostedclaude-e2e/oteldbimage both resolve through the same config.Notes
insecure-registries— that is what thedocker pushand kind's own node-image pull go through. Documented in the README.manifests/cluster.yamlpins a barespec.image; under a registry the suite patches the CR to the registry-qualified tag after apply, rather than forking the manifest.OTELDB_IMAGE=ghcr.io/...still wins overE2E_REGISTRY.🤖 Generated with Claude Code