You have worked through all 12 articles in the Kubernetes series. Now it is time to go to production.

This checklist covers everything you need to verify before your application is ready for real traffic. Each item links back to the tutorial where it is covered in depth.

Going through this checklist before your first production deploy will save you from the most common production failures.


Reliability

Define resource requests and limits on every container

Without requests, the Kubernetes scheduler cannot place Pods correctly. Without limits, one runaway container can OOM-kill an entire node.

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "256Mi"

Status: Every container in every Deployment must have this.

Add readiness and liveness probes

Without probes, Kubernetes cannot tell if your app is ready or broken. Traffic goes to crashing Pods.

readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 20
  failureThreshold: 3
  • Readiness probe — controls when a Pod receives traffic. If it fails, the Pod is removed from the Service load balancer.
  • Liveness probe — controls when Kubernetes restarts a Pod. If it fails repeatedly, the Pod is restarted.

Run at least 2 replicas for every stateless service

A single replica means one crash = full outage. Always run at least 2.

spec:
  replicas: 2    # Never 1 for production

Set a rolling update strategy with zero downtime

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0    # Never remove a Pod before its replacement is ready
      maxSurge: 1

Add a Pod Disruption Budget

Prevent cluster operations (node drains, upgrades) from taking down too many Pods at once.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  minAvailable: 1          # At least 1 Pod must be running at all times
  selector:
    matchLabels:
      app: myapp

Spread Pods across nodes (anti-affinity)

If all 3 replicas are on the same node and that node fails, your app is down.

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: myapp
            topologyKey: kubernetes.io/hostname

Networking

Use Gateway API (not Ingress) for new projects

ingress-nginx moved to maintenance mode in March 2026. Use Gateway API for all new projects.

See Kubernetes Tutorial #6: Ingress and Gateway API for migration and setup.

Enable TLS on your Gateway

All external traffic should use HTTPS. Configure TLS on the Gateway level:

spec:
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: myapp-tls

Apply Network Policies (default deny)

All Pods can talk to all Pods by default. Lock this down before going live.

# Start with deny-all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

Then add explicit allow rules for each service.


Security

Run as non-root

securityContext:
  runAsNonRoot: true
  runAsUser: 1000

Read-only root filesystem

securityContext:
  readOnlyRootFilesystem: true

If your app needs to write files, mount a specific emptyDir volume for that path.

Drop all Linux capabilities

securityContext:
  capabilities:
    drop:
      - ALL

Disable privilege escalation

securityContext:
  allowPrivilegeEscalation: false

Enforce Pod Security Standards on namespaces

kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted

Disable auto-mount of service account tokens

spec:
  automountServiceAccountToken: false

Apply RBAC with least privilege

Create dedicated ServiceAccounts with minimal permissions for each component. See Kubernetes Tutorial #10: Security.

Use External Secrets Operator for secrets

Never commit plain Secret YAML to git. Use External Secrets Operator to sync from AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault.

Scan images before deploying

trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:1.0

Run this in CI before pushing to the registry. See Kubernetes Tutorial #9: CI/CD.


Storage

Use StatefulSets for databases

Databases need stable Pod names, ordered scaling, and unique storage per replica. Deployments do not provide this.

See Kubernetes Tutorial #5: Persistent Volumes.

Set reclaim policy to Retain for important data

kind: StorageClass
spec:
  reclaimPolicy: Retain

With Delete policy, removing a PVC deletes the data permanently.

Set up Velero for cluster backups

Velero backs up Kubernetes resources and PersistentVolume data.

helm install velero vmware-tanzu/velero \
  --namespace velero \
  --set configuration.backupStorageLocation.bucket=my-backup-bucket

Schedule nightly backups:

velero schedule create daily-backup --schedule="0 2 * * *"

Configuration

Use namespaces for isolation

Do not run everything in the default namespace. Create separate namespaces per environment:

kubectl create namespace production
kubectl create namespace staging
kubectl create namespace monitoring

Apply ResourceQuotas per namespace

Prevent one team or service from consuming all cluster resources:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    pods: "50"
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi

Use ConfigMaps and Secrets — never hardcode values

Application config should be injected at runtime, not baked into the image. See Kubernetes Tutorial #4: ConfigMaps and Secrets.


Observability

Install Prometheus and Grafana

helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring

Import the Kubernetes cluster dashboard (ID: 315) in Grafana immediately.

See Kubernetes Tutorial #8: Monitoring.

Set Prometheus retention limits

helm upgrade prometheus prometheus-community/kube-prometheus-stack \
  --set prometheus.prometheusSpec.retention=30d \
  --set prometheus.prometheusSpec.retentionSize=50GB

Create alerts for critical conditions

Minimum alerts to configure:

AlertCondition
Pod CrashLoopContainer restarts > 5 in 1 hour
Node NotReadyNode condition Ready == false
High error rateHTTP 5xx rate > 5%
Disk fullPV usage > 85%
OOMKilledContainer memory limit hit

Add application-level metrics

Expose a /metrics endpoint from your app. Add a ServiceMonitor so Prometheus scrapes it.


Autoscaling

Configure HPA for all stateless services

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

Use VPA to right-size resource requests

Start with updateMode: "Off" to collect recommendations, then tune your requests accordingly.

Install KEDA for event-driven scaling

If you have background workers or queue consumers, use KEDA to scale to zero when idle.

See Kubernetes Tutorial #11: Autoscaling.


CI/CD

Use commit SHA as the image tag

IMAGE_TAG=${{ github.sha }}

Never use latest in production. You need to know exactly which code is running.

Wait for rollout to complete in CI

kubectl rollout status deployment/myapp --timeout=5m

Configure automatic rollback on failure

if ! kubectl rollout status deployment/myapp --timeout=5m; then
  kubectl rollout undo deployment/myapp
  exit 1
fi

See Kubernetes Tutorial #9: CI/CD.


Kubernetes Version Management

Stay within N-2 supported versions

Kubernetes supports the 3 most recent minor versions. Running an older version means no security patches.

Check your version:

kubectl version

Test upgrades on staging first

Never upgrade production Kubernetes directly. Always test the upgrade on a staging cluster first.

The upgrade path is sequential: 1.33 → 1.34 → 1.35. You cannot skip versions.


Final Pre-Production Check

Run these commands before going live:

# Check all Pods are running
kubectl get pods -A | grep -v Running | grep -v Completed

# Check resource usage
kubectl top nodes
kubectl top pods -A

# Check no Pods are in Pending state
kubectl get pods -A | grep Pending

# Verify HPAs are working
kubectl get hpa -A

# Verify Prometheus is scraping your app
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
# Open http://localhost:9090/targets — your app should show as UP

# Check for security policy violations
kubectl get events -A | grep Warning

# Verify backups are configured
velero backup get

If all checks pass, you are ready.


Common Mistakes That Cause Production Incidents

Running databases on Kubernetes without StatefulSets, PVCs, and proper backup

A Deployment with no PVC will lose all database data on Pod restart. A StatefulSet with reclaimPolicy: Delete will lose data if someone deletes the PVC. Always use StatefulSets, Retain reclaim policy, and Velero backups.

No liveness/readiness probes

Kubernetes marks a Pod as ready as soon as the container starts. Without a readiness probe, the Pod receives traffic before it has finished starting up. Without a liveness probe, a stuck or deadlocked app will never restart.

Missing resource limits

One Pod using too much memory causes the node to run out. Kubernetes starts killing other Pods on the same node (OOMKilled). Always set limits.memory on every container.

Congratulations

You have completed the full Docker & Kubernetes Tutorial series.

You now know:

  • Docker fundamentals and production image building
  • Docker Compose for multi-container development
  • Kubernetes architecture and core objects
  • Persistent storage and stateful workloads
  • Gateway API for production routing
  • Helm for application packaging
  • Prometheus and Grafana for monitoring
  • GitHub Actions CI/CD pipeline
  • Security hardening at every layer
  • Autoscaling with HPA, VPA, and KEDA
  • What it takes to run Kubernetes in production