Skip to main content

Pull images from a private registry

Registry credentials are scoped to a namespace, which makes them a useful isolation boundary. Give each client its own namespace with its own pull secret, and one client's registry access stays invisible to another's pods. On a cluster shared by several tenants, this keeps their registry access separated 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 lives in the cluster, where a compromised pod could read it, so it should be able to pull images and nothing more.

Attach it: pod or ServiceAccount 

You can name the Secret on a pod:

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

However, if you don't want to set it manually on every workload, 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 they can leak, so plan to rotate them. Generate a new token and overwrite the existing 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 -
			

A common concern is that rotating the credential will disrupt running workloads, but it does not. Already-running pods keep the images they have already pulled, and only the next pull uses the new credential. Rotation is a Secret update, not a redeploy, so 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, instead of a Back-off, confirms the credential is working.