繁体   English   中英

使用 Workload Identity 从 GKE 向 Google Cloud Firestore 进行身份验证

[英]Authenticating to Google Cloud Firestore from GKE with Workload Identity

我正在尝试编写一个简单的后端来访问我的 Google Cloud Firestore,它位于 Google Kubernetes 引擎中。 在我的本地,我使用以下代码对 Firestore 进行身份验证,如 Google 文档中所述。

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"角色的服务帐户获得的。

所以,在本地,我的代码运行良好。 我可以到达我的 Firestore 并做我需要做的一切。 但是,一旦我部署到 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。

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

'Getting metadata from plugin failed with error: Could not refresh access token: A Not Found error was returned while attempting to retrieve an accesstoken for the Compute Engine built-in service account. This may be because the Compute Engine instance does not have any permission scopes specified: Could not refresh access token: Unsuccessful response status code. Request failed with status code 404'

对这个问题的粗略搜索似乎没有返回任何与我想要完成的事情相关的内容,所以我回到了原点。

我认为你最初的假设是正确的。 如果您仍然必须指定范围,Workload Identity 无法正常运行,在您链接的 Workload 文章中。 不使用范围。

我一直在努力解决同样的问题,并确定了三种在 pod 中获取经过身份验证的凭据的方法。


1. Workload Identity (基本上是上面的 Workload Identity 文章,添加了一些部署细节)

这种方法是首选的,因为它允许集群中的每个 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}

然后我创建我的部署,并设置 k8sServiceAccount (设置服务帐户是我缺少的部分)

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 只需要“cloud-platform”,实时数据库还需要“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:云数据存储用户(Datastore)
  • 实时数据库:Firebase 实时数据库管理员(Firebase 产品)
  • 存储:存储 Object 管理员(云存储)

准备结束这个问题。

以防万一有人偶然发现它,这就是为我解决的问题。

1.) 我重新按照上面 Google 文档链接中的步骤操作,这解决了我的 pod 无法启动的问题。

2.) 至于我的更新,我重新创建了我的集群并授予它 Cloud Datasource 权限。 我曾假设权限与 function 所需的 Workload Identity 是分开的。 我错了。

我希望这可以帮助别人。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM