使用Python向GKE大师进行身份验证

时间:2019-01-28 21:16:23

标签: kubernetes google-cloud-platform google-oauth google-kubernetes-engine

我需要使用GKE和Google Cloud python客户端对在Kubernetes Python client中配置的Kubernetes集群进行身份验证。由于某些原因,我不希望使用gcloud

  • 当我拥有本机Google Cloud库时,依靠Python脚本中的系统外壳gcloud不好
  • 它要求系统具有gcloud
  • 我将不得不将用户切换到相关的ServiceAccount,然后再切换回
  • 这会导致启动/加入另一个进程的费用

因此,gcloud container clusters get-credentials(代表gcloud config config-helper的工作流程)不足以让我获得所需的API密钥。如何使用Google Cloud Python API获得等效的输出?

这是我到目前为止所拥有的:

import kubernetes.client
import googleapiclient.discovery
import base64

# get the cluster object from GKE
gke = googleapiclient.discovery.build('container', 'v1', credentials=config['credentials'])
name = f'projects/{config["project_id"]}/locations/{config["location"]}/{parent}/clusters/{config["name"]}'
gke_clusters = gke.projects().locations().clusters()
gke_cluster = gke_clusters.get(name=name).execute()

# set up Kubernetes Config
kube_config = kubernetes.client.Configuration()
kube_config.host = 'https://{0}/'.format(gke_cluster['endpoint'])
kube_config.verify_ssl = True
#kube_config.api_key['authenticate'] = "don't know what goes here"

# regretably, the Kubernetes client requires `ssl_ca_cert` to be a path, not the literal cert, so I will write it here.
kube_config.ssl_ca_cert = 'ssl_ca_cert'
with open(kube_config.ssl_ca_cert, 'wb') as f:
    f.write(base64.decodestring(gke_cluster['masterAuth']['clusterCaCertificate'].encode()))

# use Kubernetes client to do something
kube_client = kubernetes.client.ApiClient(configuration=kube_config)
kube_v1 = kubernetes.client.CoreV1Api(kube_client)
kube_v1.list_pod_for_all_namespaces(watch=False)

2 个答案:

答案 0 :(得分:1)

为了对GKE集群进行身份验证,可以使用service account连接到项目,然后使用GKE生成的密钥对集群进行身份验证。步骤如下:

  1. 在GCP中创建服务帐户。转到IAM>服务帐户>创建服务帐户。授予它项目所有者角色。创建SA后,创建一个密钥并将其下载为json。
  2. 将key.json上载到具有.py脚本的文件夹中
  3. 获取API_TOKEN。这是您的主要问题,可以通过读取令牌文件来获得它:
    • 首次运行kubectl get secrets
    • 您将获得“ default-token-xxxxx”
    • 运行kubectl describe secrets default-token-xxxxx(用您的令牌名称替换xxxxx)。
    • 显示的令牌参数是您的“ API-KEY”。将其复制到脚本中。
  4. 创建脚本。它与您的有一些不同,原因有几个:您需要首先使用服务帐户对项目进行身份验证,然后需要传递api_token,而且在向GKE主服务器进行身份验证时还需要获得SSL证书。
import base64, pprint
import kubernetes.client
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file("key.json")
gke = googleapiclient.discovery.build('container', 'v1', credentials=credentials)
name = 'projects/your_project/locations/your_zone/clusters/your_gke_cluster'
gke_clusters = gke.projects().locations().clusters()
gke_cluster = gke_clusters.get(name=name).execute()

kube_config = kubernetes.client.Configuration()
kube_config.host = 'https://{}'.format(gke_cluster['endpoint'])
kube_config.verify_ssl = True

kube_config.api_key['authorization'] = 'your_api_token'
kube_config.api_key_prefix['authorization'] = 'Bearer'

kube_config.ssl_ca_cert = 'ssl_ca_cert'

with open(kube_config.ssl_ca_cert, 'wb') as f:
    f.write(base64.decodestring(gke_cluster['masterAuth']['clusterCaCertificate'].encode()))

kube_client = kubernetes.client.ApiClient(configuration=kube_config)
kube_v1 = kubernetes.client.CoreV1Api(kube_client)
pprint.pprint(kube_v1.list_pod_for_all_namespaces())

特定字段:

  • 您的项目-来自GCP
  • 您的_zone-创建gke群集的位置
  • 您的_gke_cluster-GKE群集名称
  • 您的api_key-您在第3步中得到的结果。

这足以使您向GKE集群进行身份验证。

答案 1 :(得分:1)

以下是一种解决方案,可将访问令牌从googleapiclient中拉出,而不是手动复制粘贴内容。

import googleapiclient.discovery
from tempfile import NamedTemporaryFile
import kubernetes
import base64

def token(*scopes):
    credentials = googleapiclient._auth.default_credentials()
    scopes = [f'https://www.googleapis.com/auth/{s}' for s in scopes]
    scoped = googleapiclient._auth.with_scopes(credentials, scopes)
    googleapiclient._auth.refresh_credentials(scoped)
    return scoped.token

def kubernetes_api(cluster):
    config = kubernetes.client.Configuration()
    config.host = f'https://{cluster["endpoint"]}'

    config.api_key_prefix['authorization'] = 'Bearer'
    config.api_key['authorization'] = token('cloud-platform')

    with NamedTemporaryFile(delete=False) as cert:
        cert.write(base64.decodebytes(cluster['masterAuth']['clusterCaCertificate'].encode()))
        config.ssl_ca_cert = cert.name

    client = kubernetes.client.ApiClient(configuration=config)
    api = kubernetes.client.CoreV1Api(client)

    return api

def run(cluster):
    """You'll need to give whichever account `googleapiclient` is using the 
    'Kubernetes Engine Developer' role so that it can access the Kubernetes API.

    `cluster` should be the dict you get back from `projects.zones.clusters.get`
    and the like"""

    api = kubernetes_api(cluster)
    print(api.list_pod_for_all_namespaces())

弄清楚这一点所花的时间比我想承认的要长。 @Ivan的帖子很有帮助。