Kubernetes & Container Orchestration
A practical, beginner-to-advanced guide to running containerized applications — from Pods, Deployments, Services, and Ingress to configuration, scaling, security, troubleshooting, and managed Kubernetes on AKS, EKS, and GKE.
01. Introduction to Container Orchestration
Running one container is straightforward. Running a production application made of an API, background worker, cache, and supporting services is a different challenge. You must keep the right number of instances running, replace failed containers, distribute traffic, manage configuration, roll out releases safely, and recover when nodes become unavailable.
Container orchestration automates much of this operational work. Kubernetes provides a declarative platform: you describe the desired state of your application, and Kubernetes controllers continuously work to make the real cluster match it.
The control plane schedules and reconciles workloads across worker nodes; containers run inside Pods.
02. What Is Kubernetes?
Kubernetes (often shortened to k8s) is an open-source system for deploying, scaling, and managing containerized applications. It is not a container runtime and it does not build your application image. It coordinates workloads that are run by container runtimes on cluster nodes.
A Kubernetes cluster contains a control plane and one or more worker nodes. The control plane exposes the Kubernetes API and makes scheduling and management decisions. Worker nodes provide compute resources where Pods run.
| Concern | What Kubernetes provides |
|---|---|
| Scheduling | Places Pods on eligible nodes based on resources and scheduling rules. |
| Self-healing | Recreates failed Pods and replaces unhealthy workload instances. |
| Service discovery | Provides stable Service names and virtual networking. |
| Rollouts | Coordinates rolling updates and rollbacks for supported workloads. |
| Scaling | Changes replica counts and can scale workloads or node capacity with additional components. |
03. Why Orchestration Is Needed
Imagine deploying an ASP.NET Core Web API as a single Docker container on one virtual machine. What happens if the process exits, the VM fails, traffic doubles, or you need to deploy a new version without interrupting users?
- Without orchestration: scripts and operators manually restart containers, configure load balancing, and coordinate releases.
- With orchestration: you declare replicas, health checks, resource requests, networking, and rollout strategy; controllers continuously reconcile the cluster.
Kubernetes is especially useful when an application has multiple services, multiple deployment environments, changing traffic, or operational requirements that justify a cluster. For a small application, a managed app platform or a single container host may be simpler and cheaper.
04. Kubernetes Architecture
The control plane manages the cluster's desired state. Worker nodes execute the workloads. In a managed service such as AKS, EKS, or GKE, the cloud provider operates much of the control plane, while you still configure workloads, node pools, networking, access, and operations.
A simplified view. Actual networking and proxy implementation depends on the cluster's CNI and dataplane configuration.
kube-apiserverexposes the Kubernetes API.etcdstores cluster state.kube-schedulerselects nodes for newly created Pods.kube-controller-managerruns controllers that reconcile desired and observed state.kubeletensures containers described by Pod specifications are running on a node.- A container runtime such as containerd runs containers. The runtime is not the same thing as Docker Engine.
05. Kubernetes Objects and YAML
You normally interact with Kubernetes by submitting API objects, often written as YAML manifests. A manifest describes an object's apiVersion, kind, metadata, and specification.
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
labels:
app: sample
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
This is a learning example, not a production deployment pattern. In real applications, use a Deployment to manage Pods rather than creating standalone Pods for ordinary stateless services.
| Manifest field | Purpose |
|---|---|
apiVersion | API group and version for the object. |
kind | Resource type, such as Deployment or Service. |
metadata | Name, namespace, labels, and annotations. |
spec | Desired configuration for the resource. |
status | Observed state reported by Kubernetes; normally not authored by you. |
06. Pods: The Smallest Deployable Unit
A Pod is the smallest deployable unit in Kubernetes. A Pod can contain one or more tightly coupled containers that share network identity and can share mounted storage. Most application Pods contain one main application container plus, in some designs, helper containers.
Containers in the same Pod communicate over localhost. Containers in different Pods communicate through the cluster network, usually via a Service. A Pod is replaceable: do not treat its IP address or local filesystem as permanent identity or durable storage.
Use a Deployment to manage stateless API Pods. Use StatefulSet only when stable Pod identity and ordered deployment/scaling are required. Use Jobs or CronJobs for finite tasks and scheduled work.
07. Labels, Selectors, and Annotations
Labels are key/value metadata used to group and select resources. Deployments use selectors to identify the Pods they manage; Services use selectors to find the Pods that receive traffic. A selector mismatch is a common reason a Service has no endpoints.
metadata:
labels:
app: catalog-api
component: backend
environment: production
spec:
selector:
matchLabels:
app: catalog-api
Annotations store non-identifying metadata for tools and automation, such as deployment details or ingress-controller configuration. Do not use annotations as a substitute for labels when resources must be selected.
08. Deployments and ReplicaSets
A Deployment manages a desired number of interchangeable Pod replicas for stateless workloads. It creates and manages a ReplicaSet, which in turn creates Pods. If a Pod disappears, the ReplicaSet works to restore the desired replica count.
apiVersion: apps/v1
kind: Deployment
metadata:
name: catalog-api
spec:
replicas: 3
selector:
matchLabels:
app: catalog-api
template:
metadata:
labels:
app: catalog-api
spec:
containers:
- name: api
image: registry.example.com/catalog-api:1.0.0
ports:
- containerPort: 8080
The Pod template is important: changing the image or another Pod-template field creates a new rollout. Changing only the Deployment metadata does not necessarily restart Pods.
09. Services and Stable Networking
Pods are temporary, so clients should not depend on individual Pod IP addresses. A Service provides a stable virtual address and DNS name for a set of Pods selected by labels.
| Service type | Typical use |
|---|---|
ClusterIP | Internal cluster communication; default type. |
NodePort | Exposes a port on each node; often used for testing or specific network designs. |
LoadBalancer | Requests an external or internal cloud load balancer through the provider integration. |
ExternalName | Maps a Service name to an external DNS name; does not proxy traffic. |
apiVersion: v1
kind: Service
metadata:
name: catalog-api
spec:
type: ClusterIP
selector:
app: catalog-api
ports:
- name: http
port: 80
targetPort: 8080
Here, clients connect to catalog-api:80 inside the namespace; Kubernetes routes traffic to selected Pods on port 8080.
10. Ingress and Gateway API
Ingress is an API object for HTTP and HTTPS routing from outside the cluster to Services. An Ingress resource does not process traffic by itself: an Ingress controller must implement it. The controller may be provided by a cloud integration or installed separately.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: catalog-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: catalog-api
port:
number: 80
For new platform designs, also evaluate the Kubernetes Gateway API. It provides a more expressive and role-oriented model for gateways, listeners, routes, and policy attachment. Support depends on the chosen implementation; do not assume every cluster enables it by default.
11. Namespaces and Resource Isolation
A Namespace provides a logical scope for namespaced resources. Teams often use namespaces to separate environments, applications, or ownership boundaries. Namespaces are useful for organization and policy, but they are not a strong security boundary by themselves.
kubectl create namespace staging
kubectl get pods --namespace staging
kubectl config set-context --current --namespace=staging
Combine namespaces with Role-Based Access Control (RBAC), ResourceQuota, LimitRange, NetworkPolicy, and admission policies where appropriate. Cluster-scoped resources, such as Nodes and PersistentVolumes, are not contained by a namespace.
12. ConfigMaps and Application Configuration
A ConfigMap stores non-confidential configuration separately from the container image. It can be exposed as environment variables or mounted files. This allows the same image to be promoted across environments with different configuration.
apiVersion: v1
kind: ConfigMap
metadata:
name: catalog-config
data:
ASPNETCORE_ENVIRONMENT: "Production"
CatalogOptions__PageSize: "50"
ASP.NET Core supports hierarchical configuration through environment variables. Double underscores (__) represent a configuration hierarchy separator, so CatalogOptions__PageSize maps to CatalogOptions:PageSize.
ConfigMap values are not secret storage. For passwords, connection strings, certificates, and API keys, use Kubernetes Secrets with appropriate encryption and access controls, or integrate an external secret manager.
13. Secrets and Secure Configuration
Kubernetes Secrets are intended for confidential values, but base64 encoding is not encryption. Protect Secret access with least-privilege RBAC, enable encryption at rest for the cluster's data store, restrict who can create Pods in sensitive namespaces, and consider an external secret-management integration.
apiVersion: v1
kind: Secret
metadata:
name: catalog-db
type: Opaque
stringData:
ConnectionStrings__Catalog: "Server=db;Database=Catalog;..."
For production, avoid committing real Secret values to source control. Use a secure delivery workflow such as a cloud secret store with workload identity, an external-secrets controller, or an approved sealed/encrypted secret process. Rotate credentials and audit access.
14. Volumes and Persistent Storage
Container filesystems are generally ephemeral. A Pod replacement can lose data written only to its container filesystem. Kubernetes storage abstractions separate storage lifecycle from the Pod lifecycle.
- Volume: storage made available to containers in a Pod.
- PersistentVolume (PV): a cluster storage resource.
- PersistentVolumeClaim (PVC): a workload's request for storage.
- StorageClass: describes dynamic provisioning behavior and storage characteristics.
For databases, understand the storage provider's performance, availability, backup, restore, and failure semantics. A PVC is not a backup. For many applications, a managed database service is simpler than operating a database inside the cluster.
15. Health Checks: Startup, Readiness, and Liveness
Kubernetes probes answer different questions. A correct probe design prevents traffic from reaching an application before it is ready and avoids restarting an application merely because a dependency is temporarily slow.
| Probe | Question | Failure effect |
|---|---|---|
| Startup | Has the application finished starting? | Other probes are held until startup succeeds; repeated failure restarts the container. |
| Readiness | Can this instance receive traffic now? | Pod is removed from Service endpoints while unready. |
| Liveness | Is this process stuck and should it be restarted? | Repeated failure restarts the container. |
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 8080
periodSeconds: 5
livenessProbe:
httpGet:
path: /health/live
port: 8080
periodSeconds: 10
Expose suitable health endpoints in ASP.NET Core using health checks. Keep liveness checks lightweight; avoid making a temporary database outage cause every API Pod to restart repeatedly.
16. Resource Requests and Limits
The scheduler uses resource requests to decide where a Pod can fit. CPU and memory limits constrain container usage. Requests are not simply a reservation guarantee for all resources in every situation, and CPU and memory limits have different behavior.
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
CPU is measured in cores (for example, 250m is one quarter of a CPU core). Memory uses byte-based units such as Mi and Gi. A container exceeding its memory limit may be terminated with an out-of-memory event; CPU limits generally throttle CPU usage.
Set initial values from measurements, then tune them using realistic load tests and production metrics. Incorrect requests can cause poor scheduling; overly restrictive limits can cause throttling or restarts.
17. Scaling Applications
Kubernetes supports manual scaling and automated scaling. A Deployment's replica count controls how many Pod copies should exist. The Horizontal Pod Autoscaler (HPA) can adjust replicas based on resource metrics or custom/external metrics when the required metrics APIs and adapters are configured.
kubectl scale deployment catalog-api --replicas=4
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: catalog-api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: catalog-api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
HPA does not create compute capacity by itself. If no node has room for new Pods, a cluster autoscaler or provider node-pool autoscaling feature may need to add nodes. Workload scaling and node scaling solve different problems.
18. Node Pools, Scheduling, and Placement
Worker nodes are commonly grouped into node pools or node groups with similar machine types, operating systems, labels, and scaling rules. You can guide Pod placement using node selectors, node affinity, taints, and tolerations.
nodeSelectoris a simple way to require node labels.- Node affinity expresses more flexible placement preferences or requirements.
- Taints repel Pods unless they tolerate the taint.
- Topology spread constraints distribute replicas across failure domains such as zones or nodes.
For resilient APIs, avoid placing every replica on one node or one availability zone. Design for the failure domains actually offered by the selected cloud region and cluster configuration.
19. Rolling Updates and Rollbacks
A Deployment can update Pods gradually. A rolling update replaces old replicas with new replicas while respecting configured availability and surge limits.
kubectl set image deployment/catalog-api api=registry.example.com/catalog-api:1.1.0
kubectl rollout status deployment/catalog-api
kubectl rollout history deployment/catalog-api
kubectl rollout undo deployment/catalog-api
For production, define a rollout strategy, use readiness probes, set appropriate disruption budgets, and validate the new version before removing old capacity. A Kubernetes rollback restores a previous workload template; it does not automatically reverse database schema changes or external side effects.
20. Jobs and CronJobs
Not every container is a long-running web service. A Job runs work to completion, while a CronJob creates Jobs on a schedule. Common examples include report generation, data imports, cleanup, and scheduled reconciliation.
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: report
image: registry.example.com/report-worker:1.0.0
Scheduled execution is not a guarantee of exactly-once business processing. Design jobs to be idempotent, handle retries, set deadlines and history limits, and make duplicate execution safe.
21. Network Policies and Cluster Networking
Pods need network connectivity to communicate. The Container Network Interface (CNI) plugin provides the cluster's Pod networking implementation. A NetworkPolicy can restrict traffic to and from selected Pods, but it only has an effect when the installed network plugin enforces NetworkPolicy.
Start with a documented traffic model: ingress from gateway or frontend, egress to databases and approved external services, DNS, telemetry, and required platform endpoints. Test policy behavior in a non-production namespace before applying default-deny rules broadly.
22. Service Accounts and RBAC
A Kubernetes ServiceAccount is an identity for a workload or process running in a Pod. RBAC controls what a user, group, or ServiceAccount can do to Kubernetes API resources.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Bind permissions to the narrowest practical namespace and resource scope. Avoid granting cluster-admin to application workloads. Disable automatic service-account token mounting when a Pod does not need Kubernetes API access, and use cloud workload identity for access to cloud services where supported.
23. Container Images and Registries
Kubernetes pulls container images from registries such as Azure Container Registry, Amazon Elastic Container Registry, Google Artifact Registry, or another OCI-compatible registry. Use immutable version tags or image digests for repeatable deployments; avoid relying on a mutable latest tag.
containers:
- name: api
image: myregistry.example.com/catalog-api:1.4.2
imagePullPolicy: IfNotPresent
Use private registries, short-lived or workload-based credentials where available, image scanning, provenance/signature verification, and a controlled promotion process between environments. The cluster should run the same tested image artifact that passed CI.
24. Deploy an ASP.NET Core API to Kubernetes
Build the application as a Linux container image, publish it to a registry, then deploy it with Kubernetes manifests. The following .NET 10 example listens on port 8080 inside the container. Confirm your application's configured URL and health endpoints match the manifest.
# Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish ./Catalog.Api/Catalog.Api.csproj -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
USER $APP_UID
ENTRYPOINT ["dotnet", "Catalog.Api.dll"]
# Deployment fragment
containers:
- name: catalog-api
image: registry.example.com/catalog-api:1.0.0
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: catalog-config
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
Build and test the image before deploying. Keep secrets outside the image, run as a non-root user, pin base-image updates through a patching process, and scan the final image.
25. ASP.NET Core Configuration in Kubernetes
ASP.NET Core's configuration system can read environment variables. Kubernetes can populate those variables from ConfigMaps and Secrets. This keeps environment-specific values outside the image.
builder.Configuration
.AddEnvironmentVariables();
var connectionString =
builder.Configuration.GetConnectionString("Catalog");
A Kubernetes key such as ConnectionStrings__Catalog maps to the hierarchical configuration key ConnectionStrings:Catalog. Prefer the default configuration providers already registered by the ASP.NET Core hosting model unless you have a specific reason to add providers manually.
For production, retrieve sensitive connection details through a secret integration or mounted secret, and use managed identity/workload identity when your database and cloud platform support it.
26. Graceful Shutdown and Application Lifecycle
Kubernetes may terminate a Pod during a rollout, scale-down, node drain, or rescheduling event. The kubelet sends a termination signal and observes the configured grace period. Your .NET application should stop accepting new work, finish or safely abandon in-flight work, and release resources.
- Handle cancellation tokens in request and background processing paths.
- Configure an appropriate
terminationGracePeriodSeconds. - Use a readiness probe so the Pod stops receiving new Service traffic when it is no longer ready.
- Make message handlers idempotent and use durable queues for work that must survive process termination.
- Do not rely on a shutdown hook as the only way to persist critical business data.
Test shutdown behavior under rolling deployments and node drains rather than assuming the process will always have unlimited time to finish.
27. Observability: Logs, Metrics, and Traces
When a distributed application runs across multiple Pods and nodes, a developer needs more than local console output. Observability usually combines logs, metrics, and distributed traces.
- Logs: structured application and platform events, collected centrally.
- Metrics: request rate, error rate, latency, CPU, memory, queue depth, and saturation.
- Traces: correlated spans across API calls, services, and dependencies.
For .NET applications, use structured logging and OpenTelemetry instrumentation where appropriate. Export telemetry to a supported collector or managed service. Avoid logging secrets, access tokens, personal data, or full request bodies by default.
28. Helm, Kustomize, and Deployment Packaging
As manifests grow, teams often use tools to manage reusable configuration.
| Tool | How it helps |
|---|---|
| Plain YAML | Good for learning and small, stable workloads. |
| Kustomize | Applies overlays and patches to a common base without templating. |
| Helm | Packages Kubernetes resources as charts with configurable values and release lifecycle. |
Choose a tool your team can review and operate. Keep environment differences explicit, validate rendered manifests in CI, and avoid hiding important production behavior behind complex templates.
29. Local Kubernetes Development
You do not need a production cloud cluster to learn the core Kubernetes API. Local options include kind, minikube, and Docker Desktop's Kubernetes integration. Their capabilities and networking behavior differ from managed cloud clusters.
# Example using kind
kind create cluster --name learning
kubectl cluster-info
kubectl get nodes
kubectl create namespace learning
Use a local cluster to practice manifests, Services, probes, rollouts, and troubleshooting. Validate cloud-specific behavior—load balancers, identity, storage classes, and ingress integrations—on the target managed service.
30. kubectl: Essential Commands
kubectl is the command-line client for the Kubernetes API. These commands are useful during development and incident investigation:
kubectl get nodes
kubectl get pods -A
kubectl get deployments -n staging
kubectl describe pod POD_NAME -n staging
kubectl logs deployment/catalog-api -n staging
kubectl logs POD_NAME --previous -n staging
kubectl apply -f ./k8s/
kubectl delete -f ./k8s/
kubectl get events -n staging --sort-by=.lastTimestamp
kubectl port-forward service/catalog-api 8080:80 -n staging
Use namespaces explicitly in scripts and operational runbooks. Before applying or deleting resources, confirm the current context and namespace:
kubectl config current-context
kubectl config view --minify31. Troubleshooting Common Problems
| Symptom | Likely checks |
|---|---|
ImagePullBackOff | Image name/tag, registry permissions, pull secret, network access, architecture. |
CrashLoopBackOff | Container logs, startup command, configuration, dependencies, memory limit. |
| Pod remains Pending | Node capacity, requests, taints/tolerations, affinity, PVC binding, quota. |
| Service has no endpoints | Selector labels, Pod readiness, target port, namespace. |
| Ingress returns 404/502 | Controller health, ingress class, host/path rules, Service port, endpoint readiness. |
| Pod is OOMKilled | Memory usage, limit, leak, workload size, runtime diagnostics. |
| DNS lookup fails | Service name/namespace, CoreDNS, NetworkPolicy, cluster DNS configuration. |
Start with kubectl describe, logs, events, and endpoint inspection. Change one variable at a time and preserve diagnostic evidence before restarting or deleting resources.
32. Security Best Practices
- Run containers as non-root and use a read-only root filesystem where practical.
- Use minimal, maintained base images and rebuild regularly for security patches.
- Pin images by immutable digest in controlled production workflows.
- Apply least-privilege RBAC and avoid unnecessary API token mounting.
- Use Pod Security Standards and admission controls appropriate to your cluster.
- Store secrets securely, encrypt them at rest, rotate them, and audit access.
- Apply NetworkPolicies when supported by the CNI and validate actual enforcement.
- Set resource requests and limits; use quotas to prevent noisy-neighbor exhaustion.
- Scan images, generate software bills of materials where required, and verify image provenance.
- Keep Kubernetes, node images, add-ons, and ingress components on supported versions.
Security is a layered design. No single manifest field, scanner, or namespace makes a cluster secure by itself.
33. High Availability, Backups, and Disaster Recovery
High availability requires planning across multiple failure domains. Run enough replicas, distribute them across nodes/zones, use readiness probes, and configure PodDisruptionBudgets for voluntary disruptions. A PDB does not protect against every involuntary failure and does not replace replica design.
Back up application data and cluster configuration using solutions appropriate to the workload. Stateful data often lives in managed databases or external storage, not in a container's writable layer. Test restore procedures and recovery objectives. A successful backup job is not proof that recovery will work.
34. Kubernetes vs Docker vs Virtual Machines
| Technology | Main responsibility |
|---|---|
| Docker / container tooling | Builds, packages, and runs containers in developer and host workflows. |
| Kubernetes | Orchestrates containerized workloads across a cluster. |
| Virtual machines | Provide isolated operating-system environments on virtualized infrastructure. |
These technologies are complementary rather than direct replacements. A common workflow is to build an OCI image with Docker-compatible tooling, store it in a registry, and let Kubernetes run that image through the node's container runtime.
35. Managed Kubernetes: AKS, EKS, and GKE
Managed Kubernetes services reduce the operational burden of operating the control plane and integrate Kubernetes with cloud identity, networking, storage, monitoring, and load balancing. They do not remove the need to manage workload manifests, access, upgrades, costs, and application reliability.
| Service | Cloud | Useful integrations to evaluate |
|---|---|---|
| AKS | Microsoft Azure | Azure Container Registry, Microsoft Entra ID, Azure networking, Azure Monitor, managed identity / workload identity. |
| EKS | Amazon Web Services | Elastic Container Registry, IAM / EKS Pod Identity, VPC networking, load balancers, CloudWatch. |
| GKE | Google Cloud | Artifact Registry, Google Cloud IAM / Workload Identity Federation, VPC-native networking, Cloud Logging and Monitoring. |
For a .NET team already deploying to Azure, AKS may reduce integration friction. EKS and GKE are strong options when the organization operates primarily on AWS or Google Cloud. Choose based on existing platform skills, compliance, network architecture, regional availability, support model, and total cost—not only feature checklists.
36. AKS: Deploying a .NET API on Azure
For an Azure-focused .NET deployment, a typical path is: build a container image, push it to Azure Container Registry (ACR), create or use an AKS cluster, grant the cluster access to pull the image, and apply Kubernetes resources.
# Example workflow (resource names and region are placeholders)
az login
az acr login --name YOUR_ACR_NAME
docker build -t YOUR_ACR_NAME.azurecr.io/catalog-api:1.0.0 .
docker push YOUR_ACR_NAME.azurecr.io/catalog-api:1.0.0
az aks get-credentials --resource-group YOUR_RESOURCE_GROUP --name YOUR_AKS_CLUSTER
kubectl apply -f ./k8s/
Use supported AKS identity integration rather than long-lived registry passwords where possible. Decide whether ingress is public or private, configure TLS and DNS, use Azure Monitor or your standard telemetry stack, and select an AKS version supported in your region. AKS offers an optional LTS support plan for eligible Kubernetes versions; it is separate from .NET's LTS lifecycle.
37. EKS: Deploying a .NET API on AWS
On AWS, a common flow is to publish the image to Amazon ECR, create or use an EKS cluster, configure workload identity and networking, then deploy the workload. EKS provides standard and extended Kubernetes version support options; extended support can have additional cost.
# Illustrative workflow
aws ecr get-login-password --region YOUR_REGION |
docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com
docker build -t catalog-api:1.0.0 .
docker tag catalog-api:1.0.0 YOUR_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/catalog-api:1.0.0
docker push YOUR_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/catalog-api:1.0.0
aws eks update-kubeconfig --region YOUR_REGION --name YOUR_CLUSTER
kubectl apply -f ./k8s/
Use IAM-based workload access (such as EKS Pod Identity or a supported IAM roles for service accounts setup), private networking where required, and the AWS load-balancing integration that matches your ingress design.
38. GKE: Deploying a .NET API on Google Cloud
On Google Cloud, publish the image to Artifact Registry and deploy to GKE. GKE provides release channels that influence version availability and automatic upgrade timing. Stable, Regular, Rapid, and Extended channels have different trade-offs.
# Illustrative workflow
gcloud auth configure-docker YOUR_REGION-docker.pkg.dev
docker build -t YOUR_REGION-docker.pkg.dev/PROJECT/REPOSITORY/catalog-api:1.0.0 .
docker push YOUR_REGION-docker.pkg.dev/PROJECT/REPOSITORY/catalog-api:1.0.0
gcloud container clusters get-credentials YOUR_CLUSTER --region YOUR_REGION --project YOUR_PROJECT
kubectl apply -f ./k8s/
Use Workload Identity Federation for GKE to grant workloads access to Google Cloud services without embedding service-account keys. Choose Standard or Autopilot based on how much node-level control and operational responsibility your team needs.
39. CI/CD and GitOps for Kubernetes
A reliable delivery pipeline should build an image once, test it, scan it, publish it, and promote the same artifact through environments. Deployment configuration can be updated through a pipeline or a GitOps controller such as Argo CD or Flux.
- Restore dependencies and build the .NET solution.
- Run unit and integration tests.
- Build the OCI image and attach a unique version or digest.
- Scan the image and publish it to a trusted registry.
- Validate Kubernetes manifests or rendered Helm/Kustomize output.
- Deploy to a test environment and run smoke tests.
- Promote the same image digest to production with a reviewed change.
- Monitor rollout health and define rollback criteria.
GitOps makes the desired deployment state version-controlled and continuously reconciled. It is not a substitute for access control, secret management, review, or operational monitoring.
40. Cost and Capacity Planning
Kubernetes cost is driven by node capacity, storage, load balancers, network transfer, observability, control-plane pricing (where applicable), and operational support. An underutilized cluster can cost more than a managed application platform for a small workload.
- Right-size requests and limits using measured utilization.
- Use autoscaling carefully and understand minimum node-pool capacity.
- Separate workloads with different CPU, memory, or hardware requirements.
- Review idle load balancers, disks, snapshots, and unattached resources.
- Set namespace quotas and cost allocation labels.
- Include engineering time, upgrades, incident response, and compliance work in total cost.
Before adopting Kubernetes, compare the total cost and operational complexity with Azure App Service, container apps, ECS, Cloud Run, or another managed compute option.
41. Production Readiness Checklist
- Image is versioned immutably and stored in a trusted registry.
- Workload runs as non-root with least privilege.
- Readiness, liveness, and startup probes match application behavior.
- Requests and limits are based on load testing.
- Replicas are distributed across failure domains where available.
- Service and ingress/gateway routes are tested, with TLS configured.
- Secrets are protected, rotated, and not committed to Git.
- RBAC, NetworkPolicies, quotas, and admission policies are reviewed.
- Graceful shutdown and rolling updates are tested.
- Logs, metrics, traces, alerts, and dashboards are available.
- Backups and restore procedures are tested.
- Cluster, node images, add-ons, and APIs are on supported versions.
- CI/CD includes tests, image scanning, manifest validation, and rollback criteria.
42. Practical Mini Project: Catalog API
Build a small production-style deployment for a .NET 10 Catalog API. The goal is to understand the full path from source code to a reachable, observable workload.
- Create an ASP.NET Core Web API targeting
net10.0and add a lightweight health endpoint. - Create a multi-stage Dockerfile and build a Linux image.
- Run the image locally and verify the API and health endpoint.
- Push the image to a registry.
- Create a namespace, ConfigMap, Deployment, Service, and Ingress or Gateway API route.
- Add resource requests/limits and startup, readiness, and liveness probes.
- Deploy two or more replicas and verify service routing.
- Change the image tag and observe a rolling update.
- Scale the Deployment and inspect Pod placement.
- Introduce a failing configuration in a test environment and practice troubleshooting and rollback.
- Configure telemetry and verify that logs and metrics can be correlated with the deployed version.
Extend the project with an external secret store, HPA, NetworkPolicy, and a CI/CD pipeline. Keep the database outside the cluster initially so you can focus on the Kubernetes application lifecycle.
43. Interview Questions and Answers
1. What is Kubernetes?
An open-source container orchestration platform for deploying, scaling, and managing containerized applications.
2. What is a Pod?
The smallest deployable Kubernetes unit. It contains one or more containers that share network identity and can share storage.
3. Why use a Deployment instead of creating Pods directly?
A Deployment manages ReplicaSets and keeps the desired number of interchangeable Pods running, while supporting declarative updates and rollbacks.
4. What is a Service?
A stable network endpoint that selects Pods and routes traffic to them.
5. ClusterIP vs NodePort vs LoadBalancer?
ClusterIP is internal, NodePort exposes a port on nodes, and LoadBalancer requests a cloud or infrastructure load balancer integration.
6. What is Ingress?
An API resource describing HTTP/HTTPS routing into the cluster. It requires an Ingress controller to implement the routing.
7. What is a Namespace?
A logical scope for namespaced resources, commonly used for organization, access policy, quotas, and environment separation.
8. ConfigMap vs Secret?
ConfigMap holds non-confidential configuration. Secret is intended for confidential data but needs encryption, access control, and careful handling.
9. What is the difference between readiness and liveness probes?
Readiness controls whether a Pod receives Service traffic. Liveness determines whether a container should be restarted.
10. What is a startup probe?
It gives a slow-starting application time to initialize before readiness and liveness checks begin.
11. What is HPA?
Horizontal Pod Autoscaler adjusts workload replica counts using resource, custom, or external metrics.
12. Does HPA add worker nodes?
No. Node autoscaling is a separate capability that adds or removes cluster compute capacity.
13. What is a PersistentVolumeClaim?
A request for persistent storage that can be bound to a PersistentVolume or dynamically provisioned through a StorageClass.
14. What is a rolling update?
A Deployment strategy that gradually replaces old Pods with new ones while observing availability constraints.
15. What is a ReplicaSet?
A controller that maintains a specified number of Pod replicas. Deployments manage ReplicaSets for rollout history and updates.
16. What is RBAC?
Role-Based Access Control, which grants permissions to users, groups, or ServiceAccounts for Kubernetes API resources.
17. What is a NetworkPolicy?
A policy object that controls Pod network traffic when the cluster's networking implementation supports enforcement.
18. What is Helm?
A package manager for Kubernetes that groups resources into charts with configurable values and release management.
19. What is the difference between AKS, EKS, and GKE?
They are managed Kubernetes services from Azure, AWS, and Google Cloud respectively, with different integrations, support policies, and operational models.
20. Does Kubernetes replace Docker?
No. Container tooling builds and runs images; Kubernetes orchestrates workloads. Kubernetes nodes use a CRI-compatible runtime such as containerd.
21. What happens when a Pod crashes?
The kubelet applies the Pod restart policy for its containers, and workload controllers such as ReplicaSet work to maintain the desired number of Pods.
22. Why should a .NET API handle SIGTERM gracefully?
Pods are terminated during rollouts and node maintenance. Graceful shutdown helps stop new work and complete or safely cancel in-flight work.
44. Official Documentation and Further Learning
- Kubernetes official documentation
- Kubernetes release information and support windows
- Kubernetes workloads concepts
- Services and networking
- Configuration, ConfigMaps, and Secrets
- Kubernetes tasks and tutorials
- Azure Kubernetes Service (AKS)
- Amazon Elastic Kubernetes Service (EKS)
- Google Kubernetes Engine (GKE)
- What's new in .NET 10
- .NET diagnostics
- OpenTelemetry for .NET
Cloud service versions, feature availability, and support policies change independently. Verify the provider's documentation for the target region, cluster mode, and release channel before planning an upgrade.
45. Final Thought
Kubernetes is most valuable when you understand the operational problems it solves—not when you memorize YAML fields. Pods provide the execution unit, Deployments maintain stateless replicas, Services provide stable networking, and configuration, probes, scaling, and policies make workloads manageable.
As a .NET developer, focus first on building container-ready ASP.NET Core services: externalize configuration, handle graceful shutdown, expose meaningful health checks, emit useful telemetry, and keep the application stateless where possible. Then learn how Kubernetes runs and connects those services. That foundation transfers across AKS, EKS, GKE, and other Kubernetes platforms.
Skills Tutorials – Learn • Build • Grow Together