12

我们将 kubernetes python 客户端(4.0.0)与 google 的 kubernetes 引擎(master + nodepools 运行 k8s 1.8.4)结合使用,以定期在 kubernetes 上调度工作负载。我们用于创建 pod、附加到日志并报告 pod 结束状态的脚本的简化版本如下所示:

config.load_kube_config(persist_config=False)
v1 = client.CoreV1Api()
v1.create_namespaced_pod(body=pod_specs_dict, namespace=args.namespace)
logging_response = v1.read_namespaced_pod_log(
    name=pod_name,
    namespace=args.namespace,
    follow=True,
    _preload_content=False
)
for line in logging_response:
    line = line.rstrip()
    logging.info(line)
status_response = v1.read_namespaced_pod_status(pod_name, namespace=args.namespace)
print("Pod ended in status: {}".format(status_response.status.phase))

一切正常,但是我们遇到了一些身份验证问题。身份验证通过默认的auth-provider 进行,为此我通过在调度程序上手动gcp运行来获得初始访问令牌。kubectl container cluster get-credentials在某些随机时间范围内,某些 API 调用会导致来自 API 服务器的 401 响应。我的猜测是,只要访问令牌过期,就会发生这种情况,并且脚本会尝试获取新的访问令牌。但是,调度程序上会同时运行多个脚本,导致多次获取新的 API 密钥,其中只有一个仍然有效。我尝试了多种方法来解决这个问题(使用persist_config=True,重新加载配置后重试401,...)没有任何成功。由于我不完全了解 gcp 身份验证和 kubernetes python 客户端配置是如何工作的(两者的文档都相当稀缺),所以我有点不知所措。

我们应该使用另一种身份验证方法而不是gcpauth-provider 吗?这是 kubernetes python 客户端中的错误吗?我们应该使用多个配置文件吗?

4

3 回答 3

25

最后我们通过使用不记名令牌身份验证解决了这个问题,而不是依赖默认的 gcloud 身份验证方法。

以下是我为实现这一目标而采取的步骤。

首先在所需的命名空间中创建一个服务帐户,方法是创建一个包含以下内容的文件。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: <name_of_service_account>

然后使用此文件创建服务帐户

kubectl create -f <path_to_file> --namespace=<namespace_name>

每个服务帐户都有一个与之关联的不记名令牌,可用于身份验证。此不记名令牌作为秘密自动挂载到命名空间中。要找出这个令牌是什么,首先找到秘密的名称(形式为<service_account_name>-token-<random_string>),然后使用该名称获取内容。

# To search for out service account's token name
kubectl get secrets --namespace=<namespace_name>

# To find the token name
kubectl describe secret/<secret_name>

之后你应该找到API服务器的IP地址,以及kubernetes集群的Cluster CA证书。这可以通过转到谷歌云控制台上的 kubernetes 引擎详细信息页面来完成。将证书内容复制到本地文件中。

您现在可以使用不记名令牌通过 kubernetes python 客户端进行身份验证,如下所示:

from kubernetes import client

configuration = client.Configuration()
configuration.api_key["authorization"] = '<bearer_token>'
configuration.api_key_prefix['authorization'] = 'Bearer'
configuration.host = 'https://<ip_of_api_server>'
configuration.ssl_ca_cert = '<path_to_cluster_ca_certificate>'

v1 = client.CoreV1Api(client.ApiClient(configuration))
于 2018-01-22T08:34:37.660 回答
9

我有一个使用 Kubernetes 客户端的 python 容器,并且正在寻找一种方法让它在集群中执行时使用服务帐户,但在本地执行时加载安装的 kube 配置。找了好久才找到load_incluster_config(),在集群中执行时会根据容器的服务账号自动配置。我现在在本地运行时打开一个 env var。这可能对您有帮助:

https://github.com/kubernetes-client/python/blob/master/examples/in_cluster_config.py

于 2020-09-13T17:47:52.007 回答
0

为了向您的 API 服务器进行身份验证,您可以使用基于角色的访问控制 (RBAC),它可以定义一系列角色来管理对您的 API 的身份验证和访问。

这是基于通过使用绑定将角色和集群角色授予不同的用户或服务帐户。这些角色包括一些代表一组权限的规则,并且可以定义为作用于命名空间(角色)或整个集群(集群角色)。

启用 RBAC 的第一步是使用以下选项启动 API 服务器:

--authorization-mode=RBAC

您可以使用 kubectl 命令定义特定角色。例如,如果您想将管理员集群角色授予命名空间(例如 acme)上的用户(例如 Bob),您可以使用以下命令:

kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme

您还可以为用户(例如 root)定义集群角色以在整个集群中拥有管理员权限:

kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root

如果您想改用服务帐户,可以使用如下命令将角色授予服务帐户:

kubectl create rolebinding my-sa-view  --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace

您可以在此处查看有关 RBAC 的更多信息,包括您可以授予用户或服务帐户的所有可能角色和集群角色。

于 2018-01-17T16:38:04.703 回答