-1

我正在尝试在启用了工作负载身份的 GKE 集群上设置 Cloud Trace。我的 pod 使用具有Cloud Trace Agent角色的服务帐户。(我也尝试赋予它Owner角色,以排除权限问题,但这并没有改变错误。)

我遵循了Node.js quickstart,它说将以下代码段添加到我的代码中:

require('@google-cloud/trace-agent').start();

当我尝试添加跟踪时,出现以下错误:

@google-cloud/trace-agent DEBUG TraceWriter#publish:将跟踪发布到 cloudtrace.googleapis.com 时收到错误:错误:无法刷新访问令牌:尝试检索构建的计算引擎的访问令牌时返回了禁止错误-在服务帐户中。这可能是因为 Compute Engine 实例未指定正确的权限范围:无法刷新访问令牌:不成功的响应状态代码。请求失败,状态码 403

(如何)我可以将库配置为在这种情况下工作吗?

4

2 回答 2

2

为了回答您对上述评论的问题:如果我错了,请纠正我 - 工作负载身份是集群功能,未连接到命名空间?

并且看到您通过配置和之间的绑定解决了您的问题,KSA/K8s NamespaceGCP SA将添加一个响应以添加更多我相信可以帮助澄清这一点的上下文。

是的,您是对的,工作负载身份是一项 GKE 集群功能,可让您将来自 K8s(Kubernetes 服务帐户(KSA))的身份与 GCP 身份(Google 服务帐户(GSA))绑定,以便让您的工作负载通过特定的身份验证GCP 身份并具有足够的权限来访问某些 API(取决于您的 GCP 服务帐户拥有的权限)。k8s namespacesKSA在这里发挥关键作用,KSA命名空间资源也是如此。

因此,为了正确验证您的工作负载(容器)并使用 GCP 服务帐户,您需要在已k8s Namespace配置的 KSA 中创建它们,如本文档中所述

如果您在不同的(意味着使用不同的 KSA)上创建工作负载k8s Namespace,您将无法获得工作负载的经过身份验证的身份,取而代之的是,您的工作负载将使用 进行身份验证Workload Identity Pool/Workload Identity Namespace,即:PROJECT_ID.svc.id.goog. 这意味着当您创建安装了 GCP SDK 的容器并运行时,glcoud auth list您将获得PROJECT_ID.svc.id.goog经过身份验证的身份,这是一个 IAM 对象,但不是 IAM 中具有权限的身份。因此,您的工作负载将缺乏权限。

然后,您需要在配置的命名空间和配置的服务账户中创建您的容器,以便能够在您的容器中拥有正确的身份并具有 IAM 权限。

我假设上面(在缺乏许可和缺乏实际 IAM 身份的情况下进行身份验证)是这里发生的事情,正如您在回复中提到的那样,您只是在GSA和之间添加了所需的绑定KSA,这意味着您的容器缺少具有实际 IAM 权限的身份。

为了明确这一点,Workload Identity 允许您使用与 GKE 节点上的服务帐户不同的服务帐户对工作负载进行身份验证。如果您的应用程序在具有默认服务帐户的 Google Cloud 环境中运行,则您的应用程序可以检索服务帐户凭据以调用 Google Cloud API。此类环境包括 Compute Engine、Google Kubernetes Engine、App Engine、Cloud Run 和 Cloud Functions,请点击此处

有了上面的评论,我想说的是,即使您不使用 Workload Identity,您的容器也会在 GKE 上运行时进行身份验证,默认情况下使用服务帐户,并且此服务帐户是从节点继承到您的容器的,默认服务帐户(计算服务帐户)及其范围足以从容器写入Cloud Trace,这就是为什么您能够在禁用 Workload Identity 的 GKE 集群中看到跟踪,因为在您的容器和节点上使用了默认服务帐户.

如果您在这两种环境中进行测试:
具有工作负载身份的 GKE 集群:您将能够通过正确的配置看到一个不同于默认服务帐户的服务帐户,用于验证您的工作负载/容器。

禁用 Workloads Identity 的 GKE 集群:您将能够在容器上看到您的节点使用的相同服务帐户(默认情况下,使用默认服务帐户时在您的节点上应用编辑角色和范围的计算引擎服务帐户)。

这些测试可以通过旋转您在响应中使用的相同容器来执行,即:

kubectl run -it \
  --image google/cloud-sdk:slim \
 --serviceaccount KSA_NAME \ ##If needed 
 --namespace K8S_NAMESPACE \ ##If needed
  workload-identity-test

并运行 `glcoud auth list 以查看您在容器上通过身份验证的身份。

希望这能有所帮助!

于 2021-03-04T17:16:43.927 回答
0

原来我错误地配置了 IAM 服务帐户。

通过在我的命名空间中运行一个新的 pod 并安装了以下内容,我设法获得了更有意义的错误消息gcloud cli

kubectl run -it \
  --image gcr.io/google.com/cloudsdktool/cloud-sdk \
  --serviceaccount $GKE_SERVICE_ACCOUNT test \
  -- bash

之后,只需运行任何gcloud命令都会给出一条错误消息,其中包含(强调我的):

无法生成访问令牌;IAM 返回 403 Forbidden: The caller does not have permission 此错误可能是由于目标 IAM 服务账户上缺少 IAM 策略绑定造成的。

跑步

gcloud iam service-accounts get-iam-policy $SERVICE_ACCOUNT

确实表明缺少与 Kubernetes 服务帐户的绑定。

手动添加它解决了这个问题:

gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:$PROJECT.svc.id.goog[$NAMESPACE/$GKE_SERVICE_ACCOUNT]" \
  $SERVICE_ACCOUNT

经过更多研究,根本问题是我使用 Config Connector 创建了我的服务帐户,但没有使用Google Cloud 项目正确注释 Kubernetes 命名空间以将资源部署到:

kubectl annotate namespace "$NAMESPACE" cnrm.cloud.google.com/project-id="$PROJECT"

因此,Cloud Connector 无法添加 IAM 策略绑定。

于 2021-03-04T11:24:42.160 回答