Kubernetes
Container Registry
Private Registry
Docker
Image Pulling

Pulling images from private registry in Kubernetes

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When a Kubernetes workload uses an image from a private registry, the cluster needs credentials before it can pull that image. The standard solution is to store registry credentials in a Secret and reference that Secret through imagePullSecrets or through a ServiceAccount used by the Pod.

Create a Registry Secret

Kubernetes expects registry credentials in a Secret. The most direct CLI path is kubectl create secret docker-registry.

bash
1kubectl create secret docker-registry regcred \
2  --docker-server=registry.example.com \
3  --docker-username=myuser \
4  --docker-password=mypassword \
5  --docker-email=[email protected]

That creates a Secret named regcred in the current namespace. Namespace matters here. A Pod can only reference Secrets from its own namespace, so if the workload runs in production, the Secret must also exist in production.

Reference the Secret from the Pod

Once the Secret exists, attach it to the workload through imagePullSecrets.

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: private-app
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: private-app
10  template:
11    metadata:
12      labels:
13        app: private-app
14    spec:
15      imagePullSecrets:
16        - name: regcred
17      containers:
18        - name: app
19          image: registry.example.com/team/private-app:1.0.0
20          ports:
21            - containerPort: 8080

When the Pod starts, the kubelet uses the referenced credentials to authenticate to the registry and pull the image.

This is the explicit per-workload approach. It is clear and easy to debug because the Deployment manifest shows exactly which Secret is involved.

Use a ServiceAccount for Reuse

If many workloads in the same namespace need the same private registry, attach imagePullSecrets to a ServiceAccount instead of repeating the secret name on every Pod spec.

yaml
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4  name: private-registry-sa
5imagePullSecrets:
6  - name: regcred
7---
8apiVersion: apps/v1
9kind: Deployment
10metadata:
11  name: private-app
12spec:
13  replicas: 1
14  selector:
15    matchLabels:
16      app: private-app
17  template:
18    metadata:
19      labels:
20        app: private-app
21    spec:
22      serviceAccountName: private-registry-sa
23      containers:
24        - name: app
25          image: registry.example.com/team/private-app:1.0.0

This keeps the workload manifests cleaner and makes it easier to rotate registry access in one place.

Know the Cloud-Specific Variants

The generic Secret pattern works everywhere, but some managed registries also support platform-native authentication. For example, clusters running on cloud providers may use node identities, workload identities, or helper integrations for ECR, Artifact Registry, or ACR. Even in those environments, the underlying question is the same: how will the kubelet authenticate to the registry when it pulls the image?

When a native integration exists, it is often better than hardcoding long-lived credentials into a Secret. Still, understanding imagePullSecrets is important because it remains the portable Kubernetes mechanism.

Check Pod Events When Pulls Fail

When image pulling fails, the fastest signal is usually in the Pod events rather than in the application logs. Describe the Pod and look for messages such as authentication failure, DNS failure, or repository-not-found errors.

bash
kubectl describe pod private-app-abc123

If the event stream shows ImagePullBackOff, follow the exact reason string. It often tells you whether the problem is the Secret contents, the registry hostname, the image tag, or simple network reachability.

Common Pitfalls

The most common mistake is creating the Secret in the wrong namespace. Kubernetes will not look across namespaces for it.

Another issue is using the wrong registry hostname in the Secret. The server string must match the registry the image is actually pulled from.

People also often create the Secret correctly but forget to reference it from the Pod or ServiceAccount. When that happens, the event log usually shows ImagePullBackOff or an authentication failure even though the Secret exists.

Summary

  • Private images in Kubernetes require registry credentials at pull time.
  • The standard solution is a Secret created with kubectl create secret docker-registry.
  • Reference that Secret through imagePullSecrets or a ServiceAccount.
  • Keep the Secret in the same namespace as the workload.
  • Use cloud-native registry identity integrations when available, but understand the generic Secret pattern first.

Course illustration
Course illustration

All Rights Reserved.