> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Image Security

> How to configure Kubernetes to pull images from a private Docker registry by creating a docker-registry Secret and referencing it via imagePullSecrets in a Deployment

In this lab you'll secure image pulls from a private Docker registry by creating a Kubernetes Secret of type `docker-registry` and referencing it in a Deployment's pod spec via `imagePullSecrets`. This enables Kubernetes to authenticate to private registries when creating Pods.

## Which Secret type should you use for Docker registries?

Kubernetes supports multiple Secret types. For authenticating to a Docker registry you must use the `docker-registry` Secret type.

| Secret type | Use case | Notes |
| - | - | - |
| `docker-registry` | Authenticate to Docker or container registries | Required for registry credentials used by `imagePullSecrets` |
| `generic` | Arbitrary key-value pairs | Useful for application secrets not directly tied to registry auth |
| `tls` | TLS certs and keys | For TLS bootstrapping and TLS-related use cases |

Reference: [Kubernetes Secret Types](https://kubernetes.io/docs/concepts/configuration/secret/#secret-types)

***

## 1) Inspect the existing Deployment and its pod template

List Deployments and inspect the `web` Deployment to see which image it is currently configured to use:

```bash theme={null}
kubectl get deploy
kubectl get deploy web -o yaml
```

Example (trimmed) Deployment pod template showing the current image:

```yaml theme={null}
spec:
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        imagePullPolicy: IfNotPresent
```

If no registry is specified in the image name (for example `nginx:alpine`), Kubernetes pulls the image from Docker Hub by default.

***

## 2) Update the Deployment to use an image from a private registry

Change the container image to point to your private registry. For this lab we’ll use `myprivateregistry.com:5000/nginx:alpine` as an example.

Edit the Deployment and update the image:

```bash theme={null}
kubectl edit deploy web
# change:
#   image: nginx:alpine
# to:
#   image: myprivateregistry.com:5000/nginx:alpine
```

After saving your edit, confirm the change:

```bash theme={null}
kubectl describe deploy web
```

Relevant excerpt:

```console theme={null}
Containers:
  nginx:
    Image:      myprivateregistry.com:5000/nginx:alpine
```

***

## 3) Pods fail image pull due to missing credentials

Because the registry is private, newly created Pods will fail to pull the image unless credentials are provided. Typical failure symptoms include `ImagePullBackOff` and error messages indicating unauthorized access.

Example error snippet:

```console theme={null}
Status: ImagePullBackOff
Events:
  Type    Reason          Age   From               Message
  ----    ------          ---   ----               -------
  Normal  Pulling         1m    kubelet            Pulling image "myprivateregistry.com:5000/nginx:alpine"
  Warning Failed          1m    kubelet            Failed to pull image "myprivateregistry.com:5000/nginx:alpine": rpc error: code = Unknown desc = unauthorized: authentication required
```

***

## 4) Create a `docker-registry` Secret with registry credentials

Create a Secret of type `docker-registry` that contains the credentials needed to access the private registry. Replace the placeholders with your actual registry server, username, password, and email:

```bash theme={null}
kubectl create secret docker-registry private-reg-cred \
  --docker-server=myprivateregistry.com:5000 \
  --docker-username=dock_user \
  --docker-password=dock_password \
  --docker-email=dock_user@myprivateregistry.com
```

Expected response:

```console theme={null}
secret/private-reg-cred created
```

This Secret stores the equivalent of a Docker `config.json` entry that Kubernetes can use to authenticate when pulling images.

***

## 5) Configure the Deployment to use the Secret via imagePullSecrets

Add an `imagePullSecrets` entry under the Deployment’s pod spec (`spec.template.spec`) that references the Secret name (`private-reg-cred`). This tells Kubernetes to use those credentials when pulling images for Pods created by the Deployment.

Kubernetes example of the pod field:

```yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: regcred
```

Edit your Deployment to include `imagePullSecrets`:

```bash theme={null}
kubectl edit deploy web
```

Modify the pod template portion to include the Secret reference:

```yaml theme={null}
spec:
  template:
    spec:
      imagePullSecrets:
      - name: private-reg-cred
      containers:
      - name: nginx
        image: myprivateregistry.com:5000/nginx:alpine
        imagePullPolicy: IfNotPresent
```

Save the edit. The Deployment controller will perform a rolling update to replace Pods with new ones that include the `imagePullSecrets` configuration.

Monitor rollout and pod status:

```bash theme={null}
kubectl describe deploy web
kubectl get pods -w
```

Example pod status during/after rolling update:

```console theme={null}
NAME                         READY   STATUS        RESTARTS   AGE
web-5f558bb687-dxthl         1/1     Running       0          28s
web-5f558bb687-qprgq         1/1     Running       0          30s
web-85fcf65896-rbsmq         0/1     Terminating   0          5m
```

You should see new Pods successfully transition to `Running` while older replica set Pods are scaled down/terminated. Kubernetes will use the credentials stored in the `docker-registry` Secret, allowing image pulls from your private registry to succeed.

<Callout icon="lightbulb" color="#1CB2FE">
  Note: If you do not specify a registry in the image name (for example, just `nginx:alpine`), Kubernetes pulls the image from [Docker Hub](https://hub.docker.com/) by default. Use `imagePullSecrets` in the pod spec to supply credentials for private registries.
</Callout>

## References and further reading

* Kubernetes: Specifying ImagePullSecrets on a Pod — [https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod)
* Kubernetes Secrets — [https://kubernetes.io/docs/concepts/configuration/secret/](https://kubernetes.io/docs/concepts/configuration/secret/)
* Docker Hub — [https://hub.docker.com/](https://hub.docker.com/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/77826599-d456-4cb5-8cbc-b713cc077b45/lesson/ebf3d1f0-d521-4cc0-9abf-2cba44df245e" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.