kubernetes - 在 Python 中向 GKE master 进行身份验证
问题描述
我需要使用Kubernetes Python 客户端和 Google Cloud python 客户端对GKE中配置的 Kubernetes 集群进行身份验证。出于以下几个原因,我宁愿不掏钱:gcloud
gcloud
当我有一个原生谷歌云库时,依赖 Python 脚本中的系统 shell是不优雅的- 它要求系统具有
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)
解决方案
下面是从 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 的帖子很有帮助。
推荐阅读
- powershell - 在 PS 4.0 版上安装 azure powershell 模块而不更新到 PS 5.0 版
- python - 从子文件夹导入python模块,其中模块包含未初始化的参数
- javascript - 从文本文件中解释文字 HTML 标签
- python - 如何结合for循环和正则表达式?
- javascript - 如何使用 AJAX 调用来确定用户是否存在,然后继续执行下一个代码?
- javascript - Python Flask - 从 API 值计算利润/翻转
- javascript - Node.js request.open("GET", "what.should.I.put.here.html/getAll", true);
- php - 我们如何在特定单词后添加逗号
- docker - Dockerfile:重复 apt 缓存清理的好处
- docker - Kafka - 消费者无法启动:连接被拒绝 - 127.0.0.1:9092 的连接(2)