问题描述
我正在尝试从 GKE Container 上运行的代码连接到 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
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
谢谢
解决方法
看起来他们的密钥本身可能无法正确地对 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 有一个很好的部分。