AdvancedLesson 10 of 16

☸️ Docker for Kubernetes and AKS

Understand how Docker images become Kubernetes workloads — image requirements for K8s/AKS, Container Runtime Interface, pull secrets, and image best practices that prevent production issues.

🧒 Simple Explanation (ELI5)

Kubernetes is the airport control tower — it decides when, where, and how many times your planes (containers) fly. Docker is the plane manufacturer — it builds the aircraft (images) according to spec. Kubernetes does not care how you built the image, it just needs a compliant container image it can pull from a registry and run.

💡
AKS + ACR integration

AKS clusters can be directly attached to Azure Container Registry using managed identities — no pull secrets needed. Run: az aks update --attach-acr myacr. This grants the AKS kubelet managed identity AcrPull role on the registry.

🔧 Docker Image Requirements for K8s

Docker Image to K8s Pod Flow
Docker Build
image + Dockerfile
push
ACR
registry
pull (kubelet)
K8s Pod
container runtime (containerd)
managed by
AKS
Deployment / ReplicaSet

💻 Key Docker Practices for K8s

dockerfile
# K8s-ready Dockerfile checklist: # 1. Run as non-root (K8s PodSecurityStandard: restricted) RUN addgroup -S app && adduser -S app -G app USER app # 2. No hard-coded ports (use env vars) ENV PORT=8080 EXPOSE 8080 # 3. Minimal image size — smaller = faster pulls on every node FROM node:18-alpine # alpine saves ~200MB vs node:18 # 4. Stateless — no local data that matters # Store data in volumes/PVCs, not container filesystem # 5. Handle SIGTERM gracefully (K8s sends SIGTERM on pod eviction) # Node.js example: # process.on('SIGTERM', () => { server.close(() => process.exit(0)) }) # 6. Health check endpoints (K8s probes call these) # GET /healthz -> 200 OK (liveness) # GET /ready -> 200/503 (readiness)
yaml
# Kubernetes Deployment referencing ACR image apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myacr.azurecr.io/myapp:1.2.3 # always use specific tag ports: - containerPort: 8080 resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 15 readinessProbe: httpGet: path: /ready port: 8080
bash
# Attach ACR to AKS (no pull secrets needed) az aks update \ --name myaks \ --resource-group myRG \ --attach-acr myacr # Manually create an imagePullSecret (when not using managed identity) kubectl create secret docker-registry acr-secret \ --docker-server=myacr.azurecr.io \ --docker-username=$SP_ID \ --docker-password=$SP_PASSWORD \ --namespace default

🐛 Debugging Scenario

Problem: Pod is in ImagePullBackOff state and cannot start.

bash
# Diagnose kubectl describe pod <pod-name> # check Events section at the bottom # Common error: "unauthorized" or "not found" # Fix 1: re-attach ACR to AKS az aks update --attach-acr myacr --name myaks --resource-group myRG # Fix 2: verify image exists in registry az acr repository show-tags --name myacr --repository myapp # Fix 3: verify the full image path including registry hostname and tag kubectl get pod <pod> -o yaml | grep image # Fix 4: for private registries without managed identity, use imagePullSecrets # See secret creation command above

🎯 Interview Questions

What container runtime does AKS use and why does it matter?

AKS uses containerd (since Kubernetes 1.19). containerd is the Container Runtime Interface (CRI) implementation — it pulls images from registries and runs OCI-compliant containers. Docker-built images are OCI-compliant and run fine on containerd. The key implication: AKS nodes do not have the Docker daemon — docker ps commands on nodes will not work. Use crictl ps for container inspection on nodes.

What is an imagePullSecret and when do you need one?

An imagePullSecret is a Kubernetes secret containing registry credentials used by the kubelet to authenticate when pulling private images. You need one when AKS cannot authenticate to the registry automatically. With ACR + AKS using --attach-acr, the kubelet uses managed identity for AcrPull automatically — no imagePullSecrets needed. For other private registries (Docker Hub private, GCR, etc.) you must create the secret manually.

Scenario: Your container works fine with docker run but crashes in K8s. What do you check?

1. Security context: K8s may enforce non-root. Check runAsNonRoot: true in the pod spec. 2. Read-only filesystem: K8s pods sometimes have readOnlyRootFilesystem — your app must not write to the container filesystem. 3. Resource limits: K8s applies strict CPU/memory limits; OOMKilled is common. 4. Health probes: liveness probe may be too aggressive and killing the container before it is ready. 5. Environment variables: Kubernetes does not share your local env — check all required vars are set via ConfigMaps/Secrets.

📋 Summary