Azure Kubernetes Service
AKS is Kubernetes with the control plane rented rather than run. Azure builds, patches, and operates the API server, scheduler, and etcd for you — free of charge, in a subscription you can't see — and hands you a
kubeconfig. Everything below the API server, starting with the worker nodes, is still yours: your VMs, your bill, your upgrades, your 3 a.m. page.
Names: the service is Azure Kubernetes Service (AKS). Its predecessor, Azure Container Service (ACS), is long retired, as is AKS Engine and its successor Cluster API Provider Azure (CAPZ) for self-managed clusters. Two names you'll meet in older material and should treat as dead: AAD Pod Identity (retired — use Microsoft Entra Workload ID) and the Open Service Mesh add-on (retired — use the Istio-based service mesh add-on). One more is on a clock: kubenet networking retires 31 March 2028 in favour of Azure CNI Overlay.
What it is and where it fits
Kubernetes is a control loop over a pool of machines: you declare the state you want ("five copies of this container, reachable on port 80, with these secrets mounted"), and a set of controllers works continuously to make reality match. AKS is that system with the hard, stateful, security-critical half — the API server and etcd — run by Azure as a managed service.
The split is the whole point, and it's the single fact that explains most of AKS's behaviour. The
managed control plane lives in a Microsoft-owned subscription you have no ARM access to. The
data plane — your nodes — lives in your subscription, in a second resource group AKS creates
and owns, conventionally named MC_<rg>_<cluster>_<region>. Your nodes are Virtual Machine Scale
Sets. Your persistent volumes are managed disks. Your load balancer is an Azure Load Balancer. AKS
is, from one angle, a controller that turns Kubernetes objects into Azure resources on your behalf.
The problem it kills is not "running containers" — that was solved cheaply years ago. It's
running a fleet of containers with an opinionated, portable, extensible orchestration API
without also employing people to keep etcd healthy. Before managed Kubernetes, standing up a
production cluster meant certificate rotation, etcd backups, control-plane HA across zones, and an
upgrade procedure that could take the whole platform down. AKS makes that a sku_tier setting and
an az aks upgrade command.
Azure's compute catalogue overlaps itself badly here, and picking AKS by default is the most expensive mistake on the platform. The neighbours, one line each:
- Azure Container Apps — Kubernetes-shaped runtime (it is built on AKS internals) with no cluster to operate, KEDA autoscaling, and scale-to-zero. Choose it for microservices and event-driven containers. You lose the Kubernetes API, DaemonSets, custom operators, node access, and most of the CNCF ecosystem.
- App Service — you bring code or a single container, Azure brings everything else. Choose it for a straightforward web app; you lose orchestration entirely.
- Azure Container Instances (ACI) — one container, no orchestrator, billed per second. A primitive, not a platform. AKS can burst onto it via Virtual Nodes.
- Azure Container Registry (ACR) — not an alternative; the thing that stores the images AKS pulls. Nearly every AKS topic ends up touching it.
- Virtual Machines / VM Scale Sets — what AKS nodes actually are. Understanding VMs is a prerequisite for reasoning about AKS node pools, not an alternative to it.
The honest rule: choose AKS when you need the Kubernetes API itself — operators and CRDs, a service mesh, GPU scheduling with device plugins, DaemonSets, an existing set of Helm charts, or genuine multi-cloud portability of your deployment manifests. Choose Container Apps when you want what Kubernetes does without what Kubernetes costs you in people.
If you're coming from AWS: AKS is EKS, and the mental model transfers well — managed control
plane, self-managed node groups, CNI plugin choice, IRSA ≈ Workload Identity. Where it breaks, and
it breaks in ways that surprise people: the AKS control plane is free in the Free tier (EKS
always charges per cluster-hour), Azure creates a second, AKS-owned resource group for your
nodes that has no EKS equivalent, node pools are VM Scale Sets you don't manage directly, and
Azure splits authorization into Azure RBAC on the cluster resource and Kubernetes RBAC inside
the cluster — with an optional mode where Azure RBAC governs both. There is no aws-auth
ConfigMap equivalent to break.
[Image Prompt: 2D minimalistic diagram of Azure Kubernetes Service showing a Microsoft-managed control plane above a customer-owned node resource group containing virtual machine scale sets, load balancer, and disks, flat design, clean vector art style, white background]
Key facts at a glance
| Category | Compute — managed container orchestration |
| Resource provider | Microsoft.ContainerService/managedClusters (node pools: .../managedClusters/agentPools) |
| Companion providers | Microsoft.Compute/virtualMachineScaleSets, Microsoft.Network/loadBalancers, Microsoft.ContainerRegistry/registries, Microsoft.ManagedIdentity/userAssignedIdentities |
| Scope | Regional; node pools are optionally zonal (spread across availability zones you nominate). The control plane's zone redundancy depends on tier and region ⚠️ verify against current Azure docs |
| The SKU axis — tier | Free / Standard / Premium. Free has no SLA (a best-effort SLO only); Standard adds the uptime SLA and supports far larger clusters; Premium adds Long-Term Support (LTS) for Kubernetes versions. Approximate list prices as of writing: Free $0, Standard ~$0.10/cluster/hour, Premium ~$0.60/cluster/hour ⚠️ verify against current Azure pricing |
| The SKU axis — cluster mode | Standard (you configure everything) vs. Automatic (Azure preconfigures node autoprovisioning, monitoring, security defaults, and pins the Standard tier). Automatic trades control for a working production baseline |
| The SKU axis — nodes | The VM size of each node pool, exactly as for Virtual Machines, plus OS SKU (Ubuntu / Azure Linux / Windows Server) and the Spot-vs-regular choice |
| Unit of billing | The cluster tier per hour + every node VM, disk, public IP, load balancer, and egress byte. The control plane is the cheap part; nodes are essentially the whole bill |
| The billing trap | Nodes bill whether or not a single pod is scheduled on them. An idle cluster with a 3-node system pool costs the same as a busy one. Kubernetes' own scale-to-zero applies to pods, not nodes, unless the cluster autoscaler or node autoprovisioning is switched on |
| SLA posture | Free tier: SLO, no financial backing. Standard/Premium: an uptime SLA on the API server, which says nothing about your workloads — those depend on your zone spread, PDBs, and replica counts ⚠️ verify current percentages |
| Usual companions | Azure Container Registry, Key Vault (+ Secrets Store CSI driver), Azure Monitor managed Prometheus + Container Insights, Managed Grafana, Application Gateway / App Routing, Virtual Network, Entra ID + Workload Identity |
| Primary alternative | Azure Container Apps for most microservice workloads; App Service for plain web apps |
| AWS rough analogue | EKS (+ managed node groups ≈ node pools, Fargate ≈ Virtual Nodes/ACI, IRSA ≈ Workload Identity) |
When to use AKS
- You need the Kubernetes API, not just container hosting — CRDs and operators, admission
webhooks, DaemonSets, StatefulSets with stable network identity,
kubectl-shaped operations. - You already own Helm charts or Kustomize overlays and want them to run unchanged. Portability of manifests is AKS's most defensible advantage over Container Apps.
- Heterogeneous workloads on one platform — batch and services, Linux and Windows, CPU and GPU, in separate node pools under one scheduler.
- GPU or specialised hardware scheduling — device plugins, MIG partitioning, InfiniBand-capable sizes. This is why AKS is Tier-A for ML platform work regardless of the general tiering.
- A platform team exists. AKS pays off when one team runs the cluster and many teams deploy to it. It is a platform product, and it needs a platform owner.
- Multi-cloud or hybrid intent that is real, not aspirational — Azure Arc-enabled Kubernetes extends the same tooling to clusters elsewhere.
When not to use AKS
- A single web app, or three microservices. Container Apps does this with no cluster, no upgrade cycle, and scale-to-zero. The AKS version costs more in nodes and vastly more in attention.
- Nobody has agreed to own Kubernetes upgrades. Kubernetes minor versions go out of support in roughly a year (AKS supports approximately N-2 ⚠️ verify current policy), and an out-of-support cluster is both a security problem and an unsupportable one. If there's no upgrade owner, this is a genuine architectural disqualifier.
- Bursty work that's idle most of the time. You'll pay for nodes to sit empty. Functions or Container Apps scale to zero; a node pool's floor is whatever you set it to, and the system pool's floor is never zero.
- "We want containers" as the only requirement. That's ACI or Container Apps.
- You plan to run one cluster per application. Cluster sprawl is where AKS costs go to die — every cluster carries its own system pool, its own upgrade cadence, and its own add-on surface.
- Stateful data you could rent instead. Running PostgreSQL in-cluster to avoid a managed database is a trade you almost always lose: you've taken on backup, failover, and patching to save a line item.
What this topic covers
| Sub-topic | What it covers |
|---|---|
| What & Why | The problem AKS solves, the managed-control-plane bargain, the compute-catalogue decision, the EKS analogue and where it breaks, and the honest anti-patterns |
| Core Concepts | Clusters, node pools, the node resource group, tiers, Kubernetes objects, networking models, identity types, add-ons, and the vocabulary traps |
| Architecture | What happens when you kubectl apply, control plane vs. data plane vs. Kubernetes RBAC, the CNI data path, scheduling and autoscaling loops, upgrades, and the failure modes |
| Getting Started | One small cluster, three ways — portal, az CLI, minimal Terraform — deploy a pod, reach it, then tear the whole thing down |
| Deployment | A parameterised Terraform module, remote state, an Ansible playbook for day-2 work, the Bicep equivalent, OIDC CI/CD, GitOps, environments, rollback, and drift |
| Integrations | ACR, Key Vault, Azure Monitor, Application Gateway and App Routing, Entra Workload ID, storage CSI drivers, and the glue that connects them |
| Production | Security, cost, scaling and quota scopes, observability, and reliability — including the upgrade discipline that dominates AKS operations |
| Interview Questions | Three tiers with answer keys, from "what is a node pool" to "the cluster upgraded and half the pods never came back" |
| Glossary & Cheatsheet | Every term in one line, the az aks and kubectl commands you'll actually type, the resource ID shape, and the limits worth knowing |
Three ideas worth carrying into every other page
There are two resource groups, and you only made one. You create the cluster in rg-platform;
AKS creates MC_rg-platform_aks-prod_uksouth and puts the scale sets, disks, load balancer, and
public IPs in it. That group is AKS-owned: don't rename it, don't apply a CanNotDelete lock to
it (it will break upgrades and scaling in confusing ways), and don't hand-edit resources inside it,
because the cluster's reconciler will fight you. Almost every "where did my node go" and "why can't
Terraform delete this" question in AKS traces back to this group.
Three authorization systems stack, and people conflate them. Azure RBAC on the
managedClusters resource decides who can get credentials and change the cluster's shape.
Kubernetes RBAC inside the cluster decides who can do anything with the API server. Entra ID
decides who you are. Being subscription Owner does not, by itself, let you kubectl get pods on
a cluster with local accounts disabled and Entra integration on — and that's the correct, desirable
behaviour. Architecture untangles this properly.
Kubernetes' abstraction leaks straight into your Azure bill. A Service of type
LoadBalancer provisions an Azure public IP and a load-balancer rule. A PersistentVolumeClaim
provisions a managed disk that survives the pod, and — depending on the storage class reclaim
policy — sometimes survives the PVC. An Ingress with App Routing provisions an NGINX deployment
and another IP. You are writing YAML that creates ARM resources; the bill will remind you.
Reading paths
New to Kubernetes on Azure — What & Why → Core Concepts → Getting Started. Build a cluster, deploy one pod, delete it, then read Architecture.
Coming from EKS — skim What & Why, then go to Core Concepts for node pools and the node resource group, and Architecture for the three-layer authorization model, which has no clean EKS equivalent.
Need to ship this quarter — Deployment, then Production. Getting Started is deliberately throwaway; do not grow it into a platform.
Interview or certification prep — Core Concepts, Architecture, and Interview Questions. The networking-model question and the "control plane vs. data plane vs. Kubernetes RBAC" question come up constantly.
Chasing a cost surprise — the cost section of Production, then the autoscaling discussion in Architecture. Oversized system pools, orphaned disks from deleted PVCs, and clusters nobody has scaled down since a load test are the usual culprits.
Next: What & Why →