当前位置: 首页 > 知识库问答 >
问题:

使用工作负载身份从GKE向Google Cloud Firestore进行身份验证

柳韬
2023-03-14

我正在尝试编写一个简单的后端来访问我的Google Cloud Firestore,它位于Google Kubernetes引擎中。在我的本地计算机上,我使用以下代码对Firestore进行身份验证,详细内容见谷歌文档。

if (process.env.NODE_ENV !== 'production') {
  const result = require('dotenv').config()
  //Additional error handling here
}

这将拉取GOOGLE_APPLICATION_CREDENTIALS环境变量,并用我的google-application-credentals.json填充它,这是我通过使用"Cloud Datastore User"角色创建服务号获得的。

所以,在本地,我的代码运行良好。我可以到达我的火炉,做我需要做的一切。但是,一旦我部署到GKE,问题就出现了。

我按照这个谷歌文档为我的集群设置了一个工作负载标识,我已经创建了一个部署,并通过运行验证了所有Pod都使用正确的IAM服务帐户:

kubectl exec -it POD_NAME -c CONTAINER_NAME -n NAMESPACE sh
> gcloud auth list

我从文件中得到的印象是,只要上述情况属实,我的服务将进行身份验证。我真的不知道为什么,但我的Firestore()实例的行为似乎没有访问Firestore所需的凭据。

如果有帮助,下面是我的声明和实例的实现:

const firestore = new Firestore()

const server = new ApolloServer({
  schema: schema,
  dataSources: () => {
    return {
      userDatasource: new UserDatasource(firestore)
    }
  }
})

更新:

在绝望中,我决定拆除一切,重建它。随着一切一步一步地进行,我似乎要么遇到了错误,要么(更有可能)我第一次犯了轻微的错误。我现在能够连接到我的后端服务。然而,我现在得到了一个不同的错误。在发送任何请求时(我使用GraphQL,但本质上它是任何REST调用),我得到一个404。

检查日志会产生以下结果:

“从插件获取元数据失败,错误为:无法刷新访问令牌:在尝试检索计算引擎内置服务帐户的accesstoken时返回未找到错误。”。这可能是因为计算引擎实例没有指定任何权限范围:无法刷新访问令牌:响应状态代码失败。请求失败,状态代码为404'

对这个问题的粗略搜索似乎不会返回任何与我试图实现的目标相关的信息,因此我回到了原点。

共有2个答案

徐卓
2023-03-14

要结束这个问题。

以防有人无意中发现,这是为我修好的。

1.)我重新遵循了上面谷歌文档链接中的步骤,这解决了我的播客无法启动的问题。

2.)至于我的更新,我重新创建了我的集群,并授予它云数据源权限。我假设权限与工作负载标识需要的功能是分开的。我错了。

我希望这能帮助到某人。

芮雪风
2023-03-14

我认为你最初的假设是正确的!如果仍然必须指定作用域,则工作负载标识无法正常工作。在您链接的Workload文章中,没有使用范围。

我一直在努力解决同一个问题,并确定了三种在pod中获得认证凭据的方法。

1.工作负载标识(基本上是上面的工作负载标识文章,添加了一些部署细节)

这种方法是首选的,因为它允许群集中的每个Pod部署只被授予它需要的权限。

创建群集(注意:没有定义范围或服务号)

gcloud beta container clusters create {cluster-name} \
  --release-channel regular \
  --identity-namespace {projectID}.svc.id.goog

然后创建k8sServiceAccount,分配角色并注释。

gcloud container clusters get-credentials {cluster-name}

kubectl create serviceaccount --namespace default {k8sServiceAccount}

gcloud iam service-accounts add-iam-policy-binding \
  --member serviceAccount:{projectID}.svc.id.goog[default/{k8sServiceAccount}] \
  --role roles/iam.workloadIdentityUser \
  {googleServiceAccount}

kubectl annotate serviceaccount \
  --namespace default \
  {k8sServiceAccount} \
  iam.gke.io/gcp-service-account={googleServiceAccount}

然后我创建我的部署,并设置k8sService帐户。(设置服务号是我错过的部分)

kubectl create deployment {deployment-name} --image={containerImageURL}
kubectl set serviceaccount deployment {deployment-name} {k8sServiceAccount}

然后以8080为目标曝光

kubectl expose deployment {deployment-name}  --name={service-name} --type=LoadBalancer --port 80 --target-port 8080

googleServiceAccount需要分配适当的IAM角色(见下文)。

2.群集服务帐户

此方法不是首选方法,因为集群中的所有VM和POD都将基于定义的服务帐户拥有权限。

使用分配的服务帐户创建群集

gcloud beta container clusters create [cluster-name] \
 --release-channel regular \
 --service-account {googleServiceAccount}

googleServiceAccount需要分配适当的IAM角色(见下文)。

然后按上述方式部署和公开,但不设置k8sServiceAccount

3.范围

此方法不是首选方法,因为集群中的所有VM和POD都将具有基于定义的作用域的权限。

创建具有指定范围的集群(firestore只需要“云平台”,实时数据库也需要“userinfo.email”)

gcloud beta container clusters create $2 \
  --release-channel regular \
  --scopes https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email

然后按上述方式部署和公开,但不设置k8sServiceAccount

前两种方法需要一个分配了适当IAM角色的Google服务帐户。以下是我分配给一些Firebase产品的工作职责:

  • FireStore:云数据存储用户(数据存储)
 类似资料:
  • 我正在尝试使用谷歌首选的“工作负载身份”方法,使我的GKE应用程序能够安全地访问谷歌机密中的机密。 我已经完成了设置,甚至检查了故障排除部分的所有步骤(https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity?hl=sr-ba#故障排除)但我的日志中仍然出现以下错误: 未处理的异常。Grpc。果心RpcExce

  • 我正在尝试使用urllib3连接到网页。代码如下所示。 如果我们假设url是需要使用用户名和密码进行身份验证的某个网页,那么我是否使用正确的代码进行身份验证? 我使用urllib2做这件事很舒服,但使用urllib3做不到同样的事情。 非常感谢

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。

  • 我的管理员控制器扩展了控制器类,在那里我使用方法加载视图页面并传递保护。config/auth.php也通过添加管理员保护和提供程序进行了修改。在app/Actions/Fortify文件夹中,我添加了AttemptToAuthenticate和ReDirectIfTwoFactorAuthenticate类,并更改了命名空间。我的管理员控制器还扩展了Guard。用户的重定向中间件和管理员的重定向

  • 问题内容: 我可以通过接收到请求的xml 但不是 没有JavaScript错误,没有跨域策略问题。可能是语法错误,但是我找不到合适的教程。有什么建议吗? 问题答案: 我认为您需要纯格式:

  • 您好,我正在寻找一种方法,在用户建立WebSocket连接时对其进行身份验证,如果用户未通过身份验证,则关闭连接。我使用Dropwizard框架和氛围进行WebSocket连接。下面是我使用的示例。如果我可以在连接建立时使用Dropwizard提供的“@Auth”注释进行身份验证,那就太好了。