Secure Your GKE Control Plane: Migrating from IP-Based Authorized Networks to IAM-Based DNS Endpoint Access
The GKE DNS-based endpoint provides a cluster-unique FQDN (Fully Qualified Domain Name) for the Kubernetes control plane, allowing for simplified, IAM-based access control instead of relying on static IP-based authorized networks. This guide outlines the steps to enable this feature and transition your access methods.
The DNS-Based Endpoint offers several advantages over the IP-Based Endpoint with Authorized Networks for accessing Google Cloud clusters. While IP-based access relies on source IP CIDR blocks and often requires bastion hosts or VPN for private clusters, the DNS-based approach uses Google Cloud IAM and is accessible from any network that can reach Google Cloud APIs. This provides a more flexible and dynamic access control model, integrated with IAM and VPC Service Controls for enhanced security, compared to the primarily network-layer security of IP-based endpoints.
This guide walks through the steps to enable the DNS endpoint on an existing GKE cluster and migrate the access to it. We'll use a GKE cluster named gke-test-cluster-1, deployed in the GCP Finland region, zone europe-north1-a.
Step 1: Enable the DNS-Based Endpoint
You can enable the DNS-based endpoint on an existing GKE Standard or Autopilot cluster using the gcloud CLI.
First, let's review the GKE Control Plane configuration:
gcloud container clusters describe gke-test-cluster-1 \ --zone europe-north1-a --format="yaml(controlPlaneEndpointsConfig)" The output should look like this:
controlPlaneEndpointsConfig: dnsEndpointConfig: allowExternalTraffic: false enableK8sCertsViaDns: false enableK8sTokensViaDns: false endpoint: gke-CLUSTER_ID-PROJECT.europe-north1-a.gke.goog ipEndpointsConfig: authorizedNetworksConfig: cidrBlocks: - cidrBlock: ALLOWED_IP_ADDR displayName: office-network enabled: true gcpPublicCidrsAccessEnabled: true enablePublicEndpoint: true enabled: true privateEndpoint: PRV_IP_ADDR publicEndpoint: PUB_IP_ADDR This is the current GKE Control Plane configuration. The IP-based Endpoint is enabled for both Public and Private IPs and Authorized Network is also enabled allowing "office-network" IP addresses.
The GKE DNS Endpoint FQDN follows this format:
gke-CLUSTER_ID-PROJECT.europe-north1-a.gke.goog
However, it is currently disabled.
So let's update the cluster to enable DNS-based access.
gcloud container clusters update gke-test-cluster-1 \ --zone europe-north1-a --enable-dns-access It may take a few minutes for the GKE Control Plane to update with DNS Endpoint.
Once the operation is completed, you can run gcloud container clusters describe command again and should see allowExternalTraffic is enabled for dnsEndpointConfig .
Now, both IP-based and DNS-based endpoints are enabled. Both coexist at this point while we work on the next steps migrating the access from IP-based to DNS-based.
Step 2: Configure IAM Access
Access to the DNS endpoint is controlled by IAM. The specific IAM permission required for DNS-based access is container.clusters.connect
The permission container.clusters.connect is included in many predefined IAM roles such as "Kubernetes Engine Admin" and "Kubernetes Engine Developer". It's most likely your IAM user already has the permission through existing IAM roles, otherwise you were not able to update the GKE cluster in the previous step.
For other users however, your fellow developers, CI/CD pipelines and such might use other IAM roles or custom roles. In this case you need to update those roles to include the IAM permission.
As an example here if you need to add another GKE admin user, you can grant the IAM role as follow:
gcloud projects add-iam-policy-binding $PROJECT \ --member="user:$GKE_ADMIN" --role="roles/container.admin" Step 3: Test and Migrate Client Access
Now that the GKE Control Plane DNS Endpoint is enabled and IAM roles are configured, it's time to update clients to use the FQDN.
To make use of the DNS Endpoint in kubectl you need to refresh the kubeconfig file by fetching the new GKE cluster's credentials:
gcloud container clusters get-credentials gke-test-cluster-1 \ --zone europe-north1-a --dns-endpoint Take note of the --dns-endpoint parameter. This updates the kubeconfig and replaces the configuration for accessing your GKE Control Plane using FQDN instead of public IP address.
You can view the kubeconfig configuration using command:
kubectl config view --minify Output: apiVersion: v1 clusters: - cluster: server: https://gke-CLUSTER_ID-PROJECT.europe-north1-a.gke.goog name: gke_PROJECT_europe-north1-a_gke-test-cluster-1 Now, run your favourite kubectl command as usual like kubectl get namespaces. If the command executed successfully it means our setup now works correctly.
Once you verified it's working, it's time to update all your CI/CD tools, pipelines to include --dns-endpoint parameter when fetching GKE cluster credentials, and inform your fellow GKE admins and developers to refresh their GKE cluster credentials.
Step 4: Disable IP-Based Authorized Networks
After you have successfully migrated all clients to using DNS Endpoint you can safely remove the IP-based authorized network along with the IP-based Endpoint. This helps keep your GKE clusters configuration clean.
There are 2 options here:
- Disabling the Public IP Endpoint which removes the Public IP address from your GKE Control Plane.
- Disable IP-based Endpoint completely which removes both Public and Private IP Endpoint. If you still have some other dependency on the Private IP Endpoint, you can just remove the Public IP Endpoint which improves your Control Plane security by not exposing it directly to the public.
Please note that the DNS Endpoint also works from your VPC.
Nonetheless to disable the Public IP Endpoint while keeping the Private IP Endpoint you can update the GKE cluster as follow:
gcloud container clusters update gke-test-cluster-1 \ --zone europe-north1-a --enable-private-endpoint To disable IP-based Endpoint completely you can disable both Public IP and Private IP Endpoints as follow:
gcloud container clusters update gke-test-cluster-1 \ --zone europe-north1-a --no-enable-ip-access Your GKE Control Plane Endpoint config will look like this after the clean up.
controlPlaneEndpointsConfig: dnsEndpointConfig: allowExternalTraffic: true enableK8sCertsViaDns: false enableK8sTokensViaDns: false endpoint: gke-CLUSTER_ID-PROJECT.europe-north1-a.gke.goog ipEndpointsConfig: enabled: false With GKE Control Plane access now managed by IAM, you can use VPC Service Controls to add Context-Aware Access and further secure your GKE clusters.