← Back to Articles
Kubernetes Microservices Architecture DevOps Engineering Container Orchestration Cloud Native .NET Core

Kubernetes Microservices Orchestration: A Production Guide to Deployments, Scaling, and Resilience

Moving from VMs to Kubernetes is complex. This guide covers the practical reality of orchestrating microservices: managing Deployments, configuring Services, implementing autoscaling, and avoiding common production pitfalls that crash clusters.

July 2026
18 min read
Written by Engineering Team

Introduction: The Shift from Monoliths to Orchestrated Containers

Running microservices on virtual machines works fine for three or four services. But when you hit twenty? You start drowning in SSH sessions, manual restarts, and configuration drift. I’ve seen teams spend more time fixing broken deployments than writing new features.

Kubernetes (K8s) solves this by treating your infrastructure like software. It doesn’t just "run" containers; it actively maintains the desired state of your application. If a node dies, K8s reschedules the pod. If traffic spikes, it scales up. This guide isn’t just about definitions—it’s about how to actually run this in production without losing your mind.

Kubernetes orchestrating multiple microservices across nodes
Kubernetes acts as the control plane, ensuring your actual cluster state matches your desired configuration.

Core Concepts: How K8s Actually Manages State

Before diving into YAML, understand the hierarchy. Kubernetes is declarative. You don’t tell it "start this container." You tell it "I want 3 replicas of this image running," and the Control Plane figures out how to make that happen.

  • Pods: The smallest deployable unit. Rarely created directly.

  • Deployments: The manager. Handles updates, rollbacks, and scaling.

  • Services: The network abstraction. Gives Pods a stable IP/DNS.

  • Ingress: The front door. Routes external HTTP traffic to internal Services.

1. Deployments: Beyond Basic Replicas

A Deployment ensures that a specified number of Pod replicas are running at any given time. But in production, you need to care about how they update.

production-deployment.yaml
yaml
              apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-api
  labels:
    app: orders-api
    tier: backend
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1       # Only create 1 extra pod during update
      maxUnavailable: 0 # Never drop below 3 running pods (Zero Downtime)
  selector:
    matchLabels:
      app: orders-api
  template:
    metadata:
      labels:
        app: orders-api
    spec:
      containers:
      - name: api
        image: company/orders-api:v1.2.4 # NEVER use 'latest' in production
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

            

Pro Tip: Always set resource requests and limits. Without them, a single memory-leaking pod can starve the entire node, causing a cascade failure across unrelated services.

2. Service Discovery & Networking

Pods are ephemeral—they die and get new IPs constantly. Hardcoding IPs is a recipe for disaster. Kubernetes Services provide a stable virtual IP and DNS name.

Service Type Use Case Risk Level
ClusterIP Internal service-to-service communication Low
NodePort Debugging/Testing only High (Security Risk)
LoadBalancer Exposing to internet via Cloud Provider Medium
ExternalName Mapping to external DBs/APIs Low

3. Ingress: The Traffic Controller

Ingress is not a Service; it’s a set of rules. Think of it as a reverse proxy (like Nginx) managed by K8s. It handles SSL termination and path-based routing.

ingress-rules.yaml
yaml
              apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod" # Auto-manage SSL
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: orders-api
            port:
              number: 80
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80

            

4. Configuration & Secrets Management

Never bake configuration into your Docker image. Use ConfigMaps for non-sensitive data (URLs, feature flags) and Secrets for passwords/keys. For production, consider integrating with HashiCorp Vault or AWS Secrets Manager rather than relying solely on K8s native secrets, which are base64 encoded, not encrypted by default.

5. Health Probes: Preventing "Zombie" Pods

Without probes, K8s thinks your app is healthy even if it’s deadlocked. You need two types:

  • Liveness Probe: "Are you alive?" If no, restart the container.

  • Readiness Probe: "Can you take traffic?" If no, remove from Service endpoints.

  • Startup Probe: "Are you still booting?" Prevents liveness checks from killing slow-starting apps.

probes.yaml
yaml
              livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

            

6. Autoscaling: Handling Traffic Spikes

Horizontal Pod Autoscaler (HPA) adjusts replica count based on metrics. While CPU/Memory are standard, for web APIs, I recommend scaling on Requests Per Second (RPS) or latency using Custom Metrics Adapter, as CPU usage often lags behind traffic spikes.

7. Observability: Seeing Inside the Black Box

You cannot manage what you cannot see. A production cluster needs the "Three Pillars":

  • Metrics: Prometheus + Grafana (CPU, Memory, Request Rate).

  • Logging: ELK Stack or Loki (Centralized log aggregation).

  • Tracing: Jaeger or OpenTelemetry (Tracking requests across microservices).

Common Production Mistakes to Avoid

  • Using latest tag: You lose reproducibility and rollback ability.

  • Ignoring Resource Limits: One bad app kills the node.

  • Single Replica Deployments: No high availability.

  • Storing State in Pods: Pods are ephemeral; use PVCs or external DBs.

  • Skipping Readiness Probes: Users get 502 errors during deployments.

"Kubernetes gives you powerful tools, but it also gives you enough rope to hang yourself. Start simple, enforce resource limits, and monitor everything."

Frequently Asked Questions

Is Kubernetes overkill for a small startup?
Often, yes. If you have <5 services and low traffic, managed PaaS (like Heroku, Vercel, or Azure App Service) is cheaper and easier. Move to K8s when complexity outgrows PaaS capabilities.
How do I handle database migrations in K8s?
Use Init Containers or Jobs to run migrations before the main app starts. Never run migrations inside the main application startup code to avoid race conditions during scaling.
What is the difference between HPA and VPA?
HPA (Horizontal) adds more pods. VPA (Vertical) increases the CPU/RAM of existing pods. HPA is generally safer for stateless web apps; VPA is better for stateful or batch jobs.

Conclusion

Mastering Kubernetes orchestration is a journey. Start with solid Deployments and Services, implement strict health checks, and gradually add autoscaling and advanced networking. The goal isn’t just to run containers—it’s to build a system that heals itself.

Looking for more DevOps guides? Check out our articles on [Docker Best Practices] and [CI/CD Pipelines for .NET].

We use cookies to improve your experience.