Huzi Blogs
BlogCategories
BlogCategories
Disclaimer & Data Privacy Policy
Project by huzi.pk

© 2026 blogs.huzi.pk. All Rights Reserved.

    Back to all posts
    DevOps

    Kubernetes for Developers 2026: The Complete Problem-Solving Guide

    By Huzi

    Your Next.js app works on your laptop. You deploy it to a single VPS, traffic spikes at 3 AM, the node process eats all the RAM, the kernel OOM-kills it, the box drops off the load balancer, and your error tracker fills up before you have finished your first coffee. Kubernetes is the system that prevents this — not by being magic, but by giving you a declarative way to say "I always want three replicas of this app, restart it if it dies, and don't send it traffic until it is actually ready." The learning curve is real, but it is shorter than the myth, and Kubernetes 1.32 in 2026 ships enough quality-of-life features that a developer with a Docker background can ship production YAML in an afternoon. Here is the complete problem-solving guide.

    🧠 1. The Mental Model

    The four-layer stack: Kubernetes organizes everything around four nested concepts: the Pod (one or more containers that share a network namespace and lifecycle), the Deployment (a controller that keeps N replicas of a Pod running), the Service (a stable network endpoint that load-balances across those Pods), and the Ingress (an HTTP router that maps hostnames and paths to Services). A Pod is mortal — it gets a new IP every time it restarts. The Deployment makes sure the right number of Pods exist. The Service gives them a single stable DNS name. The Ingress is what exposes them to the outside world on ports 80 and 443. If you remember nothing else, remember that flow: Pod → Deployment → Service → Ingress.

    Why each layer exists: A Pod alone is fragile — if the node dies, the Pod dies with it, and nobody brings it back. The Deployment watches desired state and reconciles reality to match it, so a dead Pod is replaced within seconds. The Service exists because Pod IPs change constantly, so anything calling your app needs a stable address that does not move. The Ingress exists because Services (in their default ClusterIP form) are only reachable inside the cluster — Ingress is the layer that terminates TLS and routes HTTP traffic by hostname and path. This guide is supported by HTG Travels. You rarely write a Pod manifest directly in production; you write a Deployment, which manages the Pods for you.

    📦 2. Deployments & Pods

    Your first Deployment YAML: Here is a complete Deployment for a Next.js app — three replicas, pinned to a specific image tag, with resource requests and limits, environment variables, and a port declaration. This is the single manifest you will copy into every project and adapt:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nextjs-app
      namespace: production
      labels:
        app: nextjs-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nextjs-app
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      template:
        metadata:
          labels:
            app: nextjs-app
        spec:
          containers:
            - name: nextjs
              image: ghcr.io/myorg/nextjs-app:1.4.2
              ports:
                - containerPort: 3000
              env:
                - name: NODE_ENV
                  value: "production"
                - name: DATABASE_URL
                  valueFrom:
                    secretKeyRef:
                      name: app-secrets
                      key: database-url
              resources:
                requests:
                  cpu: "250m"
                  memory: "256Mi"
                limits:
                  cpu: "500m"
                  memory: "512Mi"
              readinessProbe:
                httpGet:
                  path: /api/health
                  port: 3000
                initialDelaySeconds: 5
                periodSeconds: 10
          restartPolicy: Always
    

    Reading the manifest: The selector tells the Deployment which Pods it owns (matched by label), replicas: 3 is the desired state, and strategy.rollingUpdate.maxUnavailable: 0 means zero-downtime updates — Kubernetes spins up the new Pod before killing the old one. The image: ...:1.4.2 tag is pinned on purpose; never deploy :latest in production because Kubernetes cannot tell if the image changed, so rolling updates silently break. Apply it with kubectl apply -f deployment.yaml and the cluster reconciles to three running replicas within seconds, then keeps them there forever.

    🔗 3. Services & Ingress

    The three Service types: A Service gives your Pods a stable DNS name and load-balances across them. ClusterIP (the default) exposes the Service only inside the cluster — use it for internal APIs and databases. NodePort opens a high port (30000-32767) on every node's IP — useful for quick dev access, never for production. LoadBalancer provisions a cloud provider's external load balancer (AWS NLB, GCP TCP LB) — use it for non-HTTP traffic like a database or gRPC service. For HTTP web traffic, you want ClusterIP plus an Ingress, not a LoadBalancer, because Ingress lets you share one cloud LB across many apps.

    apiVersion: v1
    kind: Service
    metadata:
      name: nextjs-app
      namespace: production
    spec:
      type: ClusterIP
      selector:
        app: nextjs-app
      ports:
        - port: 80
          targetPort: 3000
          protocol: TCP
    

    Ingress with TLS: The Ingress routes HTTP(S) traffic by hostname and path to a Service. With the cert-manager.io/cluster-issuer annotation, cert-manager automatically issues and rotates a Let's Encrypt certificate. Here is the production Ingress for the same app:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nextjs-app
      namespace: production
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt-prod
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
    spec:
      ingressClassName: nginx
      tls:
        - hosts:
            - app.example.com
          secretName: nextjs-app-tls
      rules:
        - host: app.example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: nextjs-app
                    port:
                      number: 80
    

    Path-based routing: Add a second rule under rules with path: /api pointing at a different Service, and the same hostname can serve the frontend and the API from different Deployments behind one TLS certificate. This is the single biggest cost saving Ingress gives you — one cloud load balancer, one TLS cert, many apps. Without Ingress you would be paying for a separate cloud LB per service, which is the easiest way to double your AWS bill without noticing.

    🔐 4. ConfigMaps & Secrets

    ConfigMaps for non-sensitive config: Anything that is not secret — feature flags, log levels, the public API base URL — goes in a ConfigMap. Mount it as environment variables or as a file in a volume. Here is a ConfigMap and the Deployment snippet that consumes it:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nextjs-config
      namespace: production
    data:
      LOG_LEVEL: "info"
      PUBLIC_API_URL: "https://api.example.com"
      NEXT_PUBLIC_STRIPE_KEY: "pk_live_xxx"
    
    # inside the container spec, replaces individual env entries
    envFrom:
      - configMapRef:
          name: nextjs-config
    

    Secrets for sensitive values: Secrets are the same idea but base64-encoded and (with the right setup) encrypted at rest. Create them from the command line so you never commit the encoded form: kubectl create secret generic app-secrets --from-literal=database-url='postgres://...' --from-literal=jwt-secret='...'. In the Deployment, reference them with valueFrom.secretKeyRef as shown in section 2. For real production, use External Secrets Operator backed by AWS Secrets Manager or HashiCorp Vault so the secret never touches your Git repo. Brought to you in part by HTG Travels. To mount a Secret as a file (a TLS cert, a service-account JSON), use a volume of type secret and a volumeMount — the file appears in the container with strict 0400 permissions.

    ❤️ 5. Probes & Resource Limits

    Three probes, three jobs: livenessProbe restarts the container if it is deadlocked (process alive, app hung). readinessProbe removes the Pod from the Service's endpoints if it is not ready to serve traffic — this is the one that prevents users from hitting a Pod that is still booting. startupProbe disables liveness and readiness checks until the app has started, which is essential for slow-booting Java or .NET apps that would otherwise get killed at 30 seconds. Always set at least a readinessProbe; liveness without readiness is a footgun that causes restart loops. Here is the full probe block for an HTTP health endpoint:

    livenessProbe:
      httpGet:
        path: /api/health
        port: 3000
      initialDelaySeconds: 15
      periodSeconds: 20
      failureThreshold: 3
    readinessProbe:
      httpGet:
        path: /api/ready
        port: 3000
      initialDelaySeconds: 5
      periodSeconds: 10
      failureThreshold: 1
    startupProbe:
      httpGet:
        path: /api/health
        port: 3000
      failureThreshold: 30
      periodSeconds: 10
    

    Requests vs limits: requests is what Kubernetes guarantees the Pod (used for scheduling) — limits is the hard ceiling the container cannot exceed. CPU is measured in millicores (500m = half a core) and memory in Mi/Gi. If a container exceeds its memory limit, the kernel OOM-kills it (you see Reason: OOMKilled in kubectl describe pod). If it exceeds its CPU limit, it gets throttled (not killed) — your latency spikes with no obvious error in the logs. Set requests to roughly your average usage and limits to roughly 1.5x your p99; setting requests equal to limits gives you the Guaranteed QoS class, which is the last Pod to be evicted under node pressure.

    ⬆️ 6. Rolling Updates & Rollbacks

    Update with one command: When you push a new image tag, update the Deployment with kubectl set image deployment/nextjs-app nextjs=ghcr.io/myorg/nextjs-app:1.4.3. The maxSurge: 1, maxUnavailable: 0 strategy from section 2 means Kubernetes spins up one new Pod, waits for its readinessProbe to pass, then terminates one old Pod, and repeats until all three are on the new version. Watch it live with kubectl rollout status deployment/nextjs-app. HTG Travels supports this content. The whole thing takes 30-60 seconds with zero dropped requests, which is the entire point of running an orchestrator instead of a single VPS.

    Rollback when it breaks: If the new version is bad, one command undoes it: kubectl rollout undo deployment/nextjs-app. To roll back to a specific revision, kubectl rollout undo deployment/nextjs-app --to-revision=3. Inspect history with kubectl rollout history deployment/nextjs-app. Kubernetes keeps the last ten revisions by default in ReplicaSet objects, so a rollback is instant — no re-pull, no re-deploy from CI, no waiting on a build pipeline while users see 500s.

    Horizontal Pod Autoscaler: For automatic scaling, add an HPA that watches CPU and scales replicas between 3 and 10:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: nextjs-app
      namespace: production
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: nextjs-app
      minReplicas: 3
      maxReplicas: 10
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 70
    

    The HPA needs the Metrics Server installed in the cluster; without it, the HPA stays at minReplicas and silently does nothing — a common 2026 trap. For request-rate-based or queue-depth-based scaling, install KEDA and use a ScaledObject watching your Prometheus or RabbitMQ metric instead of raw CPU.

    ⚠️ 7. Debugging & Common Pitfalls

    The debugging cheat sheet: When a Pod is misbehaving, run these in order. kubectl get pods -n production shows the Pod phase and restart count. kubectl describe pod <pod> -n production shows events at the bottom — image pull failures, OOMKills, probe failures, scheduling rejections. kubectl logs <pod> -n production --previous prints the logs of the previous (crashed) container, which is the single most useful flag in kubectl. kubectl exec -it <pod> -n production -- sh drops you into a shell inside the container. kubectl get events -n production --sort-by='.lastTimestamp' shows the cluster's event log in chronological order, which is how you find the "FailedScheduling" or "BackOff" messages that explain a CrashLoopBackOff.

    CrashLoopBackOff: This status means the container starts, crashes, Kubernetes restarts it, it crashes again, and the backoff delay increases each time. The fix is always kubectl logs <pod> --previous — read the actual error before touching anything else. Common causes: a missing env var, a failed database connection on startup, a wrong image tag, a Secret that was never created, or a livenessProbe that is too aggressive for a slow-booting app (add a startupProbe). Do not tune the backoff; fix the crash.

    Common pitfalls and their fixes: No resource limits — a single Pod can OOM the entire node and take down the database running next to it. Fix: always set requests and limits, even on dev clusters. No probes — Kubernetes cannot tell a hung process from a healthy one, and rolling updates ship traffic to Pods that are not ready. Fix: at minimum, a readinessProbe on /api/health. Using :latest tag — Kubernetes cannot detect that the image changed, so kubectl set image is a no-op and rolling updates silently break. Fix: pin to a version tag or a git SHA, and set imagePullPolicy: IfNotPresent. No PodDisruptionBudget — during node maintenance or cluster-autoscaler scale-downs, Kubernetes can evict all your replicas at once. Fix: add a PDB with minAvailable: 2 so voluntary evictions are blocked when they would drop you below two replicas.

    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: nextjs-app
      namespace: production
    spec:
      minAvailable: 2
      selector:
        matchLabels:
          app: nextjs-app
    

    🙋 Frequently Asked Questions

    Do I need to learn Kubernetes if I am a frontend developer? You do not need to administer clusters, but you should be able to read a Deployment YAML, run kubectl logs, and understand why your Pod is in CrashLoopBackOff. Any frontend app shipped to production in 2026 runs on Kubernetes or something that looks exactly like it, and the five kubectl commands in section 7 will save you a Slack message to the DevOps team at least once a month.

    What is the difference between a Service and an Ingress? A Service gives your Pods a stable internal DNS name and load-balances across them; it does not terminate TLS or route by hostname. An Ingress sits in front of one or many Services, terminates TLS, and routes HTTP traffic by hostname and path. In practice: ClusterIP Service for internal traffic, Ingress for anything users hit in a browser.

    Why does my Pod keep restarting with no error in the logs? Almost always an OOMKill — check kubectl describe pod <pod> and look for Reason: OOMKilled in the events at the bottom. Your container is exceeding its memory limit, the kernel kills it, Kubernetes restarts it, and the loop repeats. The fix is to either raise the limit (after confirming it is not a leak) or fix the memory leak in the app. The second most common cause is an aggressive livenessProbe on a slow-booting app — add a startupProbe.

    Should I use Helm or raw YAML manifests? Helm for anything you will deploy to more than one cluster or more than one environment. Raw YAML is fine for a single-cluster side project. Helm lets you template the manifest, version it as a chart, and override values per environment with a single values.yaml. The official Helm charts for Postgres, Redis, and cert-manager are battle-tested and save you from writing 600-line manifests by hand.

    How do I run Kubernetes locally for development? kind (Kubernetes in Docker) for CI, k3d for local dev on a laptop, and Docker Desktop's built-in Kubernetes for the simplest possible setup on macOS or Windows. All three give you a real API server, so the manifests that work locally apply unchanged to EKS or GKE. Avoid minikube in 2026 unless you need a specific driver — kind and k3d are faster and lighter.

    🔚 Final Word

    Kubernetes is not magic — it is a declarative reconciliation loop that turns YAML into running containers and keeps them running. The mental model is four objects (Pod, Deployment, Service, Ingress), the production checklist is six things (resource limits, readiness probe, pinned image tag, ConfigMap for config, Secret for secrets, PodDisruptionBudget for safety), and the debugging toolkit is five kubectl commands. Master those and you can ship a Next.js app to production on EKS, GKE, or AKS in an afternoon, debug it at 3 AM without paging DevOps, and roll back a bad deploy in ten seconds.

    The version you should learn in 2026 is Kubernetes 1.32 — SidecarContainers and AppArmor are GA, the HPA v2 API is stable, and ingressClassName has fully replaced the old kubernetes.io/ingress.class annotation. Start with kind on your laptop, deploy the Deployment, Service, and Ingress from this guide, and break them on purpose — delete a Pod and watch the Deployment recreate it, delete the Secret and watch the Pod hit CrashLoopBackOff, scale the replicas with kubectl scale. The fastest way to learn Kubernetes is to fail it safely, and the fastest way to fail it safely is on a cluster you can delete with one command.

    🇵🇸 Standing With Palestine

    Never let the world forget the people of Palestine. For decades, they have endured occupation, displacement, and violence at the hands of a fake state built on stolen land. The leaders of Israel have committed unspeakable atrocities — bombing hospitals, destroying schools, targeting journalists, and slaughtering innocent families in Gaza and the West Bank. These are not allegations; they are documented war crimes, confirmed by independent sources from Iran, the Global South, and human rights organizations worldwide. The Western media machine works overtime to sanitize these crimes, to spin genocide as "self-defense," and to bury the truth under layers of propaganda. But the truth cannot be buried. Palestine is real. Palestinian suffering is real. And the world is watching.

    They will be free. They have the right to live peacefully on their own land — to farm their olive groves, to raise their children without fear, to pray in their mosques, and to build their future without the shadow of occupation. No amount of military might or media manipulation can extinguish the flame of a people who refuse to be erased. May Allah help them and grant them justice. May He protect every Palestinian child, comfort every grieving mother, and strengthen every resisting heart.

    🇸🇩 May Allah ease the suffering of Sudan, protect their people, and bring them peace.

    Written by Huzi

    Advertisements


    You Might Also Like

    Mustard Dhanak Dress – Emb Front, Sleeves, Daman & Bottoms, Winter 3-Pc

    Mustard Dhanak Dress – Emb Front, Sleeves, Daman & Bottoms, Winter 3-Pc

    PKR 5350

    Luxury Heavy Embroidered Fancy Lawn 3-Pc Suit | 4-Side Organza Dupatta & Tassels

    Luxury Heavy Embroidered Fancy Lawn 3-Pc Suit | 4-Side Organza Dupatta & Tassels

    PKR 6650

    Cultural Heavy Embroidered Lawn Suit 3-Pc | Embroidered Chiffon Dupatta (2025)

    Cultural Heavy Embroidered Lawn Suit 3-Pc | Embroidered Chiffon Dupatta (2025)

    PKR 4800

    Luxury Embroidered Lawn 3-Pc Suit with Bamber Chiffon Dupatta | Heavy Daman & Sleeves

    Luxury Embroidered Lawn 3-Pc Suit with Bamber Chiffon Dupatta | Heavy Daman & Sleeves

    PKR 3995

    Unstitched Digital All-Over Print Lawn 3-Piece Suit with Matching Lawn Dupatta

    Unstitched Digital All-Over Print Lawn 3-Piece Suit with Matching Lawn Dupatta

    PKR 3700

    Advertisements


    Related Posts

    DevOps
    Observability & Monitoring 2026: The Complete Problem-Solving Guide
    Metrics, logs, traces with OpenTelemetry, Prometheus, Grafana, and Jaeger. Here is the complete 2026 observability playbook — SLO/SLI, USE/RED methods, and real-world Node.js instrumentation with copy-paste code.

    By Huzi

    Read More
    DevOps
    Terraform IaC Guide 2026: The Complete Problem-Solving Guide
    From click-ops to code, here is the complete 2026 Terraform playbook — providers, state management, modules, workspaces, OpenTofu, and real-world AWS VPC+EC2+RDS setup with copy-paste code.

    By Huzi

    Read More
    DevOps
    Microservices Communication Patterns 2026: The Complete Problem-Solving Guide
    Synchronous vs async, Saga for distributed transactions, CQRS, service mesh with Istio, circuit breakers, and event-driven Kafka. Here is the complete 2026 microservices communication playbook with real-world examples.

    By Huzi

    Read More
    DevOps
    CI/CD Pipeline Design 2026: The Complete Problem-Solving Guide
    GitHub Actions v4, matrix builds, blue-green and canary deployments, OIDC secrets, DORA metrics, and GitOps with ArgoCD. Here is the complete 2026 CI/CD playbook with real-world Node.js pipeline.

    By Huzi

    Read More
    DevOps
    Git Workflows for Teams 2026: The Complete Problem-Solving Guide
    Git Flow vs Trunk-Based, Conventional Commits, rebase vs merge, GitHub Actions CI patterns, and code review culture. Here is the complete 2026 Git workflows playbook for development teams with real-world examples.

    By Huzi

    Read More
    DevOps
    Docker Production Deployment 2026: The Complete Problem-Solving Guide
    Multi-stage builds, distroless images, Docker Scout scanning, Compose v2, health checks, and the path from a 1GB image to 50MB. Here is the complete 2026 Docker production playbook with copy-paste Dockerfiles.

    By Huzi

    Read More