[英]How to access Files in Google Cloud Storage through GKE pods
我正在尝试使用 Axios 客户端在我的 Node.js 应用程序中获取 Google Cloud Storage (GCS) 的图像文件。 在使用我的 PC 的开发模式下,我传递了一个不记名令牌并且一切正常。
但是,我需要在 Google Kubernetes Engine (GKE) 上托管的集群中的生产环境中使用它。
我制作了推荐的教程来创建一个服务帐户 (GSA),然后我通过工作负载身份方法使用 kubernetes 帐户 (KSA),但是当我尝试通过我的应用程序上的一个端点获取文件时,我收到:
{"statusCode":401,"message":"Unauthorized"}
缺少什么?
https://cloud.google.com/iam/docs/creating-managing-service-accounts
# gke-access-gcs.ksa.yaml file
apiVersion: v1
kind: ServiceAccount
metadata:
name: gke-access-gcs
kubectl apply -f gke-access-gcs.ksa.yaml
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:cluster_project.svc.id.goog[k8s_namespace/ksa_name]" \
gsa_name@gsa_project.iam.gserviceaccount.com
kubectl annotate serviceaccount \
--namespace k8s_namespace \
ksa_name \
iam.gke.io/gcp-service-account=gsa_name@gsa_project.iam.gserviceaccount.com
gcloud projects add-iam-policy-binding project-id \
--member=serviceAccount:gsa-account@project-id.iam.gserviceaccount.com \
--role=roles/storage.objectAdmin
kubectl run -it \
--image google/cloud-sdk:slim \
--serviceaccount ksa-name \
--namespace k8s-namespace \
workload-identity-test
上面的命令可以正常工作。 请注意,已通过--serviceaccount
和workload-identity
。 这对 GKE 有必要吗?
PS:我不知道这是否有影响,但我在项目中使用带有代理的 SQL Cloud。
问题中描述的问题与 axios 客户端不使用Workload Identity利用的应用程序默认凭据(作为官方 Google 库)机制有关。 ADC 检查:
- 如果设置了环境变量
GOOGLE_APPLICATION_CREDENTIALS
,ADC 将使用该变量指向的服务帐户文件。- 如果未设置环境变量
GOOGLE_APPLICATION_CREDENTIALS
,ADC 将使用 Compute Engine、Google Kubernetes Engine、App Engine、Cloud Run 和 Cloud Functions 提供的默认服务帐号。
这意味着 axios 客户端将需要回退到不Bearer token
身份验证方法以对 Google Cloud Storage 进行身份验证。
官方文档中描述了使用Bearer token
的身份验证如下:
接口认证
要使用 OAuth 2.0 向 Cloud Storage XML API或JSON API发出请求,请在每个需要身份验证的请求的
Authorization
标头中包含您应用的访问令牌。 您可以从OAuth 2.0 Playground生成访问令牌。Authorization: Bearer OAUTH2_TOKEN
以下是列出存储桶中对象的请求示例。
使用对象资源的 列表方法。
GET /storage/v1/b/example-bucket/o HTTP/1.1 Host: www.googleapis.com Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg
我已经包含了使用 Axios 查询云存储的代码片段的基本示例(需要$ npm install axios
):
const Axios = require('axios');
const config = {
headers: { Authorization: 'Bearer ${OAUTH2_TOKEN}' }
};
Axios.get(
'https://storage.googleapis.com/storage/v1/b/BUCKET-NAME/o/',
config
).then(
(response) => {
console.log(response.data.items);
},
(err) => {
console.log('Oh no. Something went wrong :(');
// console.log(err) <-- Get the full output!
}
);
我在下面留下了带有 node.js 官方库代码片段的 Workload Identity 设置示例,因为它可能对其他社区成员有用。
发布此答案是因为我设法使用Workload Identity
和一个简单的nodejs
应用程序从GCP bucket
发送和检索数据。
我包含了一些要点来解决潜在问题。
GKE
集群是否启用了Workload Identity
。Kubernetes service account
是否与您的Google Service account
相关联。Google Service account
。Google Service account
是否具有访问您的bucket
正确权限。也可以参考官方文档:
假如说:
awesome-project
<-这只是示例bucket-namespace
bucket-service-account
google-bucket-service-account
Google 服务google-bucket-service-account
workload-bucket-example
<-这只是示例的云存储桶我已经包含了以下命令:
$ kubectl create namespace bucket-namespace
$ kubectl create serviceaccount --namespace bucket-namespace bucket-service-account
$ gcloud iam service-accounts create google-bucket-service-account
$ gcloud iam service-accounts add-iam-policy-binding --role roles/iam.workloadIdentityUser --member "serviceAccount:awesome-project.svc.id.goog[bucket-namespace/bucket-service-account]" google-bucket-service-account@awesome-project.iam.gserviceaccount.com
$ kubectl annotate serviceaccount --namespace bucket-namespace bucket-service-account iam.gke.io/gcp-service-account=google-bucket-service-account@awesome-project-ID.iam.gserviceaccount.com
使用上面链接的指南检查对 API 进行身份验证的服务帐户:
$ kubectl run -it --image google/cloud-sdk:slim --serviceaccount bucket-service-account --namespace bucket-namespace workload-identity-test
$ gcloud auth list
的输出应显示:
Credentialed Accounts
ACTIVE ACCOUNT
* google-bucket-service-account@AWESOME-PROJECT.iam.gserviceaccount.com
To set the active account, run:
$ gcloud config set account `ACCOUNT`
之前创建的 Google 服务帐户应该出现在输出中!
还需要将服务帐户的权限添加到存储桶。 您可以:
Cloud Console
$ gsutil iam ch serviceAccount:google-bucket-service-account@awesome-project.iam.gserviceaccount.com:roles/storage.admin gs://workload-bucket-example
要从workload-bucket-example
下载文件,可以使用以下代码:
// Copyright 2020 Google LLC
/**
* This application demonstrates how to perform basic operations on files with
* the Google Cloud Storage API.
*
* For more information, see the README.md under /storage and the documentation
* at https://cloud.google.com/storage/docs.
*/
const path = require('path');
const cwd = path.join(__dirname, '..');
function main(
bucketName = 'workload-bucket-example',
srcFilename = 'hello.txt',
destFilename = path.join(cwd, 'hello.txt')
) {
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function downloadFile() {
const options = {
// The path to which the file should be downloaded, e.g. "./file.txt"
destination: destFilename,
};
// Downloads the file
await storage.bucket(bucketName).file(srcFilename).download(options);
console.log(
`gs://${bucketName}/${srcFilename} downloaded to ${destFilename}.`
);
}
downloadFile().catch(console.error);
// [END storage_download_file]
}
main(...process.argv.slice(2));
代码完全复制自:
运行此代码应该会产生一个输出:
root@ubuntu:/# nodejs app.js
gs://workload-bucket-example/hello.txt downloaded to /hello.txt.
root@ubuntu:/# cat hello.txt
Hello there!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.