Authenticating to the Kubernetes API server

This page describes the supported authentication methods when connecting to the Kubernetes API server in Google Kubernetes Engine (GKE).

For information on authenticating Kubernetes workloads to Google Cloud APIs, see Workload Identity instead.

Overview

There are several methods for authenticating to a Kubernetes API server. In GKE, OAuth authentication is recommended for cluster authentication and is automatically configured for you.

Before you begin

Before you start, make sure you have performed the following tasks:

  • Ensure that you have enabled the Google Kubernetes Engine API.
  • Enable Google Kubernetes Engine API
  • Ensure that you have installed the Cloud SDK.
  • Set up default gcloud command-line tool settings for your project by using one of the following methods:
    • Use gcloud init, if you want to be walked through setting project defaults.
    • Use gcloud config, to individually set your project ID, zone, and region.

    gcloud init

    1. Run gcloud init and follow the directions:

      gcloud init

      If you are using SSH on a remote server, use the --console-only flag to prevent the command from launching a browser:

      gcloud init --console-only
    2. Follow the instructions to authorize the gcloud tool to use your Google Cloud account.
    3. Create a new configuration or select an existing one.
    4. Choose a Google Cloud project.
    5. Choose a default Compute Engine zone.
    6. Choose a default Compute Engine region.

    gcloud config

    1. Set your default project ID:
      gcloud config set project PROJECT_ID
    2. Set your default Compute Engine region (for example, us-central1):
      gcloud config set compute/region COMPUTE_REGION
    3. Set your default Compute Engine zone (for example, us-central1-c):
      gcloud config set compute/zone COMPUTE_ZONE
    4. Update gcloud to the latest version:
      gcloud components update

    By setting default locations, you can avoid errors in gcloud tool like the following: One of [--zone, --region] must be supplied: Please specify location.

Authenticating users

GKE manages end-user authentication for you through the gcloud command-line tool. The gcloud tool authenticates users to Google Cloud, sets up the Kubernetes configuration, gets an OAuth access token for the cluster, and keeps the access token up-to-date. You can control access to your cluster using Identity and Access Management (IAM) or Kubernetes Role Based Access Control (RBAC).

Before OAuth integration with GKE, the pre-provisioned X.509 certificate or a static password were the only available authentication methods. These methods are no longer recommended and are disabled by default on new clusters that run GKE version 1.12 and later. If you use legacy authentication methods, we recommend that you migrate off these methods.

Authenticating using OAuth

To authenticate to your cluster using the OAuth method, perform the following:

  1. Sign in to the gcloud tool using your credentials. This opens a web browser to complete the authentication process to Google Cloud:

    gcloud auth login
    
  2. Retrieve the Kubernetes credentials for a specific cluster:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    
  3. Verify that you are authenticated:

    kubectl cluster-info
    

Authenticating services

Sometimes you might need to authenticate to a GKE cluster's API server from a service without user interaction (for example, a CI/CD pipeline script). How you achieve this depends on the environment where your service is running.

Service within the same GKE cluster

If your service is running in a Pod inside the GKE cluster you want to connect to, use a Kubernetes service account to authenticate.

  1. Create a Kubernetes service account and attach it to your Pod. If your Pod already has a Kubernetes service account, you may skip this step.

    In our example, we use a Kubernetes service account named cicd in the cicd-ns namespace.

  2. Use Kubernetes RBAC to grant the Kubernetes service account the correct permissions.

    The following example grants edit permissions in the prod namespace:

    kubectl create rolebinding cicd \
        --clusterrole=edit \
        --serviceaccount=cicd-ns:cicd \
        --namespace=prod
    
  3. At runtime, when your service invokes kubectl, it automatically receives the credentials you configured.

Service within Google Cloud

If your service runs inside Google Cloud (for example, a Compute Engine VM or another GKE cluster), you should authenticate to the API server using the Google service account credentials available in the environment.

  1. Assign a Google service account to your Compute Engine environment. If your service is running inside a Compute Engine VM, assign a Google service account to the instance. If your service is running inside a GKE cluster, use Workload Identity to configure your Pod to run as a Google service account.

    In our example, we use ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com as the Google service account.

  2. Grant the Google service account access to the cluster.

    In our example, we grant the roles/container.developer IAM role, which provides access to Kubernetes API objects inside clusters:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    
  3. Retrieve the cluster credentials:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

    Your service is automatically authenticated using the Google service account set on the environment.

Service in other environments

If your service is authenticating from an environment outside Google Cloud, it cannot access managed Google service account credentials. To retrieve cluster credentials, you must create a Google service account, download its key, and use the key at runtime from your service to retrieve cluster credentials with the gcloud tool.

  1. Create a Google service account for your service. If you already have a Google service account, you may skip this step.

    In our example, we create a service account named ci-cd-pipeline:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. Grant the Google service account access to your cluster.

    In our example, we use ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com as the Google service account, and we grant the roles/container.developer IAM role, which provides access to Kubernetes API objects inside clusters:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    You can also grant this access using Kubernetes RBAC for more fine-grained control.

  3. Create and download a key for your Google service account. Make it available to your service at runtime:

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. At runtime, in the environment running your service, authenticate to the gcloud tool by using your Google service account key:

    gcloud auth activate-service-account ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --key-file=gsa-key.json
    
  5. Use the gcloud tool to retrieve the cluster credentials:

    gcloud config set project PROJECT_ID
    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    

Environments without gcloud

Using the gcloud tool to retrieve cluster credentials is recommended because this method is resilient to cluster events like a control plane IP rotation or credential rotation. However, if you cannot install the gcloud tool in your environment, you can still create a static kubeconfig file to authenticate to the cluster:

  1. Create a Google service account for your service. If you already have a Google service account, you may skip this step.

    In our example, we create a service account named ci-cd-pipeline:

    gcloud iam service-accounts create ci-cd-pipeline
    
  2. Grant the Google service account access to your cluster.

    In our example, we use ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com as the Google service account, and we grant the roles/container.developer IAM role, which provides access to Kubernetes API objects inside clusters:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/container.developer
    

    You can also grant this access using Kubernetes RBAC for more fine-grained control.

  3. Create and download a key for your Google service account.

    In our example, the key file is named gsa-key.json:

    gcloud iam service-accounts keys create gsa-key.json \
        --iam-account=ci-cd-pipeline@PROJECT_ID.iam.gserviceaccount.com
    
  4. Get the endpoint and clusterCaCertificate values for your cluster:

    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
         --format="value(endpoint)"
    
    gcloud container clusters describe CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --format="value(masterAuth.clusterCaCertificate)"
    
  5. Create a kubeconfig.yaml file containing the following:

    apiVersion: v1
    kind: Config
    clusters:
    - name: CLUSTER_NAME
      cluster:
        server: https://endpoint
        certificate-authority-data: masterAuth.clusterCaCertificate
    users:
    - name: ci-cd-pipeline-gsa
      user:
        auth-provider:
          name: gcp
    contexts:
    - context:
        cluster: CLUSTER_NAME
        user: ci-cd-pipeline-gsa
      name: CLUSTER_NAME-ci-cd
    current-context: CLUSTER_NAME-ci-cd
    

    Replace the following:

    • CLUSTER_NAME: the name of your cluster.
    • endpoint: the value you obtained for endpoint from the previous step.
    • masterAuth.clusterCaCertificate: the value you obtained for clusterCaCertificate from the previous step (you don't need to decode the base64-encoded certificate).
  6. Deploy kubeconfig.yaml and gsa-key.json alongside your service in your environment. At runtime, in the environment running your service, set these environment variables:

    export KUBECONFIG=path/to/kubeconfig.yaml
    export GOOGLE_APPLICATION_CREDENTIALS=path/to/gsa-key.json
    
  7. Your service can now invoke kubectl and will be authenticated as the Google service account.

Legacy authentication methods

Before OAuth integration with GKE, the pre-provisioned X.509 certificate or a static password were the only available authentication methods, but are no longer recommended and should be disabled. These methods present a wider surface of attack for cluster compromise and are disabled by default on clusters running GKE version 1.12 and later. If you use legacy authentication methods, we recommend that you turn them off.

If enabled, a user with thecontainer.clusters.getCredentials permission can retrieve the client certificate and static password. The roles/container.admin, roles/owner, androles/editor roles all have this permission, so use those roles wisely. Read more about IAM roles in GKE.

Disabling authentication with a static password

A static password is a username and password combination that the API server validates. In GKE, this authentication method is referred to as basic authentication.

To update an existing cluster and remove the static password:

gcloud container clusters update CLUSTER_NAME --no-enable-basic-auth

Disabling authentication with a client certificate

With certificate authentication, a client presents a certificate that the API server verifies with the specified certificate authority. In GKE, the cluster root Certificate Authority (CA) signs client certificates.

Client certificate authentication has implications on authorization to the Kubernetes API server. If legacy Attribute Based Access Control (ABAC) authorization is enabled on the cluster, by default, client certificates can authenticate and perform any action on the API server. On the other hand, with Role Based Access Control (RBAC) enabled, client certificates must be granted specific authorization to Kubernetes resources.

To create a cluster without generating a client certificate, use the --no-issue-client-certificate flag:

gcloud container clusters create CLUSTER_NAME \
    --no-issue-client-certificate

Currently, there is no way to remove a client certificate from an existing cluster. To stop using client certificate authentication on an existing cluster, ensure you have RBAC enabled on the cluster, and that the client certificate does not have any authorization on the cluster.

What's next