← Back to Blog DevOps

Production Kubernetes for .NET: Helm, HPA, and Zero-Downtime Deploys

Saurav Rai

Founder & Lead Architect

· · 14 min read

Overview

Complete production Kubernetes guide: health checks, resource limits, rolling updates, PodDisruptionBudgets.

Health Checks Are Not Optional

Kubernetes uses liveness and readiness probes to manage pod lifecycle. Liveness restarts unhealthy pods; readiness controls traffic routing. Without proper probes, your zero-downtime deployment will briefly route traffic to unready pods.

.NET 8 has excellent built-in health check middleware. Configure it to report database connectivity, external dependencies, and memory pressure.

builder.Services.AddHealthChecks()
    .AddSqlServer(connectionString)
    .AddRedis(redisConnectionString)
    .AddCheck<CustomHealthCheck>("dependencies");

// In kubernetes deployment.yaml:
livenessProbe:
  httpGet: { path: /healthz/live, port: 8080 }
  initialDelaySeconds: 10
readinessProbe:
  httpGet: { path: /healthz/ready, port: 8080 }
  initialDelaySeconds: 5

Horizontal Pod Autoscaler

HPA automatically scales your deployment based on CPU, memory, or custom metrics. For .NET services, we configure CPU-based scaling with a 60% target—providing enough headroom for traffic spikes without wasting resources.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target: { type: Utilization, averageUtilization: 60 }

Zero-Downtime Deployments

Rolling updates replace pods one-by-one, but without preStop hooks and terminationGracePeriodSeconds, in-flight requests will be dropped. Configure a preStop sleep to drain connections before termination.

  • Set maxUnavailable: 0 for zero-downtime
  • Add preStop: exec: command: ['sleep', '10']
  • Set terminationGracePeriodSeconds: 60
  • Use PodDisruptionBudget to prevent cluster disruptions
  • Always set resource requests and limits

Key Takeaways

  • Readiness probes prevent routing traffic to unready pods
  • HPA keeps costs down while handling traffic spikes
  • preStop hooks prevent connection drops during rolling updates
  • Resource limits prevent noisy-neighbour problems
  • PodDisruptionBudget guarantees minimum available replicas

Saurav Rai

Founder & Lead Architect, Omni Stack

7+ years building enterprise .NET and cloud applications for clients across Australia, USA, and the Middle East. Passionate about clean architecture, developer experience, and shipping fast.

.NET / Blazor · 12 min read

Blazor Auto Render Mode: Server vs WebAssembly Per Component

.NET 8 per-component interactivity: our production guide to choosing Server vs WASM—with benchmarks.

Read More →
.NET / Blazor · 8 min read

Building Real-Time Dashboards with SignalR and Blazor Server

Step-by-step: live-updating dashboards using SignalR Hub groups, Blazor Server, and efficient diff rendering.

Read More →
Azure · 15 min read

Deploying .NET Microservices to Azure AKS with Helm and GitHub Actions

Complete CI/CD walkthrough: containerise .NET, write Helm charts, configure AKS, and automate deployment.

Read More →