Skip to main content

Ensure Use Of VPC-Native Clusters

More Info:

Use VPC-native clusters (alias IP) so pod and service IPs are native VPC addresses, enabling better network integration and firewalling. Route-based clusters are less secure and scalable.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Manual Steps
  1. Identify whether the cluster is VPC‑native and document current state

    • On any machine with gcloud and project access, run:
      PROJECT_ID="<your-project-id>"
      LOCATION="<your-cluster-location>"
      CLUSTER_NAME="<your-cluster-name>"

      gcloud container clusters describe "$CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --format json | jq '.ipAllocationPolicy'
    • Confirm whether .useIpAliases is true. If it is true, this control is satisfied for this cluster; record that result. If false or null, proceed.
  2. Assess business/technical requirements and compatibility for migration

    • Review whether any workloads rely on node IPs or legacy routing (e.g., custom routes, firewalls keyed to node IPs, non‑GCP VPN/peering relying on current pod CIDRs).
    • Document required CIDR ranges for pods/services and overlap risks with existing VPCs, VPNs, and peered networks.
  3. Design a VPC‑native cluster configuration

    • On a planning workstation, draft the target settings (example):
      POD_RANGE="10.16.0.0/14"
      SVC_RANGE="10.20.0.0/20"
    • Ensure these ranges do not overlap with any existing on‑prem, VPC, or peered CIDRs.
    • Decide whether you will recreate the cluster manually, via scripts, or via IaC (Terraform, Deployment Manager, etc.), and record that as the approved migration plan.
  4. Create a new VPC‑native (Alias IP) cluster according to your plan

    • When ready to migrate, create a replacement cluster with Alias IP enabled (on any machine with gcloud):
      PROJECT_ID="<your-project-id>"
      LOCATION="<new-cluster-location>"
      NEW_CLUSTER_NAME="<new-cluster-name>"
      POD_RANGE="<non-overlapping-pod-cidr>"
      SVC_RANGE="<non-overlapping-service-cidr>"

      gcloud container clusters create "$NEW_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --enable-ip-alias \
      --cluster-ipv4-cidr="$POD_RANGE" \
      --services-ipv4-cidr="$SVC_RANGE"
    • If you use IaC, encode equivalent settings there instead of running the CLI directly, and have them reviewed/approved.
  5. Migrate workloads and traffic to the VPC‑native cluster

    • Point kubectl to the new cluster:
      gcloud container clusters get-credentials "$NEW_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID"
    • Recreate namespaces, RBAC, ConfigMaps, Secrets, Deployments, Services, Ingress, and other resources from source control or exported manifests.
    • Update DNS, load balancer configs, and any external dependencies to direct traffic to the new cluster’s endpoints. Perform validation tests before decommissioning the old cluster.
  6. Verify and formally close the finding

    • On any machine with gcloud, confirm the new cluster is VPC‑native:
      gcloud container clusters describe "$NEW_CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID" \
      --format json | jq '.ipAllocationPolicy.useIpAliases'
    • Ensure it returns true.
    • Once the old (route‑based) cluster is no longer needed, delete it:
      gcloud container clusters delete "$CLUSTER_NAME" \
      --location "$LOCATION" \
      --project "$PROJECT_ID"
    • Update your documentation and risk register to reflect that all active clusters are now VPC‑native.
Using kubectl

This setting is part of the GKE control plane / cluster configuration and cannot be changed with kubectl, which only manages Kubernetes API objects. To address this finding, use the Google Cloud console, gcloud CLI, or your IaC as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Check GKE clusters for VPC-native (Alias IP) usage.
# Requires: gcloud, jq
#
# Run on: any machine with gcloud configured and access to the target projects.

set -euo pipefail

# Optional: limit to specific projects by setting PROJECT_IDS="proj1 proj2"
PROJECT_IDS="${PROJECT_IDS:-}"

if [[ -z "${PROJECT_IDS}" ]]; then
echo "Discovering all active projects in the current account..." >&2
PROJECT_IDS=$(gcloud projects list --format="value(projectId)")
fi

printf "project,location,cluster,useIpAliases\n"

for PROJECT in ${PROJECT_IDS}; do
# Get all clusters in all locations for this project
mapfile -t CLUSTERS < <(
gcloud container clusters list \
--project "${PROJECT}" \
--format="value(name,location)" 2>/dev/null || true
)

if [[ ${#CLUSTERS[@]} -eq 0 ]]; then
continue
fi

for ENTRY in "${CLUSTERS[@]}"; do
NAME=$(awk '{print $1}' <<< "${ENTRY}")
LOCATION=$(awk '{print $2}' <<< "${ENTRY}")

# Fetch ipAllocationPolicy.useIpAliases
USE_IP_ALIASES=$(
gcloud container clusters describe "${NAME}" \
--location "${LOCATION}" \
--project "${PROJECT}" \
--format="json" 2>/dev/null \
| jq -r '.ipAllocationPolicy.useIpAliases // "unknown"' \
|| echo "error"
)

printf "%s,%s,%s,%s\n" "${PROJECT}" "${LOCATION}" "${NAME}" "${USE_IP_ALIASES}"
done
done

How to use

Run on any machine with gcloud and jq:

chmod +x check-gke-vpc-native.sh
./check-gke-vpc-native.sh > gke-vpc-native-report.csv

Interpreting results

  • useIpAliases=true → cluster is VPC-native (Alias IP) and aligned with the control.
  • useIpAliases=false → cluster is not VPC-native and is a finding to review.
  • unknown or error → unable to determine; investigate that cluster manually with:
gcloud container clusters describe CLUSTER_NAME \
--location LOCATION \
--project PROJECT_ID \
--format json | jq '.ipAllocationPolicy'