iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Path to Kubernetes

Docker + Kubernetes: how images run on K8s. Pull, secrets, pod spec, troubleshooting Docker-specific issues.

Docker — Docker + Kubernetes

EXAMPLE
# ===== The relationship =====
# Kubernetes runs containers built from Docker (or OCI) images.
# K8s no longer uses Docker as the runtime (dropped containerd as default in 1.24+),
# but Docker images still work because they follow the OCI spec.

# ===== Build image, push, deploy =====
# 1. Build with Docker:
docker build -t ghcr.io/me/shop:v1 .

# 2. Push to registry:
docker push ghcr.io/me/shop:v1

# 3. Reference in K8s manifest:
apiVersion: apps/v1
kind: Deployment
metadata: { name: shop }
spec:
  replicas: 3
  selector: { matchLabels: { app: shop } }
  template:
    metadata: { labels: { app: shop } }
    spec:
      containers:
        - name: shop
          image: ghcr.io/me/shop:v1     # the Docker-built image
          ports: [{ containerPort: 3000 }]

# ===== Private registry credentials =====
# Create a docker-registry secret:
kubectl create secret docker-registry ghcr-creds \
  --docker-server=ghcr.io \
  --docker-username=USERNAME \
  --docker-password=TOKEN \
  --namespace=apps

# Reference in pod spec:
spec:
  imagePullSecrets:
    - name: ghcr-creds
  containers: [...]

# ===== Image pull policy =====
imagePullPolicy: Always         # for moving tags (latest, dev)
imagePullPolicy: IfNotPresent   # for immutable tags (digest, semver)
imagePullPolicy: Never          # for locally-loaded images (kind / minikube)

# ===== Common issues =====
# 1. ImagePullBackOff
#    - Wrong image name / tag
#    - Missing imagePullSecrets for private registry
#    - Registry unreachable from cluster

# 2. CrashLoopBackOff with 'exec format error'
#    - Image built for wrong architecture (e.g. arm64 image on amd64 nodes)
#    - Solution: buildx with --platform linux/amd64,linux/arm64

# 3. CrashLoopBackOff with exit code immediately
#    - CMD wrong; check 'kubectl logs --previous'
#    - Wrong entrypoint, missing env vars, file permissions

# 4. Slow startup -> liveness probe failing
#    - Add startup probe with initialDelaySeconds
#    - Increase failureThreshold

# ===== Multi-arch builds =====
docker buildx create --use --name multi
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/me/shop:v1 --push .

# Now the image works on both amd64 nodes (most cloud K8s) and arm64 nodes (Graviton, Apple Silicon).

# ===== Image scanning =====
# In CI:
trivy image ghcr.io/me/shop:v1 --severity HIGH,CRITICAL --exit-code 1

# In cluster (admission controller):
# Kyverno / Falco / Connaisseur can verify signatures + scan results before allowing pods.

# ===== Local dev =====
# kind: load image into the cluster without registry push
kind load docker-image ghcr.io/me/shop:dev --name dev

# minikube:
eval $(minikube docker-env)
docker build -t shop:dev .

# ===== Patterns =====
# - Build with Docker; pull from registry in K8s
# - imagePullSecrets for private registries
# - Pin by digest in production (image@sha256:...)
# - Multi-arch builds for cross-platform clusters
# - Scan in CI; sign images; verify at admission

# ===== Pitfalls =====
# - Image built locally + not pushed -> ImagePullBackOff
# - imagePullPolicy: Always wasting bandwidth on immutable tags
# - 'latest' tag in prod -> non-deterministic deploys
# - Wrong architecture -> 'exec format error'

Why it matters

Docker images run on K8s via the registry. Build with buildx for multi-arch, push to a registry, reference in pod spec, set imagePullSecrets for private. Pin by digest in prod, scan in CI, sign for admission. ImagePullBackOff and CrashLoopBackOff are the daily diagnoses.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Once you have many containers + replicas + rolling deploys, K8s starts to earn its keep.
# Start with managed K8s (EKS, GKE, AKS).
Try it Yourself »

Discussion

Loading…