无法从 Google Kubernetes Engine 集群访问 Google Cloud Datastore
Can't access Google Cloud Datastore from Google Kubernetes Engine cluster
我有一个简单的应用程序,可以从数据存储中获取和放入信息。
它无处不在,但是当我从 Kubernetes Engine 集群内部 运行 它时,我得到了这个输出:
Error from Get()
rpc error: code = PermissionDenied desc = Request had insufficient authentication scopes.
Error from Put()
rpc error: code = PermissionDenied desc = Request had insufficient authentication scopes.
我正在使用 cloud.google.com/go/datastore
包和 Go 语言。
我不知道为什么会收到此错误,因为该应用程序在其他任何地方都可以正常工作。
更新:
为了寻找答案,我在 Google 组上找到了这条评论:
In order to use Cloud Datastore from GCE, the instance needs to be
configured with a couple of extra scopes. These can't be added to
existing GCE instances, but you can create a new one with the
following Cloud SDK command:
gcloud compute instances create hello-datastore --project
--zone --scopes datastore userinfo-email
这是否意味着默认情况下我不能使用来自 GKE 的 Datastore?
更新二:
我可以看到在创建我的集群时我没有启用任何权限(默认情况下对大多数服务是禁用的)。我想这就是导致问题的原因:
奇怪的是,我可以很好地使用 CloudSQL,即使它被禁用(使用 cloudsql_proxy
容器)。
所以我在调试这个问题的过程中了解到:
在创建 Kubernetes 集群期间,您可以为将要创建的 GCE 节点指定权限。
例如,如果您在创建期间在集群节点上启用数据存储访问,您将能够直接从 Pods 访问数据存储,而无需进行任何其他设置。
如果您的集群节点权限像我一样对大多数事情(默认设置)禁用,您将需要为每个想要使用 GCP 资源(如数据存储)的应用程序创建一个适当的服务帐户。
另一种方法是使用 gcloud
命令创建一个新的节点池,设置所需的权限范围,然后将所有部署迁移到新的节点池(相当繁琐)。
所以在一天结束时,我通过为我的应用程序创建服务帐户、下载 JSON 身份验证密钥、创建包含该密钥的 Kubernetes 秘密以及数据存储的情况解决了这个问题,我将 GOOGLE_APPLICATION_CREDENTIALS
环境变量设置为安装的秘密 JSON 密钥的路径。
这样当我的应用程序启动时,它会检查 GOOGLE_APPLICATION_CREDENTIALS
变量是否存在,并根据变量指向的 JSON 键验证数据存储区 API 访问权限。
部署 YAML 片段:
...
containers:
- image: foo
name: foo
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /auth/credentials.json
volumeMounts:
- name: foo-service-account
mountPath: "/auth"
readOnly: true
volumes:
- name: foo-service-account
secret:
secretName: foo-service-account
经过几个小时的努力,我也能够连接到数据存储。这是我的结果,大部分来自 Google Docs:
创建服务帐户
gcloud iam service-accounts create [SERVICE_ACCOUNT_NAME]
获取完整的iam账户名
gcloud iam service-accounts list
结果将如下所示:
[SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
为服务帐户授予所有者访问项目的权限
gcloud projects add-iam-policy-binding [PROJECT_NAME] --member serviceAccount:[SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com --role roles/owner
创建密钥文件
gcloud iam service-accounts keys create mycredentials.json --iam-account [SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
创建app-key
秘密
kubectl create secret generic app-key --from-file=credentials.json=mycredentials.json
此 app-key
秘密随后将安装在 deployment.yaml
编辑部署文件
deployment.yaml:
...
spec:
containers:
- name: app
image: eu.gcr.io/google_project_id/springapplication:v1
volumeMounts:
- name: google-cloud-key
mountPath: /var/secrets/google
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/secrets/google/credentials.json
ports:
- name: http-server
containerPort: 8080
volumes:
- name: google-cloud-key
secret:
secretName: app-key
我使用的是简约的 Docker 文件,例如:
FROM SCRATCH
ADD main /
EXPOSE 80
CMD ["/main"]
这让我的 go 应用程序在尝试连接到 GCP 数据存储时处于不确定的 "hanging" 状态。玩了很多次之后,我发现 SCRATCH Docker 图像可能缺少 Google 云库所需的某些环境工具/变量/库。现在可以使用此 Docker 文件:
FROM golang:alpine
RUN apk add --no-cache ca-certificates
ADD main /
EXPOSE 80
CMD ["/main"]
不需要我提供 google credentials 环境变量。该库似乎自动了解它在 运行 中的位置(可能来自 context.Background() ?)并自动使用默认服务帐户,当您在 GKE 上创建集群时,该帐户 Google 会为您创建.
我有一个简单的应用程序,可以从数据存储中获取和放入信息。
它无处不在,但是当我从 Kubernetes Engine 集群内部 运行 它时,我得到了这个输出:
Error from Get()
rpc error: code = PermissionDenied desc = Request had insufficient authentication scopes.
Error from Put()
rpc error: code = PermissionDenied desc = Request had insufficient authentication scopes.
我正在使用 cloud.google.com/go/datastore
包和 Go 语言。
我不知道为什么会收到此错误,因为该应用程序在其他任何地方都可以正常工作。
更新:
为了寻找答案,我在 Google 组上找到了这条评论:
In order to use Cloud Datastore from GCE, the instance needs to be configured with a couple of extra scopes. These can't be added to existing GCE instances, but you can create a new one with the following Cloud SDK command:
gcloud compute instances create hello-datastore --project --zone --scopes datastore userinfo-email
这是否意味着默认情况下我不能使用来自 GKE 的 Datastore?
更新二:
我可以看到在创建我的集群时我没有启用任何权限(默认情况下对大多数服务是禁用的)。我想这就是导致问题的原因:
奇怪的是,我可以很好地使用 CloudSQL,即使它被禁用(使用 cloudsql_proxy
容器)。
所以我在调试这个问题的过程中了解到:
在创建 Kubernetes 集群期间,您可以为将要创建的 GCE 节点指定权限。
例如,如果您在创建期间在集群节点上启用数据存储访问,您将能够直接从 Pods 访问数据存储,而无需进行任何其他设置。
如果您的集群节点权限像我一样对大多数事情(默认设置)禁用,您将需要为每个想要使用 GCP 资源(如数据存储)的应用程序创建一个适当的服务帐户。
另一种方法是使用
gcloud
命令创建一个新的节点池,设置所需的权限范围,然后将所有部署迁移到新的节点池(相当繁琐)。
所以在一天结束时,我通过为我的应用程序创建服务帐户、下载 JSON 身份验证密钥、创建包含该密钥的 Kubernetes 秘密以及数据存储的情况解决了这个问题,我将 GOOGLE_APPLICATION_CREDENTIALS
环境变量设置为安装的秘密 JSON 密钥的路径。
这样当我的应用程序启动时,它会检查 GOOGLE_APPLICATION_CREDENTIALS
变量是否存在,并根据变量指向的 JSON 键验证数据存储区 API 访问权限。
部署 YAML 片段:
...
containers:
- image: foo
name: foo
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /auth/credentials.json
volumeMounts:
- name: foo-service-account
mountPath: "/auth"
readOnly: true
volumes:
- name: foo-service-account
secret:
secretName: foo-service-account
经过几个小时的努力,我也能够连接到数据存储。这是我的结果,大部分来自 Google Docs:
创建服务帐户
gcloud iam service-accounts create [SERVICE_ACCOUNT_NAME]
获取完整的iam账户名
gcloud iam service-accounts list
结果将如下所示:
[SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
为服务帐户授予所有者访问项目的权限
gcloud projects add-iam-policy-binding [PROJECT_NAME] --member serviceAccount:[SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com --role roles/owner
创建密钥文件
gcloud iam service-accounts keys create mycredentials.json --iam-account [SERVICE_ACCOUNT_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
创建
app-key
秘密kubectl create secret generic app-key --from-file=credentials.json=mycredentials.json
此
app-key
秘密随后将安装在 deployment.yaml编辑部署文件
deployment.yaml:
...
spec:
containers:
- name: app
image: eu.gcr.io/google_project_id/springapplication:v1
volumeMounts:
- name: google-cloud-key
mountPath: /var/secrets/google
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/secrets/google/credentials.json
ports:
- name: http-server
containerPort: 8080
volumes:
- name: google-cloud-key
secret:
secretName: app-key
我使用的是简约的 Docker 文件,例如:
FROM SCRATCH
ADD main /
EXPOSE 80
CMD ["/main"]
这让我的 go 应用程序在尝试连接到 GCP 数据存储时处于不确定的 "hanging" 状态。玩了很多次之后,我发现 SCRATCH Docker 图像可能缺少 Google 云库所需的某些环境工具/变量/库。现在可以使用此 Docker 文件:
FROM golang:alpine
RUN apk add --no-cache ca-certificates
ADD main /
EXPOSE 80
CMD ["/main"]
不需要我提供 google credentials 环境变量。该库似乎自动了解它在 运行 中的位置(可能来自 context.Background() ?)并自动使用默认服务帐户,当您在 GKE 上创建集群时,该帐户 Google 会为您创建.