Skip to main content

Pull images from a private registry

Inspect 1.36

Registry credentials live in a namespace. That one detail is what turns a chore into an isolation boundary: give each client its own namespace with its own pull secret, and one client's registry access is never visible from another's pods. If you run several tenants on the same cluster, this is the seam that keeps their supply chains apart without any extra tooling.

Create the credential Secret#

		$ kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=<user> \
  --docker-password=<token> \
  --namespace team-web
	

Use a registry access token scoped to pull-only, not your personal login. The credential sits in the cluster where a compromised pod could read it, so it should be able to do exactly one thing: pull.

Attach it: pod or ServiceAccount#

You can name the Secret on a single pod:

yaml
		spec:
  imagePullSecrets:
    - name: regcred
  containers:
    - name: app
      image: registry.example.com/team/app:1.4.0
	

But you rarely want to. Attach it to the namespace's default ServiceAccount instead, and every pod inherits it with no per-pod change:

		$ kubectl patch serviceaccount default -n team-web \
  -p '{"imagePullSecrets":[{"name":"regcred"}]}'
	

From here, anything scheduled into team-web pulls from the private registry. This is the setup you want for a whole team or client: one place to point at the registry, one place to rotate.

Rotate credentials#

Tokens expire and tokens leak, so plan to replace them. Mint the new token and overwrite the Secret in place:

		$ kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=<user> --docker-password=<new-token> \
  --namespace team-web --dry-run=client -o yaml | kubectl apply -f -
	

Here is the part people expect to go wrong, and it does not: already-running pods keep the images they have pulled, and only the next pull uses the new credential. Rotation is a Secret update, not a redeploy. Nothing restarts.

When it says ImagePullBackOff#

Start at the bottom, in the events:

		$ kubectl describe pod <pod> -n team-web
	

ImagePullBackOff and ErrImagePull are symptoms; the event line underneath names the actual cause. Map the message to the fix:

A Pulled event, not a Back-off, is how you know the credential is doing its job.