我们有一个系统,旨在同时管理外部客户账户中的大量Kubernetes集群。该系统目前的工作原理是将kubeconfig
存储在运行时查询的数据库中,然后传递给golang kube-client构造函数,如下所示:
clientcmd.NewClientConfigFromBytes([]byte(kubeConfigFromDB))
对于使用基本身份验证的群集,这“正常”。
对于EKS集群,只要aws-iam-authenticator
安装在运行golang代码的机器上,以便kube-client可以调用它进行身份验证,并且在API_AWS_ACCESS_KEY_ID
的API_AWS_SECRET_ACCESS_KEY
密钥中设置正确的kubeconfig
和user.exec.env
,这就可以正常工作。
对于GKE集群,目前尚不清楚实现这一目标的最佳实践方法是什么,尽管尝试了下面详述的一些不同的操作,但我还是无法使其工作。为GKE集群生成kubeconfig
的标准做法与使用https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl?authuser=1#generate_kubeconfig_entry生成身份验证凭据的EKS(此处详细介绍gcloud config config-helper
)非常相似。
一个想法是使用GOOGLE_APPLICATION_CREDENTIALS
环境变量,但是问题在于它是全局的,因此我们不能让我们的系统同时与许多远程GKE集群通信,因为每个集群需要一组唯一的google凭据进行身份验证。
我的第二个想法是使用提供给--impersonate-service-account
的gcloud config config-helper
标志,但是当我运行它时会出现以下错误:
$ 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 [[email protected]].
ERROR: gcloud crashed (AttributeError): 'unicode' object has no attribute 'utcnow'
我的最终想法非常复杂。我会得到google-credentials-JSON并将其放入kubeconfig
中,如下所示:
user:
auth-provider:
config:
credentials: "<google-credentials-JSON>"
name: my-custom-forked-gcp
我会创建自己的https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go#L156副本并替换156行
ts, err := google.DefaultTokenSource(context.Background(), scopes...)
同
ts, err := tokenSourceFromJSON(context.Background(), gcpConfig["credentials"], scopes...)
其中tokenSourceFromJSON
是我添加的新方法,如下所示:
func tokenSourceFromJSON(ctx context.Context, jsonData string, scopes ...string) (oauth2.TokenSource, error) {
creds, err := google.CredentialsFromJSON(ctx, []byte(jsonData), scopes...)
if err != nil {
return nil, err
}
return creds.TokenSource, nil
}
这个最后的想法可能会起作用(希望!我现在正在努力)但对于一个简单的问题来说它似乎是一个非常复杂的解决方案:在运行时向golang kubernetes客户端提供google-credentials-JSON
以使用这些凭据进行身份验证。有没有更简单的方法?
一个想法是使用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的最终想法。