Skip to content
Back to Deployment

Kubernetes Deployment Patterns

Production K8s patterns: deployments, services, ingress, HPA, and rolling updates with zero downtime.

ContainersAdvanced

Why

Kubernetes orchestrates containerized apps at scale: auto-healing, auto-scaling, rolling updates, and service discovery. It is the industry standard for production container workloads across cloud providers.

Docker is used by 59% of professional developers per the Stack Overflow 2024 survey, and Kubernetes runs 60% of containerized workloads in production (CNCF 2024 survey). Container orchestration reduces deployment-related incidents by 35% through declarative rollouts.

When

Adopt Kubernetes when you have 10+ microservices, need multi-cloud portability, or require fine-grained scaling per service. Avoid for simple monoliths — Vercel/Cloudflare is simpler.

How

1. Package app — Docker image pushed to registry (ECR/GCR/Docker Hub) 2. Write Deployment — specify replicas, image, resources, probes 3. Write Service — expose pods via ClusterIP (internal) or LoadBalancer (external) 4. Configure Ingress — route HTTP traffic, TLS termination, path-based routing 5. Set HPA — HorizontalPodAutoscaler scales on CPU/memory or custom metrics 6. Rolling update — kubectl set image deployment/app app=myapp:v2 7. Rollback — kubectl rollout undo deployment/app 8. Monitor — Prometheus + Grafana for metrics, Loki for logs

Example

# deployment.yaml 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: myapp:v2.0 ports: [{ containerPort: 3000 }] resources: requests: { cpu: "100m", memory: "128Mi" } limits: { cpu: "500m", memory: "512Mi" } livenessProbe: httpGet: { path: /health, port: 3000 } initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: { path: /ready, port: 3000 } initialDelaySeconds: 5 periodSeconds: 10 --- # hpa.yaml — auto-scale 3-10 replicas on CPU apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: myapp-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: myapp minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: { type: Utilization, averageUtilization: 70 }

Common Problems

  • ⚠No resource limits — pods consume all node memory, causing OOMKilled evictions
  • ⚠Missing readiness probe — traffic routes to pods before they are ready, causing 502s
  • ⚠ImagePullPolicy: Always — slows pod startup, use IfNotPresent for tagged images
  • ⚠ConfigMap changes don't restart pods — use Reloader or hash suffix in deployment name

Best Practices

  • ✓Always set resource requests AND limits — prevents noisy neighbor and OOM issues
  • ✓Use liveness + readiness probes — liveness restarts dead pods, readiness controls traffic
  • ✓Tag images with semver or git SHA — never use :latest in production
  • ✓Use kustomize or Helm for environment overlays — avoid duplicating YAML per env

FAQ

Deployment vs StatefulSet — which should I use?

Deployment for stateless apps (web servers, APIs) — pods are interchangeable. StatefulSet for stateful apps (databases) — pods have stable identity and persistent volumes. Use StatefulSet only for ordered startup or stable storage.

Why does my pod keep getting OOMKilled?

The container exceeds its memory limit. Check kubectl describe pod for the limit, then raise it or fix the memory leak. Set requests close to actual usage (kubectl top pod) so the scheduler places pods correctly.

How do I roll back a bad deployment?

kubectl rollout undo deployment/<name> instantly reverts to the previous ReplicaSet. Check history with kubectl rollout history. Always set progressDeadlineSeconds so stuck rollouts auto-fail.

Why are my pods pending forever?

The cluster has no node with enough resources. Run kubectl describe pod <name> and look at Events — Insufficient cpu/memory or 0/3 nodes available. Scale up the node pool or lower resource requests.

Should I use Helm or raw manifests?

Helm for anything deployed to multiple environments (dev/staging/prod) — it templatizes values. Raw manifests for one-off configs. Don't hand-edit Helm-generated manifests; change the chart and re-render.