👋Hi, I'm Waqas — a Software Architect and Technical Consultant specializing in .NET, Azure, microservices, and API-first system design..
I help companies build reliable, maintainable, and high-performance backend platforms that scale.
Pods, Deployments, Services. Running .NET on AKS and local Kubernetes.
April 3, 2025 · Waqas Ahmad
Read the article
Introduction
This guidance is relevant when the topic of this article applies to your system or design choices; it breaks down when constraints or context differ. I’ve applied it in real projects and refined the takeaways over time (as of 2026).
Running .NET apps in production at scale usually means containers and an orchestrator—and Kubernetes is the dominant choice (AKS, EKS, GKE, or on-prem). This article is for .NET developers new to Kubernetes: we cover Pods, Deployments, Services, ConfigMaps and Secrets, health checks and resource limits, and how to run .NET on Kubernetes locally and on AKS. For architects and tech leads, understanding these basics matters when you move from “run on a VM” to orchestrated containers and need scheduling, scaling, and self-healing.
System scale: Containerised apps (e.g. .NET) from a few pods to many; single cluster or multi-environment. Applies when you’re moving from “run on a VM” to orchestrated containers.
Team size: Dev and ops (or platform); someone must own manifests, secrets, and cluster health. Works when the team can use kubectl and maintain YAML (or Helm).
Time / budget pressure: Fits when you need scaling, self-healing, or portability; breaks down when the team has no container or Kubernetes experience—then start with managed Kubernetes (e.g. AKS) and simple deployments.
Technical constraints: .NET in Docker; Kubernetes (or AKS, EKS, GKE); ConfigMaps, Secrets, health checks. Assumes you can build container images and deploy to a cluster.
Non-goals: This article does not optimise for non-container workloads or for deep cluster operations; it focuses on .NET developers getting apps onto Kubernetes.
What is Kubernetes and why use it?
Kubernetes is a container orchestrator. It takes your containerised applications (Docker images) and runs them across a cluster of machines, handling:
Capability
What it does
Scheduling
Decides which node runs which container
Scaling
Runs multiple replicas; scales up/down based on load
Why .NET developers should care: Your .NET API runs in a Docker container. Kubernetes runs that container, ensures it stays running, scales it when traffic increases, and routes requests to it.
Pods, Deployments, and Services
Resource
Purpose
Analogy
Pod
Runs one or more containers
A single instance of your app
Deployment
Manages a set of Pods
The “desired state” manager
Service
Exposes Pods to the network
A stable address for your app
Pod: Smallest deployable unit; one or more containers sharing network and storage. For .NET apps, typically one container per Pod.
Deployment: Manages replicas of Pods; handles rolling updates and rollback. You define the desired state (3 replicas); Kubernetes maintains it.
Service: Stable network identity for Pods (ClusterIP, LoadBalancer, NodePort). Pods are ephemeral; Services provide a stable address.
ConfigMaps store non-sensitive configuration (app settings, feature flags). Secrets store sensitive data (connection strings, API keys). Both can be mounted as environment variables or files.
# secret.yaml (values are base64-encoded)apiVersion:v1kind:Secretmetadata:name:my-api-secretstype:Opaquedata:ConnectionStrings__Default:U2VydmVyPW15c2VydmVyO0RhdGFiYXNlPW15ZGI=
Kubernetes runs containerised apps with scheduling, scaling, and self-healing; .NET apps run as Pods, Deployments manage replicas and rolling updates, Services expose them with a stable network name. Skipping health checks or resource limits makes the cluster unable to manage your app well; using ConfigMaps and Secrets (and not plain env vars for secrets) keeps config and security under control. Next, containerise your .NET app, write a Deployment and Service, set liveness and readiness probes and resource requests/limits, then deploy to AKS (or your cluster) and use kubectl to inspect and debug.
Position & Rationale
I use Kubernetes (or AKS) when we need orchestration: multiple replicas, rolling updates, self-healing, and a single place to define config and secrets. I prefer managed Kubernetes (AKS, EKS, GKE) over self-managed so we don’t run the control plane. For .NET I run one process per container and one main container per Pod unless we have a clear sidecar need. I set resource requests and limits and liveness/readiness probes so the scheduler and load balancer can make good decisions. I avoid running stateful or persistent data in Pods without a proper storage abstraction (PVC, StatefulSet) and I don’t put secrets in environment variables in plain text—use Kubernetes Secrets or a vault integration.
Trade-Offs & Failure Modes
Kubernetes adds YAML and operational concepts (Pods, Deployments, Services); you gain portability and orchestration. Managed Kubernetes reduces control-plane burden but ties you to a cloud provider. Failure modes: Pods without resource limits (one hungry pod can starve others); missing or wrong readiness probes (traffic sent to pods that aren’t ready); secrets in env as plain text; ImagePullBackOff or CrashLoopBackOff without a runbook.
What Most Guides Miss
Most guides show Pod/Deployment/Service but don’t stress readiness vs liveness—readiness controls when the Pod gets traffic; liveness controls when it gets restarted. Getting them wrong leads to restarts or traffic to broken pods. Another gap: resource requests and limits—if you don’t set them, the scheduler can overcommit and nodes run out of memory. Debugging (kubectl logs, describe, events) is often mentioned but not as a first resort when “it doesn’t work.”
Decision Framework
If you’re deploying a .NET app → Containerise it; create a Deployment (replicas, image, env) and a Service (ClusterIP or LoadBalancer).
For config → ConfigMaps for non-sensitive; Secrets for sensitive (or integrate with Key Vault).
For health → Set liveness and readiness probes so Kubernetes can restart and route traffic correctly.
For resources → Set requests and limits (CPU, memory) so the scheduler and node don’t overcommit.
When things fail → Use kubectl get/describe/logs/events to see why Pods are Pending, CrashLoopBackOff, or not receiving traffic.
Key Takeaways
Pods run containers; Deployments manage replica count and rolling updates; Services give a stable network name.
Use ConfigMaps and Secrets for config; set liveness and readiness and resource limits.
For .NET: one container per Pod unless you have a sidecar; use AKS (or similar) for managed Kubernetes.
Debug with kubectl get pods, describe pod, logs, and events when Pods don’t start or receive traffic.
When I Would Use This Again — and When I Wouldn’t
I’d use Kubernetes (AKS) again for any production .NET workload that needs scaling, rolling updates, and a standard place to run containers. I’d use the same pattern: Deployment + Service, ConfigMaps/Secrets, health checks, and resource limits. I wouldn’t run stateful data in Pods without a proper storage and backup story. I also wouldn’t adopt Kubernetes for a single small app with no scaling or portability need—simpler hosting (App Service, single VM) can be enough.
For production-grade Azure systems, I offer consulting on cloud architecture, scalability, and cloud-native platform design.
Frequently Asked Questions
Frequently Asked Questions
What is a Pod?
A Pod is the smallest deployable unit in Kubernetes; it runs one or more containers that share network and storage. Usually one container per Pod for .NET apps.
What is a Deployment?
A Deployment manages a set of Pod replicas: desired count, rolling updates, rollback. You define a template (container image, env, ports); Kubernetes creates Pods to match.
What is a Kubernetes Service?
A Service gives Pods a stable network name and IP; other Pods or external clients reach them via the Service. Types: ClusterIP (internal), LoadBalancer (external), NodePort.
What is the difference between ClusterIP and LoadBalancer?
ClusterIP is internal-only (accessible within the cluster). LoadBalancer creates a cloud load balancer with an external IP. Use ClusterIP for internal APIs; LoadBalancer for external APIs.
How do I configure my .NET app in Kubernetes?
Use ConfigMaps for non-sensitive config and Secrets for sensitive data. Reference them with envFrom or mount as files. For production, use Azure Key Vault with the CSI driver.
What are liveness and readiness probes?
Liveness probe: Is the container alive? If it fails, Kubernetes restarts the container. Readiness probe: Is the container ready for traffic? If it fails, Kubernetes stops sending traffic.
How do I scale my app in Kubernetes?
Manually: kubectl scale deployment my-api --replicas=5. Automatically: Use Horizontal Pod Autoscaler (HPA) to scale based on CPU.
What is AKS?
Azure Kubernetes Service (AKS) is Azure’s managed Kubernetes. Azure manages the control plane; you manage worker nodes.
Why is my Pod stuck in ImagePullBackOff?
The image cannot be pulled. Check image name/tag; verify registry auth with imagePullSecrets or ACR integration.
Why is my Pod in CrashLoopBackOff?
The container is crashing on startup. Check logs with kubectl logs <pod-name>.
What is the difference between requests and limits?
Requests are guaranteed resources. Limits are maximum resources. If memory limit is exceeded, the container is OOMKilled.
How do I run Kubernetes locally?
Use Docker Desktop, minikube, kind, or k3d. Docker Desktop is easiest for Windows/Mac.
What is an Ingress?
An Ingress routes HTTP traffic to Services based on host/path. Use one Ingress controller instead of multiple LoadBalancers.
Related Guides & Resources
Explore the matching guide, related services, and more articles.