Setting the file. One moment.
AKS Baseline · Azure Diagnostics · microsoft/azure-skills · Skills Docs
ContentsBack to the top of the page ·
scripts/aks-baseline.sh
scripts/ aks-baseline.sh
Shell · 159 lines · 7 KB
14
# All steps are READ-ONLY. Each step is guarded so a single failure (for example,
15 # kubectl not authenticated) prints a note and the sweep continues.
16 #
17 # Usage:
18 # ./aks-baseline.sh -g <resource-group> -n <cluster> [--namespace <ns>] [--subscription <id>]
19 #
20 # Examples:
21 # ./aks-baseline.sh -g my-rg -n my-cluster
22 # ./aks-baseline.sh -g my-rg -n my-cluster --namespace payments
23
24 set -uo pipefail
25
26 RESOURCE_GROUP = ""
27 CLUSTER = ""
28 NAMESPACE = ""
29 SUBSCRIPTION = ""
30
31 usage () {
32 echo "Usage: $0 -g <resource-group> -n <cluster> [--namespace <ns>] [--subscription <id>]" >&2
33 exit " ${1 :- 1} "
34 }
35
36 require_value () {
37 # require_value <option-name> <remaining-arg-count>
38 if [ " $2 " -lt 2 ]; then
39 echo "Missing value for $1 " >&2
40 usage 1
41 fi
42 }
43
44 while [ $# -gt 0 ]; do
45 case " $1 " in
46 -g | --resource-group ) require_value " $1 " " $# " ; RESOURCE_GROUP = " $2 " ; shift 2 ;;
47 -n | --cluster ) require_value " $1 " " $# " ; CLUSTER = " $2 " ; shift 2 ;;
48 --namespace ) require_value " $1 " " $# " ; NAMESPACE = " $2 " ; shift 2 ;;
49 --subscription ) require_value " $1 " " $# " ; SUBSCRIPTION = " $2 " ; shift 2 ;;
50 -h | --help ) usage 0 ;;
51 *) echo "Unknown argument: $1 " >&2 ; usage 1 ;;
52 esac
53 done
54
55 [ -z " $RESOURCE_GROUP " ] && { echo "Missing required -g/--resource-group" >&2 ; usage 1 ; }
56 [ -z " $CLUSTER " ] && { echo "Missing required -n/--cluster" >&2 ; usage 1 ; }
57
58 AZ_SUB_ARGS = ()
59 [ -n " $SUBSCRIPTION " ] && AZ_SUB_ARGS = ( --subscription " $SUBSCRIPTION " )
60
61 section () {
62 echo ""
63 echo "=============================================================="
64 echo "== $1 "
65 echo "=============================================================="
66 }
67
68 run () {
69 # run "<description>" <command...>
70 local desc = " $1 " ; shift
71 if ! " $@ " ; then
72 echo " [!] Could not gather: $desc (command failed or unavailable)"
73 fi
74 }
75
76 echo "AKS baseline diagnostic sweep (read-only)"
77 echo "Resource group: $RESOURCE_GROUP "
78 echo "Cluster: $CLUSTER "
79 [ -n " $NAMESPACE " ] && echo "Namespace: $NAMESPACE "
80
81 # 1. Cluster provisioning state ------------------------------------------------
82 section "1. Cluster provisioning state"
83 run "cluster provisioning state" \
84 az aks show -g " $RESOURCE_GROUP " -n " $CLUSTER " ${AZ_SUB_ARGS[ @ ]+ "${ AZ_SUB_ARGS [ @ ]}" } \
85 --query "{name:name, provisioningState:provisioningState, powerState:powerState.code, k8sVersion:currentKubernetesVersion, fqdn:fqdn}" \
86 -o table
87
88 # 2. Node pool summary ---------------------------------------------------------
89 section "2. Node pool summary"
90 run "node pool summary" \
91 az aks nodepool list -g " $RESOURCE_GROUP " --cluster-name " $CLUSTER " ${AZ_SUB_ARGS[ @ ]+ "${ AZ_SUB_ARGS [ @ ]}" } \
92 --query "[].{name:name, mode:mode, count:count, vmSize:vmSize, state:provisioningState, powerState:powerState.code, k8sVersion:orchestratorVersion}" \
93 -o table
94
95 # 3. Recent Azure activity -----------------------------------------------------
96 section "3. Recent Azure activity (last 20 events)"
97 run "recent activity log" \
98 az monitor activity-log list -g " $RESOURCE_GROUP " ${AZ_SUB_ARGS[ @ ]+ "${ AZ_SUB_ARGS [ @ ]}" } \
99 --max-events 20 \
100 --query "[].{time:eventTimestamp, operation:operationName.value, status:status.value, resource:resourceId}" \
101 -o table
102
103 # 4. Node readiness ------------------------------------------------------------
104 section "4. Node readiness"
105 run "node readiness" kubectl get nodes -o wide
106
107 # 5. Unhealthy pods ------------------------------------------------------------
108 # Filter on the READY and STATUS columns (not just pod phase) so container-level
109 # failures such as CrashLoopBackOff / ImagePullBackOff — which stay in phase
110 # "Running" — are caught. Terminal pods (Completed/Succeeded) are excluded so
111 # finished jobs are not falsely flagged.
112 section "5. Unhealthy pods (CrashLoopBackOff, not Ready, restarting, or bad status)"
113 ALL_PODS = "$( kubectl get pods -A -o wide 2> /dev/null)"
114 if [ -z " $ALL_PODS " ]; then
115 echo " No pods reported (or cluster unreachable)."
116 else
117 UNHEALTHY = "$( printf '%s\n' " $ALL_PODS " | awk 'NR>1 {
118 split($3, ready, "/");
119 status = $4;
120 restarts = $5 + 0;
121 terminalOk = (status == "Completed" || status == "Succeeded");
122 notReady = (status == "Running" && ready[1] != ready[2]);
123 badStatus = (status != "Running" && !terminalOk);
124 highRestarts = (!terminalOk && restarts >= 5);
125 if (notReady || badStatus || highRestarts) print
126 }')"
127 if [ -n " $UNHEALTHY " ]; then
128 printf '%s\n' " $ALL_PODS " | head -n 1
129 printf '%s\n' " $UNHEALTHY "
130 else
131 echo " All pods are Running/Succeeded and Ready with low restart counts."
132 fi
133 fi
134
135 # 6. kube-system health --------------------------------------------------------
136 section "6. kube-system health"
137 run "kube-system pods" kubectl get pods -n kube-system -o wide
138
139 # 7. Recent warning events -----------------------------------------------------
140 section "7. Recent warning events (last 40, sorted by time)"
141 run "warning events" bash -c \
142 "set -o pipefail; kubectl get events -A --field-selector=type=Warning --sort-by=.lastTimestamp 2>/dev/null | tail -n 40"
143
144 # 8. Namespace pod overview (optional) ----------------------------------------
145 if [ -n " $NAMESPACE " ]; then
146 section "8. Pods in namespace ' $NAMESPACE '"
147 run "pods in namespace $NAMESPACE " kubectl get pods -n " $NAMESPACE " -o wide
148 fi
149
150 # Summary ----------------------------------------------------------------------
151 section "Summary"
152 echo "Gathered the read-only AKS baseline for cluster ' $CLUSTER ' in resource group"
153 echo "' $RESOURCE_GROUP ': Azure-side cluster/node-pool state and recent activity, then"
154 echo "Kubernetes-side node readiness, unhealthy pods, kube-system health, and recent"
155 echo "warning events. Review the sections above for anomalies (non-Succeeded"
156 echo "provisioning state, NotReady nodes, unhealthy or restarting pods, warning events)"
157 echo "before deep-diving with 'kubectl describe' / 'kubectl logs' on a specific pod."
158 echo ""
159 echo "No changes were made to any resource."