在 GCP 中使用 python Kubernetes api 的身份验证不起作用

Authentication using python Kubernetes api in GCP is not working

我希望能够从 python kubernetes 客户端访问 GCP 中的 GKE (kubernetes) 集群。 我无法验证并连接到我的集群,但我找不到原因。 这是我到目前为止尝试过的方法。

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("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

我想让配置工作我让它工作的地方,代码是 运行 集群,它产生 kubectl 配置为自己归档。 (见最后的更新)

原创

第一个解决方案假设 (!) 您已在本地配置集群(~/.kube/config 并且可能由 KUBE_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

  1. Assumes you've run gcloud containers clusters get-credentials to set the ~/.kube/config file for the current cluster (and has a current-context set.
  2. Uses your user credentials in the ~/.kube/config file so no additional credentials are needed.

更新

好的,我有它的工作。下面是将生成 kubectl 配置并连接到集群的代码。此代码使用 Application Default Credentials 为代码提供服务帐户密钥(通常为 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}")