Self-hosted service
kubernetes/registry.k8s.io avatar
kubernetes/registry.k8s.io

registry.k8s.io is a volunteer run registry that asks you not to depend on it

This project is the repo for registry.k8s.io, the production OCI registry service for Kubernetes' container image artifacts

534 stars92 forksGoApache-2.0

At a glance

What is it?
This repository holds the backend behind registry.k8s.io, the OCI registry that serves Kubernetes container images, and its README is unusually blunt about what that means: no uptime SLA, endpoints and backing services can change at any time, and if you need to allow-list a domain you should mirror the images yourself. The reasons are all about egress costs.
Who is it for?
Adopt registry.k8s.io as the pull-through source for Kubernetes images, since it is the project supported home of them and the migration from k8s.gcr.io is explicitly requested. Do not build anything that depends on its endpoints, its IP addresses or its backing services, because the README says those may change at any time, and do not depend on its availability, since there is no SLA.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the README tells you not to do

registry.k8s.io is the production OCI registry service for Kubernetes' container image artifacts, and this repository implements the backend for it.

The service is GA, and the README asks that all users migrate from k8s.gcr.io as soon as possible. After that comes the part that matters, stated in capitals: do not depend on the implementation details of this registry.

The specifics are spelled out. Other than registry.k8s.io serving an OCI compliant registry, the API endpoints, the IP addresses and the backing services used are subject to change at any time as new resources become available or as otherwise necessary. And if you need to allow-list domains or IPs in your environment, the README highly recommends mirroring images to a location you control instead.

There is no uptime SLA, because this is a free, volunteer managed service. The project says it will do its best to respond to issues and that the system is designed to be reliable and low-maintenance, and then it gives the practical advice: if you need higher uptime guarantees, consider mirroring.

Put together, that is a specific contract. Pull images from here, do not depend on where they are served from, do not depend on it being up, and keep a copy you control.

The one part you can depend on is the interface: an OCI compliant registry. That is the industry specification, and it is the only stability guarantee the README offers.

The traffic arrangement is also stated. The Kubernetes project is currently sending traffic to GCP and AWS thanks to their donations, and the project hopes to redirect traffic to more sponsors and their respective API endpoints in the future to keep the project sustainable.

So the registry's architecture is a function of who is paying for the bandwidth. That is unusual for a registry, and it explains most of the caveats.

Why it moved off gcr.io

The Background section explains the move, and it is a cost story rather than a governance one.

Previously all of Kubernetes' image hosting was out of gcr.io, the Google Container Registry. The problem was egress traffic costs from users on other cloud providers, in particular in doing so, which severely limited the project's ability to use the GCP credits from Google for purposes other than hosting end-user downloads.

That is the whole mechanism. Cloud credits from a sponsor were being consumed by users on other clouds' networks, which meant the credits could not be used for the things the sponsors wanted them used for.

The response was to move all traffic behind a community controlled domain, so the project could quickly implement cost-cutting measures such as serving the bulk of the traffic for AWS users from AWS-local storage funded by Amazon, or potentially other providers in the future.

Read that as a routing strategy. The domain is stable and community controlled, and the backing storage is chosen per provider, so a user pulling from AWS gets served from AWS-local storage paid for by Amazon, and a user pulling from GCP gets served from GCP. The domain is the stable interface and the storage is the variable part.

That design is exactly why the README warns that the backing services are subject to change. The backing store for your region is not a contract, it is a donation.

The project links further context in the Kubernetes blog post on making the registry faster and cheaper, and a talk with more details titled Why We Moved the Kubernetes Image Registry. It also notes that the repository implements the backend sources for the steps outlined there.

The privacy position is short: the project abides by the Linux Foundation privacy policy, documented at the privacy page on the registry's own site.

archeio, and what the backend is built from

For details on the implementation the README points at `cmd/archeio`, with its own README in that directory, so that is where the design lives.

The Go module is `k8s.io/registry.k8s.io` and it requires Go 1.26.8, which sets the floor for anyone building it. The direct dependencies describe what the service does:

go
require (
	github.com/aws/aws-sdk-go-v2 v1.43.1
	github.com/aws/aws-sdk-go-v2/config v1.32.32
	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.36
	github.com/aws/aws-sdk-go-v2/service/s3 v1.106.1
	github.com/aws/smithy-go v1.27.5
	github.com/go-logr/zapr v1.3.0
	github.com/google/go-containerregistry v0.21.7
	go.uber.org/zap v1.28.0
	golang.org/x/sync v0.22.0
	golang.org/x/time v0.15.0
	k8s.io/klog/v2 v2.140.0
)

The AWS SDK is the centre of it, with the S3 service, the S3 feature manager and the configuration package. The indirect requirements make the purpose clearer still: `docker/cli` and `docker/docker-credential-helpers` are present, which is what you need to read private images from a registry and to talk to container runtimes, and `klauspost/compress` is the compression library.

`github.com/google/go-containerregistry` is the other load-bearing dependency. That is the Go library for working with container images and registries, so the backend is not parsing image formats itself, it is using the same library that most Go tooling uses, which is a reasonable choice for a service that has to serve OCI compliant output.

The observability stack is klog with the zap backend through `go-logr/zapr`, so the service logs through the Kubernetes logging conventions, and `golang.org/x/time` and `golang.org/x/sync` handle rate limiting and concurrency.

So the shape is a Go service that serves an OCI registry on top of object storage in a cloud, using the AWS SDK for the storage side, with the cloud chosen per provider as the donation arrangement allows.

Building it, and the old-skool makefile

The repository has a Makefile that describes itself as old-skool build tools, a simple makefile to build archeio quickly and reproducibly, with the common uses being `make build` and `make clean`.

The interesting part is the environment capture at the top:

make
# Old-skool build tools.
# Simple makefile to build archeio quickly and reproducibly
#
# Common uses:
# - building: `make build`
# - cleaning up and starting over: `make clean`
#
################################################################################
# ========================== Capture Environment ===============================
# get the repo root and output path
REPO_ROOT:=${CURDIR}
OUT_DIR=$(REPO_ROOT)/bin
# record the source commit in the binary, overridable
COMMIT?=$(shell git rev-parse HEAD 2>/dev/null)

The build output goes to `bin` at the repository root, and the source commit is recorded in the binary, with the value overridable so a reproducible build can be stamped with a specific commit.

Below that, the makefile handles the Go toolchain itself. It runs `. hack/tools/setup-go.sh` and takes the resulting PATH, which is how the correct Go version is selected using gimme, and it sets `GO111MODULE=on`. There is also a note that Go 1.9 and later can autodetect GOROOT but that the variable is cleared if some other tool sets it, and that CGO is disabled by default to produce static binaries.

That is a slightly old-fashioned build setup for a Go 1.26 project, and it comes with the Kubernetes house style rather than from the project itself. The repository also has a `.go-version` file, which is the more modern way to pin the toolchain, so the gimme path and the `.go-version` file coexist.

The `hack/` directory holds the helper scripts, and the top level also has `cmd/` for the binaries, `internal/` and `pkg/` for the code, `docs/` for the guides, `cloudbuild.yaml` for the build pipeline, plus `OWNERS`, `CONTRIBUTING.md`, `SECURITY.md` and `SECURITY_CONTACTS`.

Deployment, publishing and how to reach the maintainers

This repository is not the deployment configuration, and the README is explicit about where that lives.

The community deployment configs are documented in the k8s.io repository with the rest of the community infrastructure deployments, and the link points at the `infra/gcp/terraform` directory in the kubernetes/k8s.io repository. So the backend code is here and the deployment is there, which is the normal split for a Kubernetes project and also means you cannot read the deployment from this repository alone.

For publishing, the README points at the docs in k8s.io under `registry.k8s.io/`, in the site repository, which covers managing the Kubernetes container registries.

The `cloudbuild.yaml` at the root is the build pipeline, which is the Google Cloud Build configuration for producing the container images the service runs.

Support is through the standard Kubernetes channels. The maintainers are reachable on Slack in the channel `#sig-k8s-infra` and on the SIG Infra mailing list, and participation is governed by the Kubernetes Code of Conduct, with the file in this repository.

The issue tracker has a specific convention that is worth knowing before you file anything: known user-facing issues are pinned at the top of the issue tracker. So a symptom you are seeing has probably been reported before, and reading the pinned issues first is faster than filing a duplicate. There is also a debugging guide for identifying and resolving or reporting issues, and a mirroring guide for how to mirror and use mirrored Kubernetes images.

That last document is the one to read before you decide what to build against. It is the README's own recommendation for anyone who needs allow-listing or uptime guarantees, and it is the answer to the question of what happens when you cannot depend on the registry.

Editorial conclusion

Adopt registry.k8s.io as the pull-through source for Kubernetes images, since it is the project supported home of them and the migration from k8s.gcr.io is explicitly requested. Do not build anything that depends on its endpoints, its IP addresses or its backing services, because the README says those may change at any time, and do not depend on its availability, since there is no SLA. Verify first that your allow-list will not block it or, better, that you have set up mirroring to storage you control as the mirroring guide describes, that the image references you use point at registry.k8s.io rather than k8s.gcr.io, and that the version of this repository you read matches the release you deploy, with v0.8.0 tagged on 2026-10-01 and the last push on 2026-10-16.

Frequently asked questions

What is registry.k8s.io?

It is the production OCI registry service for Kubernetes' container image artifacts, and this repository implements its backend. The service is GA and the README asks that all users migrate from k8s.gcr.io as soon as possible.

Is there an uptime SLA for registry.k8s.io?

No. The README states there is no uptime SLA because it is a free, volunteer managed service, and says that if you need higher uptime guarantees you should consider mirroring images to a location you control.

Can I depend on the registry.k8s.io endpoints and IP addresses?

No. The README says the API endpoints, IP addresses and backing services are subject to change at any time, and that if you need to allow-list domains or IPs in your environment you should mirror images to a location you control instead. The only stated guarantee is that the registry serves an OCI compliant registry.

Why was Kubernetes image hosting moved off gcr.io?

Egress traffic costs from users on other cloud providers were severely limiting the project's ability to use the GCP credits from Google for purposes other than hosting end-user downloads. Moving traffic behind a community controlled domain let them serve the bulk of traffic for AWS users from AWS-local storage funded by Amazon, and potentially other providers later.

What is the implementation built on?

The module is `k8s.io/registry.k8s.io` and requires Go 1.26.8. Its direct dependencies are the AWS SDK v2 with the S3 service and manager, smithy-go, klog with the zap backend, `github.com/google/go-containerregistry` for container image handling, zap, and the x/sync and x/time libraries. The implementation details are documented in `cmd/archeio`.

Official sources

  1. kubernetes/registry.k8s.io on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kubernetes-registry-k8s-io.svg)](https://hysenlabs.com/projects/kubernetes-registry-k8s-io)

Was this useful?