GCP Firestore:服务器请求因 GKE 权限缺失或不足而失败

时间:2021-06-07 02:21:03

标签: kubernetes google-cloud-platform google-cloud-firestore google-kubernetes-engine kubernetes-secrets

我正在尝试从 GKE Con​​tainer 上运行的代码连接到 Firestore。简单的 REST GET api 工作正常,但是当我从读/写访问 Firestore 时,我的权限丢失或不足。

An unhandled exception was thrown by the application.
Info
2021-06-06 21:21:20.283 EDT
      Grpc.Core.RpcException: Status(StatusCode="PermissionDenied", Detail="Missing or insufficient permissions.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1623028880.278990566","description":"Error received from peer ipv4:172.217.193.95:443","file":"/var/local/git/grpc/src/core/lib/surface/call.cc","file_line":1068,"grpc_message":"Missing or insufficient permissions.","grpc_status":7}")
         at Google.Api.Gax.Grpc.ApiCallRetryExtensions.<>c__DisplayClass0_0`2.<<WithRetry>b__0>d.MoveNext()

更新 我正在尝试使用服务帐户凭据向 pod 提供机密。 这是 k8 文件,它在没有提供任何机密的情况下将 pod 部署到集群中,不会出现任何问题,并且我可以执行不会触发 Firestore 的 Get 操作,并且它们工作正常。

kind: Deployment
apiVersion: apps/v1
metadata:
  name: foo-worldmanagement-production
spec:
  replicas: 1
  selector:
    matchLabels:
       app: foo
       role: worldmanagement
       env: production
  template:
    metadata:
      name: worldmanagement
      labels:
        app: foo
        role: worldmanagement
        env: production
    spec:
      containers:
      - name: worldmanagement
        image: gcr.io/foodev/foo/master/worldmanagement.21
        resources:
          limits:
            memory: "500Mi"
            cpu: "300m"
        imagePullworld: Always
        readinessProbe:
          httpGet:
            path: /api/worldManagement/policies
            port: 80
        ports:
        - name: worldmgmt
          containerPort: 80

现在,如果我尝试挂载 secret,pod 永远不会完全创建,并且最终会失败

kind: Deployment
apiVersion: apps/v1
metadata:
  name: foo-worldmanagement-production
spec:
  replicas: 1
  selector:
    matchLabels:
       app: foo
       role: worldmanagement
       env: production
  template:
    metadata:
      name: worldmanagement
      labels:
        app: foo
        role: worldmanagement
        env: production
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: firestore-key   
      containers:
      - name: worldmanagement
        image: gcr.io/foodev/foo/master/worldmanagement.21
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/key.json        
        resources:
          limits:
            memory: "500Mi"
            cpu: "300m"
        imagePullworld: Always
        readinessProbe:
          httpGet:
            path: /api/worldManagement/earth
            port: 80
        ports:
        - name: worldmgmt
          containerPort: 80

我尝试部署 sample application 并且工作正常。

如果我只保留以下 yaml 文件,容器将正确部署

- name: google-cloud-key
            secret:
              secretName: firestore-key 

但是一旦我将以下内容添加到 yaml 中,它就会失败

    volumeMounts:
    - name: google-cloud-key
      mountPath: /var/
    env:
    - name: GOOGLE_APPLICATION_CREDENTIALS
      value: /var/key.json      

而且我可以在 GCP 事件中看到容器无法找到 google-cloud-key。知道如何解决此问题,即为什么我无法安装机密,如果需要,我可以冲入 pod。

我正在使用由

组成的多阶段 docker 文件
From mcr.microsoft.com/dotnet/sdk:5.0 AS build 
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime

谢谢

1 个答案:

答案 0 :(得分:1)

看起来他们的密钥本身可能无法正确地对 pod 可见。我将首先使用 kubectl exec --stdin --tty <podname> -- /bin/bash 进入 pod,并确保 /var/key.json(根据您的配置)可访问且具有正确的凭据。

以下是挂载密钥的好方法:

volumeMounts:
- name: google-cloud-key
  mountPath: /var/run/secret/cloud.google.com
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
  value: /var/run/secret/cloud.google.com/key.json

以上假设您的秘密是使用如下命令创建的:

kubectl --namespace <namespace> create secret generic firestore-key --from-file key.json

此外,检查您的 Workload Identity 设置也很重要。 Workload Identity | Kubernetes Engine Documentation 有一个很好的部分。