Stage 5 · Platform
Compute & Containers
AKS Cluster Architecture
Node pools, system pools, kubelet identity, and cluster autoscaler.
What Is AKS?
Azure Kubernetes Service (AKS) is a managed Kubernetes control plane. Microsoft manages the Kubernetes API server, scheduler, and etcd — you only manage the worker nodes (and even those can be auto-managed with Node Auto-Provisioning).
# Create a production AKS cluster
az aks create \
--resource-group rg-aks-prod \
--name aks-payments-prod \
--node-count 3 \
--node-vm-size Standard_D4s_v3 \
--network-plugin azure \
--network-policy calico \
--enable-managed-identity \
--generate-ssh-keys \
--tags Environment=production Team=paymentsThe --network-plugin azure flag uses Azure CNI, which assigns each pod a VNet IP. This is required for most enterprise networking scenarios.
Control Plane
The AKS control plane is fully managed by Azure. You receive a Kubernetes API server endpoint and an etcd cluster. The control plane is free for the Basic SKU — the Premium SKU adds a 99.95% SLA and private cluster support.
# Merge cluster credentials into local kubeconfig
az aks get-credentials \
--resource-group rg-aks-prod \
--name aks-payments-prod \
--overwrite-existing
# Verify connection
kubectl cluster-info
kubectl get nodesaz aks get-credentials merges the cluster context into ~/.kube/config. Use --overwrite-existing to replace any existing context with the same cluster name.
For clusters with Azure AD integration, install kubelogin (az aks install-cli). It handles the OAuth2 token flow for kubectl authentication.
Node Pools
A node pool is a group of VMs with the same configuration (size, OS, labels, taints). AKS clusters have at least one node pool. You can add additional node pools for different workload types.
# Add a node pool for memory-intensive workloads
az aks nodepool add \
--resource-group rg-aks-prod \
--cluster-name aks-payments-prod \
--name pool-memory \
--node-count 2 \
--node-vm-size Standard_E8s_v3 \
--mode User \
--labels workload=memory \
--taints workload=memory:NoSchedule
# List all node pools
az aks nodepool list \
--resource-group rg-aks-prod \
--cluster-name aks-payments-prod \
--query "[].{name:name, mode:mode, size:vmSize, count:count}" \
--output tableNode pools with --mode System are part of the default system pool and cannot be deleted until the cluster is deleted. User pools can be freely added and removed.
System vs User Pools
| Feature | System Pool | User Pool |
|---|---|---|
| Required | Yes (minimum 1) | No (optional) |
| Can delete independently | No | Yes |
| Workload scheduling | Can schedule workloads | Dedicated to workloads |
| Upgrade behavior | Upgraded first | Upgraded after system pool |
| Autoscaler | Recommended off | Recommended on |
System pools run cluster-critical components (CoreDNS, metrics-server). Scheduling production workloads here risks resource contention and upgrade failures.
Cluster Autoscaler
The cluster autoscaler automatically adjusts the number of nodes in a pool based on pending pods and node utilization. It scales down when nodes are underutilized for more than 10 minutes.
# Create a node pool with autoscaler
az aks nodepool add \
--resource-group rg-aks-prod \
--cluster-name aks-payments-prod \
--name pool-app \
--node-count 2 \
--node-vm-size Standard_D4s_v3 \
--mode User \
--enable-cluster-autoscaler \
--min-count 2 \
--max-count 10
# Update autoscaler settings
az aks nodepool update \
--resource-group rg-aks-prod \
--cluster-name aks-payments-prod \
--name pool-app \
--update-cluster-autoscaler \
--min-count 1 \
--max-count 20The autoscaler checks every 10 seconds for unschedulable pods and 5 minutes for underutilized nodes. Scale-down happens after 10 minutes of low utilization.
Cluster Identity
AKS clusters need an identity to manage Azure resources (load balancers, managed disks, ACR pull). The kubelet identity (node identity) is used for ACR authentication and disk management.
# Get the kubelet identity
az aks show \
--resource-group rg-aks-prod \
--name aks-payments-prod \
--query "identityProfile.kubeletidentity.objectId" --output tsv
# Assign AcrPull role to the kubelet identity
KUBELET_ID=$(az aks show \
--resource-group rg-aks-prod \
--name aks-payments-prod \
--query "identityProfile.kubeletidentity.objectId" --output tsv)
az role assignment create \
--assignee-object-id "$KUBELET_ID" \
--role "AcrPull" \
--scope "/subscriptions/{sub-id}/resourceGroups/rg-aks-prod/providers/Microsoft.ContainerRegistry/registries/craksprodeastus"The kubelet identity is automatically created when you use --enable-managed-identity. It must be assigned AcrPull to pull images from ACR without admin credentials.
# Alternatively, use the built-in ACR integration
az aks update \
--resource-group rg-aks-prod \
--name aks-payments-prod \
--attach-acr craksprodeastus
# Verify ACR access from a pod
kubectl run test --image=craksprodeastus.azurecr.io/myapp:v1 --rm -it --restart=Never -- echo "Image pulled successfully"The --attach-acr flag automatically assigns the AcrPull role to the kubelet identity. This is simpler than manual role assignment.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.