I would like to be able to access GKE (kubernetes) cluster in GCP from python kubernetes client. I cant authenticate and connect to my cluster and i dont find the reason. Here is what i tried so far.
from google.auth import compute_engine
from google.cloud.container_v1 import ClusterManagerClient
from kubernetes import client
def test_gke(request):
    project_id = "myproject"
    zone = "myzone"
    cluster_id = "mycluster"
    credentials = compute_engine.Credentials()
    cluster_manager_client = ClusterManagerClient(credentials=credentials)
    cluster = cluster_manager_client.get_cluster(name=f'projects/{project_id}/locations/{zone}/clusters/{cluster_id}')
    configuration = client.Configuration()
    configuration.host = f"https://{cluster.endpoint}:443"
    configuration.verify_ssl = False
    configuration.api_key = {"authorization": "Bearer " + credentials.token}
    client.Configuration.set_default(configuration)
    v1 = client.CoreV1Api()
    print("Listing pods with their IPs:")
    pods = v1.list_pod_for_all_namespaces(watch=False)
    for i in pods.items:
        print("%st%st%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
Advertisement
Answer
I’d like to get the configuration working I have it work where, the code is running off cluster and it produces the kubectl config file for itself. (see update at end)
Original
The first solution assumes (!) you’ve the cluster configured in your local (~/.kube/config and probably adjusted by KUBE_CONFIG) config.
from google.cloud.container_v1 import ClusterManagerClient
from kubernetes import client,config
config.load_kube_config()
api_instance = client.CoreV1Api()
resp = api_instance.list_pod_for_all_namespaces()
for i in resp.items:
    print(f"{i.status.pod_ip}t{i.metadata.namespace}t{i.metadata.name}")
NOTE
- Assumes you’ve run
gcloud containers clusters get-credentialsto set the~/.kube/configfile for the current cluster (and has acurrent-contextset.- Uses your user credentials in the
~/.kube/configfile so no additional credentials are needed.
Update
Okay, I have it working. Here’s the code that will generate a kubectl config and connect to the cluster. This code uses Application Default Credentials to provide a Service Account key to the code (usually export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json)
import os
import google.auth
import base64
from google.cloud.container_v1 import ClusterManagerClient
from kubernetes import client,config
from ruamel import yaml
PROJECT = os.getenv("PROJECT")
ZONE = os.getenv("ZONE")
CLUSTER = os.getenv("CLUSTER")
# Get Application Default Credentials
# `project_id` is the Service Account's
# This may differ to the cluster's `PROJECT`
credentials, project_id = google.auth.default()
# Get the cluster config from GCP
cluster_manager_client = ClusterManagerClient(credentials=credentials)
name=f"projects/{PROJECT}/locations/{ZONE}/clusters/{CLUSTER}"
cluster = cluster_manager_client.get_cluster(name=name)
SERVER = cluster.endpoint
CERT = cluster.master_auth.cluster_ca_certificate
configuration = client.Configuration()
# Create's a `kubectl` config
NAME="freddie" # arbitrary
CONFIG=f"""
apiVersion: v1
kind: Config
clusters:
- name: {NAME}
  cluster:
    certificate-authority-data: {CERT}
    server: https://{SERVER}
contexts:
- name: {NAME}
  context:
    cluster: {NAME}
    user: {NAME}
current-context: {NAME}
users:
- name: {NAME}
  user:
    auth-provider:
      name: gcp
      config:
        scopes: https://www.googleapis.com/auth/cloud-platform
"""
# The Python SDK doesn't directly support providing a dict
# See: https://github.com/kubernetes-client/python/issues/870
kubeconfig = yaml.safe_load(CONFIG)
loader = config.kube_config.KubeConfigLoader(kubeconfig)
loader.load_and_set(configuration)
api_client= client.ApiClient(configuration)
api_instance = client.CoreV1Api(api_client)
# Enumerate e.g. Pods
resp = api_instance.list_pod_for_all_namespaces()
for i in resp.items:
     print(f"{i.status.pod_ip}t{i.metadata.namespace}t{i.metadata.name}")
