Ensure Node Auto-Repair Is Enabled For Gke Nodes
More Info:
Nodes In A Degraded State Are An Unknown Quantity And So May Pose A Security Risk
Risk Level
Medium
Address
Security
Compliance Standards
- CIS GKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
List all node pools and identify those without auto-repair
- Run on: any machine with
gcloudconfigured and access to the project.
gcloud container node-pools list \--cluster CLUSTER_NAME \--location LOCATION \--project PROJECT_IDFor each
NODE_POOL_NAMEin the output, gather its management settings:gcloud container node-pools describe NODE_POOL_NAME \--cluster CLUSTER_NAME \--location LOCATION \--project PROJECT_ID \--format json | jq '.name, .management'Record which pools have
"autoRepair": falseor missing. - Run on: any machine with
-
Review workload criticality and disruption tolerance per node pool
- For each node pool with auto-repair disabled, determine what runs on it (e.g., critical system workloads, stateful apps, batch jobs) and the tolerance for node reboots or replacement.
- If the pool hosts critical, always-on, or security-sensitive workloads, plan to enable auto-repair unless there is a strong operational reason not to.
-
Check for alternative health and repair mechanisms if you decide not to enable auto-repair
- Confirm whether there are other processes that detect and remediate unhealthy nodes (e.g., external automation, strict SLOs, manual rotation).
- If such mechanisms are weak, undocumented, or slow, favor enabling auto-repair to reduce the risk of long-lived degraded nodes.
-
Plan maintenance window and communication for enabling auto-repair
- Enabling auto-repair can trigger node recreation when nodes are deemed unhealthy, which may cause pod rescheduling and brief interruptions.
- Ensure pod disruption budgets, readiness/liveness probes, and multi-zone/replicated deployments are in place so workloads tolerate node replacement.
-
Enable node auto-repair on selected node pools
- Run on: any machine with
gcloudconfigured and access to the project. - For each node pool you decide should have auto-repair:
gcloud container node-pools update NODE_POOL_NAME \--cluster CLUSTER_NAME \--location LOCATION \--project PROJECT_ID \--enable-autorepair - Run on: any machine with
-
Verify auto-repair is enabled for the intended node pools
- Re-run for each updated node pool:
gcloud container node-pools describe NODE_POOL_NAME \--cluster CLUSTER_NAME \--location LOCATION \--project PROJECT_ID \--format json | jq '.management'- Confirm
"autoRepair": trueis present for all node pools where you decided to enforce auto-repair, and document any remaining exceptions with justification.
Using kubectl
kubectl cannot enable or configure GKE node auto-repair because it is a managed control-plane / cloud provider setting applied at the node pool level, not a Kubernetes API object. To remediate this finding, make the change via the GCP console, gcloud CLI, or your IaC as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Report GKE node auto-repair status for all node pools in all clusters
# in the current gcloud project.
#
# Requirements:
# - gcloud CLI authenticated and configured with a project
# - jq installed
#
# Run on: any machine with gcloud and jq installed and access to the project.
set -euo pipefail
PROJECT_ID="$(gcloud config get-value project 2>/dev/null || true)"
if [[ -z "${PROJECT_ID}" ]]; then
echo "ERROR: No active gcloud project configured. Run:"
echo " gcloud config set project YOUR_PROJECT_ID"
exit 1
fi
echo "Using project: ${PROJECT_ID}"
echo
# List all GKE clusters (both zonal and regional)
CLUSTERS_JSON="$(gcloud container clusters list --project "${PROJECT_ID}" --format=json)"
if [[ "$(echo "${CLUSTERS_JSON}" | jq 'length')" -eq 0 ]]; then
echo "No GKE clusters found in project ${PROJECT_ID}."
exit 0
fi
# Header
printf "%-40s %-20s %-40s %-15s %-15s\n" \
"CLUSTER" "LOCATION" "NODE_POOL" "AUTO-REPAIR" "AUTO-UPGRADE"
printf "%0.s-" {1..140}
echo
# Iterate through clusters and their node pools
echo "${CLUSTERS_JSON}" | jq -r '.[] | @base64' | while read -r cluster_b64; do
_jq() {
echo "${cluster_b64}" | base64 --decode | jq -r "${1}"
}
CLUSTER_NAME="$(_jq '.name')"
LOCATION="$(_jq '.location')"
# Get all node pools for this cluster
NPS_JSON="$(gcloud container node-pools list \
--cluster "${CLUSTER_NAME}" \
--location "${LOCATION}" \
--project "${PROJECT_ID}" \
--format=json)"
if [[ "$(echo "${NPS_JSON}" | jq 'length')" -eq 0 ]]; then
printf "%-40s %-20s %-40s %-15s %-15s\n" \
"${CLUSTER_NAME}" "${LOCATION}" "<no node pools>" "N/A" "N/A"
continue
fi
echo "${NPS_JSON}" | jq -r '.[] | @base64' | while read -r np_b64; do
_np_jq() {
echo "${np_b64}" | base64 --decode | jq -r "${1}"
}
NP_NAME="$(_np_jq '.name')"
MGMT_JSON="$(_np_jq '.management')"
AUTO_REPAIR="$(echo "${MGMT_JSON}" | jq -r '.autoRepair // "false"')"
AUTO_UPGRADE="$(echo "${MGMT_JSON}" | jq -r '.autoUpgrade // "false"')"
printf "%-40s %-20s %-40s %-15s %-15s\n" \
"${CLUSTER_NAME}" "${LOCATION}" "${NP_NAME}" "${AUTO_REPAIR}" "${AUTO_UPGRADE}"
done
done
cat <<'EOF'
Interpretation:
- For CIS GKE 5.5.2, node pools where AUTO-REPAIR == "false" (or missing)
are problematic and should be reviewed.
- Expected/healthy state for compliance: AUTO-REPAIR == "true" for all
security-sensitive or production node pools.
Use this script's output to identify node pools that need manual review and
a policy decision on enabling auto-repair. Do not assume auto-repair can be
blindly enabled everywhere without considering workload and maintenance
requirements.
EOF