Search code examples
kubernetesgoogle-cloud-platformgoogle-kubernetes-enginekubectlkubeconfig

Authenticate to GKE cluster without setting GOOGLE_APPLICATION_CREDENTIALS environment variable


What is the best way to authenticate to a GKE cluster without actually setting env variables for GOOGLE_APPLICATION_CREDENTIALS or KUBECONFIG. I have an application running on a container which has to communicate with multiple GKE clusters at once. Hence I am trying to generate the kubeconfig yaml file on the fly like so. But when I try to run any kubectl commands I get a non authorized error as it is expecting the service account creds to be set in the environment variable. Is there any way to actually avoid this and auth to multiple clusters on the fly by generating the kubeconfig file ?

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: {{.CertData}}
    server: {{.MasterURL}}
  name: {{.ClusterName}}
contexts:
- context:
    cluster: {{.ClusterName}}
    user: {{.ClusterName}}
  name: {{.ClusterName}}
current-context: {{.ClusterName}}
kind: Config
preferences: {}
users:
- name: {{.ClusterName}}
  user:
    auth-provider:
      config:
        cmd-args: config config-helper --format=json
        cmd-path: /usr/local/bin/gcloud/google-cloud-sdk/bin/gcloud
        expiry-key: '{.credential.token_expiry}'
        token-key: '{.credential.access_token}'
      name: {{.ClusterName}}

Solution

  • I ended up using oauth2 to generate a token and inpute that value in the kubeconfig token.

    Sample code to extract the token

    
    func getGKEToken(creds []byte, ctx context.Context) (string, error){
        var token *oauth2.Token
        scopes := []string{"https://www.googleapis.com/auth/cloud-platform",}
        cred, err := auth.CredentialsFromJSON(ctx, creds, scopes...)
        if err != nil {
            fmt.Printf("Failed to authenticate using credentials to extract token. Error %s \n", err.Error())
            return "", err
        }
        
        token, err = cred.TokenSource.Token()
        if err != nil {
            return "", err
        }
    
        return token.AccessToken, nil
    }
    

    GKE kubeconfig template

    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: {{.CertData}}
        server: {{.MasterURL}}
      name: {{.ClusterName}}
    contexts:
    - context:
        cluster: {{.ClusterName}}
        user: {{.ClusterName}}
      name: {{.ClusterName}}
    current-context: {{.ClusterName}}
    kind: Config
    preferences: {}
    users:
    - name: {{.ClusterName}}
      user:
        token: {{.AccessToken}}