Access
az aks get-credentials -g rg-aks -n aks-prod --overwrite-existing
kubelogin convert-kubeconfig -l azurecli # Entra ID-enabled clusters
kubectl config get-contexts
kubectl auth can-i '*' '*' --all-namespaces # what am I allowed to do?
Cluster and node health
kubectl get nodes -o wide
kubectl top nodes
kubectl describe node <node> | sed -n '/Conditions/,/Addresses/p' # MemoryPressure, DiskPressure...
kubectl get events -A --sort-by=.lastTimestamp | tail -30
az aks show -g rg-aks -n aks-prod --query "{k8s:kubernetesVersion, state:provisioningState, power:powerState.code}" -o table
Pod triage
kubectl get pods -A --field-selector=status.phase!=Running
kubectl describe pod <pod> -n <ns> # read Events at the bottom first
kubectl logs <pod> -n <ns> --previous # logs of the last crashed container
kubectl get pod <pod> -n <ns> -o jsonpath='{.status.containerStatuses[*].lastState}'
kubectl debug -it <pod> -n <ns> --image=busybox --target=<container>
| Status | Usually means |
|---|---|
Pending | No node has the CPU/memory, or a taint/affinity rule blocks scheduling. Check the events and the cluster autoscaler. |
ImagePullBackOff | Wrong tag, or the kubelet identity can't pull from ACR. Run az aks check-acr. |
CrashLoopBackOff | The app exits on start. Check the --previous logs, config and secrets. |
OOMKilled | Container memory limit too low, or a memory leak. |
Node pools and scaling
az aks nodepool list -g rg-aks --cluster-name aks-prod -o table
az aks nodepool scale -g rg-aks --cluster-name aks-prod -n user1 --node-count 5
az aks nodepool update -g rg-aks --cluster-name aks-prod -n user1 \
--enable-cluster-autoscaler --min-count 2 --max-count 10
az aks nodepool add -g rg-aks --cluster-name aks-prod -n spot1 \
--priority Spot --eviction-policy Delete --spot-max-price -1 --node-count 1
Upgrades
az aks get-upgrades -g rg-aks -n aks-prod -o table
# Node OS image only (security patches, no Kubernetes version change)
az aks nodepool upgrade -g rg-aks --cluster-name aks-prod -n user1 --node-image-only
# Control plane, then each pool
az aks upgrade -g rg-aks -n aks-prod --control-plane-only --kubernetes-version 1.31.2
az aks nodepool upgrade -g rg-aks --cluster-name aks-prod -n user1 --kubernetes-version 1.31.2 --max-surge 33%
Important
Before upgrading, make sure every critical workload has a PodDisruptionBudget and more than one replica. If a PDB allows 0 disruptions, the node drain blocks and the upgrade stalls.
Maintenance on a single node
kubectl cordon <node>
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --timeout=10m
# ...patch / investigate...
kubectl uncordon <node>
Useful one-liners
# Pods per node
kubectl get pods -A -o wide --no-headers | awk '{print $8}' | sort | uniq -c | sort -rn
# Top memory pods
kubectl top pods -A --sort-by=memory | head -15
# Restart a deployment (rolling)
kubectl rollout restart deploy/<name> -n <ns> && kubectl rollout status deploy/<name> -n <ns>