如何轻松切换 gcloud / kubectl 凭据

11

我在工作中使用托管在GCP中的Kubernetes,同时我还有一个个人项目托管在我的GCP帐户中,使用Google App Engine(使用gcloud app deploy进行部署)。

经常当我尝试运行命令,比如 kubectl logs -f service-name 时,我会遇到类似这样的错误:“来自服务器的错误(Forbidden):pods是被禁止的:用户“my_personal_email@gmail.com”无法在API组“”中列出名称空间“WORK_NAMESPACE”中的资源“pods”:需要“container.pods.list”权限。”然后我就必须花费几个小时与kubectl打交道,试图让它正常工作。

能否有人向像我这样的慢人解释一下,gcloudkubectl是如何协同工作的,以及我如何轻松切换帐户,以便我可以使用gcloud命令处理个人项目和kubectl命令处理工作项目?如果需要的话,我很乐意彻底删除我的配置并重新开始。我找到了各种kubectlgcloud文档,但它们不太容易理解或者说含混不清。

编辑:这是在Linux上。


哪个操作系统?为什么不创建两个不同的登录,然后切换终端窗口(如果在Linux上)。对于Windows,将设置移动到批处理脚本,并为每个环境打开不同的命令提示符。第一步是定义正确设置每个环境的命令。您不应该花费数小时来切换。 - John Hanley
2
看看我写的这篇文章。有多种方法可以满足您的需求:https://medium.com/google-cloud/context-light-gcloud-and-kubectl-89185d38ce82 - DazWilkin
kubectl 的另外两个特性:您可以创建多个配置文件,然后针对每个环境设置 KUBECONFIG;您可以在上下文中包含命名空间,因此不仅可以默认到特定的集群和授权对,还可以默认到一个命名空间。 - DazWilkin
这篇文章介绍了gcloud如何与kubectl配合使用:https://medium.com/google-cloud/kubernetes-engine-kubectl-config-b6270d2b656c - DazWilkin
4个回答

19

我也遇到同样的问题并尝试了以下所有方法:

gcloud auth login
gcloud auth list
gcloud config set account
gcloud projects list

没有帮助。 我知道 gcloud 切换得很好,因为我能够直接列出其他资源。 但是,似乎kubectl无法自动捕捉这些更改,因为kubectl/gcloud集成依赖于预生成的密钥,其有效期为1小时(不确定是否为默认值,但目前在我的计算机上是这样)。 因此,在正确设置gcloud的用户/项目/帐户之上,您应该重新生成凭据:

gcloud container clusters get-credentials <my-cluster> --zone <clusters-zone>


4
最后一行非常关键,这将强制 kubectl 使用新的集群。 - howMuchCheeseIsTooMuchCheese

6

简短概述

编辑:Kubernetes 1.26 对此答案有所更改,现在请使用 gcloud auth 来管理您的不同配置文件。

  1. 使用 gcloud auth 来管理您在 Google Cloud Platform 上的不同配置文件。
  2. 将一个明确的帐户添加到您的 kubectl 配置文件(~/.kube/config)中,以便在请求使用 gke-gcloud-auth-plugin 生成令牌时,教会 kubectl 使用特定帐户与某个集群配对,而不是使用您的活动帐户。
# file: ~/.kube/config
users:
- name: gke_project-name_cluster-zone_cluster-name
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: gke-gcloud-auth-plugin
      args:
      - --account=your@work.email # <<< Add this line

有没有人能给像我这样的慢人解释一下,gcloud和kubectl是如何协同工作的,以及我如何轻松切换帐户,以便我可以在个人项目中使用gcloud命令,而在工作项目中使用kubectl命令?
当配置kubernetes集群并按照谷歌建议的指示运行"gcloud container clusters get-credentials ..."时,您将获得kubeconfig的一部分,其中包含有关kubectl如何执行操作以获取访问令牌的信息,当与配置了给定用户的群集通信时。它看起来会像这样:
users:
- name: gke_project-name_cluster-zone_cluster-name
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args: null
      command: gke-gcloud-auth-plugin
      env: null
      installHint: Install gke-gcloud-auth-plugin for use with kubectl by following
        https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
      interactiveMode: IfAvailable
      provideClusterInfo: true

基本上,这告诉kubectl在需要新令牌时运行gke-gcloud-auth-plugin,并且访问令牌可以从该命令的输出中解析出来。 这是理解kubectl如何与gcloud通信的关键所在

像您一样,我个人和工作中都使用Google Cloud。问题在于,此用户配置块没有考虑到它在生成凭据时不应该使用当前活动的gcloud帐户。即使您在两个项目中都没有使用kubernetes,例如vscode中的扩展程序可能会尝试在您处理其他项目时运行kubectl命令。如果在当前令牌过期后发生这种情况,则可能会调用gke-gcloud-auth-plugin以使用个人帐户生成令牌。

为了防止这种情况发生,我建议使用gcloud config configurations。配置是全局配置文件,您可以快速切换。它们可以存储更多的信息,而不仅仅是帐户信息,任何gcloud config ...都可以保存。例如,我有两个配置看起来像这样:

> gcloud config configurations list                                               

NAME      IS_ACTIVE  ACCOUNT             PROJECT            COMPUTE_DEFAULT_ZONE       COMPUTE_DEFAULT_REGION
work      False      zev@work.email      work-project       us-west1-a                 us-west1
personal  True       zev@personal.email  personal-project   northamerica-northeast1-a  northamerica-northeast1

当设置多个配置时,您将需要使用不同的帐户运行gcloud auth login。我们只需要指示kubectl使用特定的帐户与给定的集群通信,而不是当前活动的帐户。

所以问题就变成了这样:如果您设置kubeconfig以在kubectl需要为您的个人集群获取新的访问令牌时执行gke-gcloud-auth-plugin --acount=your@work.email,它将使用您工作配置中的帐户,而不管当前活动的帐户是哪个gcloud工具。那么它看起来会像这样:

# file: ~/.kube/config
users:
- name: gke_project-name_cluster-zone_cluster-name
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1

      # ----- Remove this ------
      args: null
      # -------------------------
      # +++++ Then add this: ++++
      args:
      - --account=your@work.email
      # +++++++++++++++++++++++++

      command: gke-gcloud-auth-plugin
      env: null
      installHint: Install gke-gcloud-auth-plugin for use with kubectl by following
        https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
      interactiveMode: IfAvailable
      provideClusterInfo: true

在 Kubernetes 1.26 之前,流程是相同的,只不过您需要直接使用 gcloud config configuration 而不是帐户,因此:
  1. 使用 gcloud config configurations 来管理您在 Google Cloud Platform 中的不同配置文件。

  2. 找到您的 kubeconfig 用户的 cmd-args,然后添加显式的 --configuration 参数,以防止 gcloud 为无关的配置文件生成访问令牌。

    # file: ~/.kube/config
    users:
    - user:
        auth-provider:
          config:
            # !! Prior to GKE 1.26
            cmd-args: config --configuration=work config-helper --format=json
    

如果您已升级 kubectl、gcloud 并使用 gcloud_auth_plugin 进行身份验证,则令牌的位置和到期详细信息已更改为 code ~/.kube/gke_gcloud_auth_plugin_cache。因此,现在您需要在那里将到期时间设置为过去。 - priyesh.patel
@priyesh.patel,不确定你想要指出什么。那与我的答案无关,这个设置的整个重点是你不需要涉及这些令牌或它们的过期日期。 - Zev Isert
另外,相比之下,当使用awscli的等效populate-kubeconfig命令时,它执行类似的操作,但在上下文条目中,它还设置了一个环境变量条目AWS_PROFILE=yourprofile,这就是为什么awscli等效命令能够正常工作的原因。 - undefined

3
对我来说,更新“~/.kube/config”文件并将到期时间设置为过去的日期即可解决该问题。

令牌的位置和过期详细信息已更改为代码~/.kube/gke_gcloud_auth_plugin_cache,如果您已升级kubectl、gcloud并使用gcloud_auth_plugin进行身份验证,则需要在那里将到期设置为过去。 - priyesh.patel

2
我和你一样 - 我在GKE上部署了工作应用程序,并在我的个人GCP帐户中部署了个人项目。 gcloud存储已登录帐户的列表,您可以在其中切换以与关联的项目通信。请查看以下命令:
gcloud auth login
gcloud auth list
gcloud config set account
gcloud projects list

要使用帐户下的特定项目,您需要通过gcloud config set project PROJECT_ID设置该配置。
在本地计算机上,kubectl有一个“上下文”列表,存储在~/.kube/config中。您当前的上下文是您想要运行命令的集群 - 类似于gcloud中的活动帐户/项目。
gcloud不同,这些是特定于集群的,并存储有关集群端点、默认名称空间、当前上下文等的信息。您可以从GCP、AWS、on-prem等任何具有集群的地方获得上下文。我们为开发、qa和prod拥有不同的集群(因此有不同的上下文),并在它们之间频繁切换。查看[kubectx项目][1] https://github.com/ahmetb/kubectx以更轻松地在上下文和名称空间之间切换。 kubectl将使用您登录到的任何GCP帐户的密钥来针对设置为当前上下文的集群。即,根据上面的错误,如果您的gcloud活动帐户为个人帐户,但尝试从工作中的集群列出pod,则会出现错误。您需要将gcloud的活动帐户/项目设置为您的工作电子邮件,或更改kubectl上下文以连接到托管在您的个人GCP帐户/项目中的集群。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接