Skip to content

6.14 Image Security

Abstract

Container images are the foundation of Kubernetes workloads. Securing images is critical for preventing malicious code, supply‑chain attacks, and unauthorized access to private registries.


Image Naming Basics

A container image follows this structure:

registry/user-or-org/repository:tag

Example:

docker.io/library/nginx
Component Description
Registry Where the image is stored (Docker Hub, ECR, GCR, ACR, etc.)
User/Account Organization or account that owns the image
Repository The application image
Tag Version identifier

Note

If the registry or user is not specified, Kubernetes assumes:

  • Registry → docker.io
  • User → library

Example interpreted path:

nginx → docker.io/library/nginx

Public vs Private Registries

Public Registry

Public images are accessible to anyone.

Examples:

  • Docker Hub (docker.io)
  • Google Container Registry (gcr.io)

Example:

gcr.io/kubernetes-e2e-test-images/dnsutils

Warning

Public images may contain vulnerabilities or malicious code if not verified.


Private Registry

Organizations typically store internal images in private registries.

Common solutions:

  • AWS ECR
  • Azure ACR
  • Google Artifact Registry
  • Private Docker Registry

Example private image:

private-registry.io/apps/internal-app

Authenticating to Private Registries

To allow Kubernetes to pull private images, credentials must be stored in a Secret.

Create Docker Registry Secret

kubectl create secret docker-registry regcred \
  --docker-server=private-registry.io \
  --docker-username=registry-user \
  --docker-password=registry-password \
  --docker-email=user@company.com

Note

Kubernetes stores registry credentials securely inside a Secret object.


Using Private Images in Pods

Add the imagePullSecrets field inside the Pod spec.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: private-registry.io/apps/internal-app
  imagePullSecrets:
  - name: regcred

Tip

The Kubelet uses the secret to authenticate and pull the image from the registry.


Production Image Security Best Practices

Production Best Practices

  • Use private registries for internal workloads
  • Always pin image versions using tags or digests
  • Enable image scanning for vulnerabilities
  • Use minimal base images (Alpine, Distroless)
  • Enable image signing and verification (Cosign/Sigstore)
  • Restrict registry access using RBAC and IAM policies
  • Regularly rotate registry credentials

Image Tagging Strategy

Example

Good practice:

nginx:1.25.3
nginx@sha256:abcd...

Avoid:

nginx:latest

Danger

Using latest can break production deployments because the image may change unexpectedly.


Do's and Don'ts

Do

  • Use trusted base images
  • Scan images using tools like:
  • Trivy
  • Clair
  • Anchore
  • Store images in private registries
  • Use image digests for immutability

Don't

  • Don't deploy unverified public images
  • Don't store credentials in plain YAML
  • Don't use latest tag in production
  • Don't allow unrestricted image pulls

Image Pull Security Flow

  1. Pod is scheduled on a node
  2. Kubelet checks image location
  3. If private registry → credentials required
  4. Kubelet reads imagePullSecrets
  5. Registry authentication occurs
  6. Image is pulled securely
  7. Container starts

Quick Production Checklist

Before deploying images

  • Is the image scanned?
  • Is the registry private?
  • Are credentials stored in Kubernetes Secrets?
  • Is the tag immutable?
  • Is the image signed?

Summary

Quote

  • Container images are stored in registries
  • Public images are accessible by everyone
  • Private images require authentication
  • Kubernetes uses Secrets + imagePullSecrets to access private registries
  • Production environments must enforce image security policies