简体   繁体   English

如何在启用了工作负载身份的 GKE 上将 Cloud Trace 与 Nodejs 结合使用?

[英]How to use Cloud Trace with Nodejs on GKE with workload identity enabled?

I'm trying to set up Cloud Trace on a GKE cluster with workload identity enabled.我正在尝试在启用了工作负载身份的 GKE 集群上设置 Cloud Trace。 My pod uses a service account, which has the Cloud Trace Agent role.我的 pod 使用具有Cloud Trace Agent角色的服务帐号。 (I also tried giving it the Owner role, to rule out permission issues, but that didn't change the error.) (我还尝试赋予它Owner角色,以排除权限问题,但这并没有改变错误。)

I followed the Node.js quickstart , which says to add the following snippet to my code:我遵循了Node.js quickstart ,它说将以下代码段添加到我的代码中:

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

When I try to add a trace, I get the following error:当我尝试添加跟踪时,出现以下错误:

@google-cloud/trace-agent DEBUG TraceWriter#publish: Received error while publishing traces to cloudtrace.googleapis.com: Error: Could not refresh access token: A Forbidden error was returned while attempting to retrieve an access token for the Compute Engine built-in service account. @google-cloud/trace-agent DEBUG TraceWriter#publish:将跟踪发布到 cloudtrace.googleapis.com 时收到错误:错误:无法刷新访问令牌:尝试检索构建的计算引擎的访问令牌时返回了禁止错误-在服务帐户中。 This may be because the Compute Engine instance does not have the correct permission scopes specified: Could not refresh access token: Unsuccessful response status code.这可能是因为 Compute Engine 实例没有指定正确的权限范围:无法刷新访问令牌:不成功的响应状态代码。 Request failed with status code 403请求失败,状态码 403

(How) can I configure the library to work in this scenario? (如何)我可以将库配置为在这种情况下工作吗?

In order to answer your question on comments above: correct me if I'm wrong - workload identity is a cluster feature, not connected to a namespace?为了回答您对上述评论的问题:如果我错了,请纠正我 - 工作负载身份是一个集群功能,未连接到命名空间?

And seeing that you have fixed your problem by configuring the binding between KSA/K8s Namespace and GCP SA I will add a response to add more context that I believe could help clarify this.看到您通过配置KSA/K8s NamespaceGCP SA之间的绑定解决了您的问题,我将添加一个响应以添加更多我相信可以帮助澄清这一点的上下文。

Yes you are right, Workload identity is a GKE cluster feature that lets you bind an identity from K8s (Kubernetes Service Account (KSA)) with a GCP identity (Google Service Account(GSA)) in order to have your workloads authenticated with an specific GCP identity and with enough permissions to be able to reach certain APIs (depending on the permissions that your GCP service account has).是的,您是对的,工作负载身份是 GKE 集群功能,它允许您将来自 K8s(Kubernetes 服务帐户(KSA))的身份与 GCP 身份(Google 服务帐户(GSA))绑定,以便让您的工作负载通过特定的身份验证GCP 身份并具有足够的权限来访问某些 API(取决于您的 GCP 服务帐户拥有的权限)。 k8s namespaces and KSA take a critical role here, as KSA are Namespaced resources. k8s namespacesKSA在这里起着关键作用,因为KSA是命名空间资源。

Therefore, in order to authenticate correctly your workloads (containers) and with a GCP Service account, you need to create them in the configured k8s Namespace and with the configured KSA, as mentioned in this doc因此,为了正确验证您的工作负载(容器)并使用 GCP 服务帐户,您需要在配置的k8s Namespace和配置的 KSA 中创建它们,如本文档中所述

If you create your workloads on a different k8s Namespace (meaning using a different KSA), you will not be able to get an authenticated identity for your workloads, instead of that, your workloads will be authenticated with the Workload Identity Pool/Workload Identity Namespace , which is: PROJECT_ID.svc.id.goog .如果您在不同的k8s Namespace (意味着使用不同的 KSA)上创建工作负载,您将无法为工作负载获得经过身份验证的身份,取而代之的是,您的工作负载将通过Workload Identity Pool/Workload Identity Namespace进行身份验证,即: PROJECT_ID.svc.id.goog Meaning that when you create a container with the GCP SDK installed and run a glcoud auth list you will get PROJECT_ID.svc.id.goog as the authenticated identity, which is an IAM object but not an identity with permission in IAM.这意味着当您创建一个安装了 GCP SDK 的容器并运行glcoud auth list时,您将获得PROJECT_ID.svc.id.goog作为经过身份验证的身份,这是一个 IAM object 但不是具有 IAM 权限的身份。 So your workloads will be lacking of permissions.因此,您的工作负载将缺乏权限。

Then you need to create your containers in the configured namespace and with the configured service account to be able to have a correct identity in your containers and with IAM permissions.然后,您需要在配置的命名空间和配置的服务账户中创建您的容器,以便能够在您的容器中拥有正确的身份并具有 IAM 权限。

I'm assuming that above (authentication with lack of permission and lack of an actual IAM Identity) is what happened here, as you mentioned in your response, you just added the needed binding between GSA and the KSA , meaning that your container was lacking of an identity with actual IAM permissions.我假设上面的情况(在缺乏许可和缺乏实际 IAM 身份的情况下进行身份验证)是这里发生的事情,正如您在回复中提到的那样,您只是在GSAKSA之间添加了所需的绑定,这意味着您的容器缺少具有实际 IAM 权限的身份。

Just to be clear on this, Workload Identity allows you to authenticate your workloads with a service account different from the one on your GKE nodes.为了明确这一点,Workload Identity 允许您使用与 GKE 节点上的服务帐户不同的服务帐户对工作负载进行身份验证。 If your application runs inside a Google Cloud environment that has a default service account, your application can retrieve the service account credentials to call Google Cloud APIs.如果您的应用程序在具有默认服务帐户的 Google Cloud 环境中运行,则您的应用程序可以检索服务帐户凭据以调用 Google Cloud API。 Such environments include Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run, and Cloud Functions, here .此类环境包括 Compute Engine、Google Kubernetes Engine、App Engine、Cloud Run 和 Cloud Functions,请点击此处

With above comment I want to say that even if you do not use Workload Identity, your containers will be authenticated as they are running on GKE, which by default use a service account, and this service account is inherited from the nodes to your containers, the default service account (Compute service Account) and its scopes are enough to write from containers to Cloud Trace and that is why you were able to see traces with a GKE cluster with Workload Identity disabled, because the default service account was used on your containers and nodes.有了上面的评论,我想说的是,即使您不使用 Workload Identity,您的容器也会在 GKE 上运行时进行身份验证,默认情况下使用服务帐户,并且此服务帐户是从节点继承到您的容器的,默认服务帐户(计算服务帐户)及其范围足以从容器写入Cloud Trace ,这就是为什么您能够在禁用 Workload Identity 的 GKE 集群中看到跟踪,因为默认服务帐户已用于您的容器和节点。

If you test this on both environments:如果您在两种环境中都进行测试:
GKE cluster with Workload Identity: You will be able to see, with the correct config, a service account different than the default, authenticating your workloads/containers.具有工作负载身份的 GKE 集群:您将能够通过正确的配置看到一个不同于默认服务帐户的服务帐户,用于验证您的工作负载/容器。

GKE cluster with Workloads Identity disabled: You will be able to see the same service account used by your nodes (by default the compute engine service account with Editor role and scopes applied on your nodes when using default service account) on your Containers.禁用 Workloads Identity 的 GKE 集群:您将能够在您的容器上看到节点使用的相同服务帐户(默认情况下,使用默认服务帐户时在您的节点上应用编辑角色和范围的计算引擎服务帐户)。

These tests can be performed by spinning the same container you used on your response, which is:这些测试可以通过旋转您在响应中使用的相同容器来执行,即:

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

And running `glcoud auth list to see the identity you are authenticated with on your containers.并运行 `glcoud auth list 以查看您在容器上通过身份验证的身份。

Hope this can help somehow!希望这能有所帮助!

It turned out I had misconfigured the IAM service account.原来我错误地配置了 IAM 服务帐户。

I managed to get a more meaningful error message by running a new pod in my namespace with the gcloud cli installed:通过在我的命名空间中运行一个安装了gcloud cli的新 pod,我设法获得了更有意义的错误消息:

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

after that, just running any gcloud command gave an error message containing (emphasis mine):之后,只需运行任何gcloud命令都会给出一条错误消息,其中包含(强调我的):

Unable to generate access token;无法生成访问令牌; IAM returned 403 Forbidden: The caller does not have permission This error could be caused by a missing IAM policy binding on the target IAM service account. IAM 返回 403 Forbidden: The caller does not have permission此错误可能是由于目标 IAM 服务账户上缺少 IAM 策略绑定造成的。

Running跑步

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

indeed showed that the binding to the Kubernetes service account was missing.确实表明缺少与 Kubernetes 服务帐户的绑定。

Adding it manually fixed the issue:手动添加它解决了这个问题:

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

After more research, the underlying problem was that I created my service accounts using Config Connector but hadn't properly annotated the Kubernetes namespace with the Google Cloud project to deploy the resources in:经过更多研究,根本问题是我使用 Config Connector 创建了我的服务帐户,但没有使用 Google Cloud 项目正确注释 Kubernetes 命名空间以将资源部署到:

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

Therefore, Cloud Connector could not add the IAM policy binding.因此,Cloud Connector 无法添加 IAM 策略绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Workload Identity 从 GKE 向 Google Cloud Firestore 进行身份验证 - Authenticating to Google Cloud Firestore from GKE with Workload Identity 用于捆绑应用程序的 Google Cloud Trace NodeJS - Google Cloud Trace NodeJS for bundled applications 如何使用nodejs的spring cloud? - How to use spring cloud from nodejs? 如何使用 Keystore 连接到使用 NodeJS 启用 SSL 的 IBM MQ - How to use Keystore to connect to SSL enabled IBM MQ using NodeJS 如何在 NodeJS 项目中使用 Google Cloud FireStore 模拟器? - How to use Google Cloud FireStore emulator with NodeJS project? 如何在带有NodeJS的Google Cloud Storage中使用google-auth-library? - How to use google-auth-library with Google Cloud Storage with NodeJS? 如何使用nodejs从谷歌云存储获取链接文件 - how to get link file from google cloud storage use nodejs 如何跟踪nodejs表达服务静态文件 - how to trace nodejs express serving static files 在 GKE 集群上运行时如何在 NodeJs 中捕获抢占通知? - How to catch preemption notice in NodeJs when running on a GKE cluster? 如何通过 GKE pod 访问 Google Cloud Storage 中的文件 - How to access Files in Google Cloud Storage through GKE pods
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM