Kubernetes python客户端:身份验证问题

时间:2018-01-08 13:32:29

标签: kubernetes google-kubernetes-engine kubernetes-python-client

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

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))

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

我们应该使用其他身份验证方法而不是gcp身份验证提供程序吗?这是kubernetes python客户端中的错误吗?我们应该使用多个配置文件吗?

3 个答案:

答案 0 :(得分:10)

最后,我们通过使用承载令牌身份验证解决了这个问题,而不是依赖于默认的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群集的群集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))

答案 1 :(得分:2)

我有一个使用Kubernetes客户端的python容器,并且正在寻找一种方法来使其在集群中执行时使用服务帐户,但是在本地执行时加载已安装的kube配置。我花了一段时间才找到sudo rm -rf var/cache ,它在集群中执行时会根据容器的服务帐户自动配置。我现在在本地运行时打开一个环境变量。这可能对您有帮助:

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

答案 2 :(得分: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

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

相关问题