如何使用动态和唯一的Google凭据对多个GKE Kubernetes集群进行身份验证

时间:2019-04-25 22:17:38

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

我们有一个系统旨在同时管理外部客户帐户中容纳的大量Kubernetes集群。当前,此系统的工作方式是将kubeconfig存储在运行时查询的数据库中,然后将其传递到golang kube-client构造函数中,如下所示:

clientcmd.NewClientConfigFromBytes([]byte(kubeConfigFromDB))

对于使用基本身份验证的集群,这“有效”。

对于EKS群集,只要在运行golang代码的机器上都安装了aws-iam-authenticator,以便kube-client可以对其进行身份验证并更正{{1} }和API_AWS_ACCESS_KEY_IDAPI_AWS_SECRET_ACCESS_KEY的{​​{1}}键中设置。

对于GKE集群,目前尚不清楚实现此目标的最佳实践方法是什么,尽管尝试了以下详细介绍的一些其他操作,但我仍无法使其工作。为GKE群集生成kubeconfig的标准做法与使用user.exec.env生成身份验证凭据的EKS(此处为https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl?authuser=1#generate_kubeconfig_entry详细)非常相似。

一个想法是使用kubeconfig环境变量,但是它的问题是它是 global ,因此我们不能让我们的系统同时与许多远程GKE集群通信,因为每个集群需要一组唯一的Google凭据进行身份验证。

我的第二个想法是使用提供给gcloud config config-helper的{​​{1}}标志,但是当我运行它并出现以下错误时会崩溃:

GOOGLE_APPLICATION_CREDENTIALS

我的最终想法很复杂。我将得到google-credentials-JSON并将其放在--impersonate-service-account中,如下所示:

gcloud config config-helper

然后我将创建自己的https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go#L156副本并替换第156行

$ gcloud config config-helper --format=json --impersonate-service-account=acct-with-gke-access@myorg.iam.gserviceaccount.com --project myproject
WARNING: This command is using service account impersonation. All API calls will be executed as [acct-with-gke-access@myorg.iam.gserviceaccount.com].
ERROR: gcloud crashed (AttributeError): 'unicode' object has no attribute 'utcnow'

kubeconfig

user: auth-provider: config: credentials: "<google-credentials-JSON>" name: my-custom-forked-gcp 是我添加的新方法,如下所示:

ts, err := google.DefaultTokenSource(context.Background(), scopes...)

最后一个想法可能会起作用(希望!我现在正在研究它),但这似乎是一个简单问题的非常复杂的解决方案:在运行时向golang kubernetes客户端提供ts, err := tokenSourceFromJSON(context.Background(), gcpConfig["credentials"], scopes...) 以进行身份​​验证使用这些凭据。有没有更简单的方法?

1 个答案:

答案 0 :(得分:1)

  

一个想法是使用GOOGLE_APPLICATION_CREDENTIALS环境变量,但是,它的问题是它是全局变量,因此我们不能让我们的系统同时与许多远程GKE集群通信,因为每个集群都需要一组唯一的Google凭据进行身份验证。

您可以使用以下命令为运行go程序的特定shell覆盖env变量:

os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", value)
  

我的第二个想法是使用提供给gcloud config config-helper的--impersonate-service-account标志

看起来像gcloud应用的python代码中的错误。如上所述,here utcnow仅适用于datetime.datetime对象。您可以检查该模块是否在系统中的python shell中工作。

  

我的最终想法很复杂。

只要credentials: "<google-credentials-JSON>"的值在GCP API的不同会话之间不改变(凭据值可能已过期),似乎就可以使用

注意:PR是最终的想法。