gpt4 book ai didi

node.js - 如何通过 GKE pod 访问 Google Cloud Storage 中的文件

转载 作者:行者123 更新时间:2023-12-02 12:25:09 25 4
gpt4 key购买 nike

我正在尝试使用 Axios 客户端在我的 Node.js 应用程序中获取 Google Cloud Storage (GCS) 的图像文件。在使用我的 PC 的开发模式下,我传递了一个 Bearer Token,并且一切正常。

但是,我需要在 Google Kubernetes Engine (GKE) 上托管的集群中的生产环境中使用它。

我制作了创建服务帐户 (GSA) 的推荐教程,然后我通过工作负载身份方法使用 kubernetes 帐户 (KSA) 进行了介绍,但是当我尝试通过我的应用程序的一个端点获取文件时,我收到:

{"statusCode":401,"message":"Unauthorized"}

还缺什么?


更新:我做了什么:

  1. 创建 Google 服务帐户

https://cloud.google.com/iam/docs/creating-managing-service-accounts

  1. 创建 Kubernetes 服务帐户
# gke-access-gcs.ksa.yaml file

apiVersion: v1
kind: ServiceAccount
metadata:
name: gke-access-gcs
kubectl apply -f gke-access-gcs.ksa.yaml
  1. 关联 KSA 和 GSA
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
  1. 记下 KSA 并完成 KSA 和 GSA 之间的链接
kubectl annotate serviceaccount \
--namespace k8s_namespace \
ksa_name \
iam.gke.io/gcp-service-account=gsa_name@gsa_project.iam.gserviceaccount.com
  1. 设置读写角色:
gcloud projects add-iam-policy-binding project-id \
--member=serviceAccount:gsa-account@project-id.iam.gserviceaccount.com \
--role=roles/storage.objectAdmin
  1. 测试访问:
kubectl run -it \
--image google/cloud-sdk:slim \
--serviceaccount ksa-name \
--namespace k8s-namespace \
workload-identity-test

上面的命令工作正常。请注意,已传递 --serviceaccountworkload-identity。这对 GKE 有必要吗?

PS:不知道有没有影响,我在项目中使用的是带代理的SQL Cloud

最佳答案

编辑

问题中描述的问题与 axios 客户端不使用 Workload Identity 的应用程序默认凭证(作为官方 Google 库)机制有关。利用。 ADC 检查:

  • If the environment variable GOOGLE_APPLICATION_CREDENTIALS is set, ADC uses the service account file that the variable points to.
  • If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn't set, ADC uses the default service account that Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run, and Cloud Functions provide.

-- Cloud.google.com: Authentication: Production

这意味着 axios 客户端将需要回退到 Bearer token 身份验证方法以针对 Google Cloud Storage 进行身份验证。

使用Bearer token认证在官方文档中描述如下:

API authentication

To make requests using OAuth 2.0 to either the Cloud Storage XML API or JSON API, include your application's access token in the Authorization header in every request that requires authentication. You can generate an access token from the OAuth 2.0 Playground.

Authorization: Bearer OAUTH2_TOKEN

The following is an example of a request that lists objects in a bucket.

JSON API

Use the list method of the Objects resource.

GET /storage/v1/b/example-bucket/o HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg

-- Cloud.google.com: Storage: Docs: Api authentication


我包含了使用 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 服务帐户是否与您的 Google 服务帐户相关联。
  • 检查示例工作负载在连接到 API 时是否使用了正确的 Google 服务帐户
  • 检查您的 Google 服务帐户 是否具有访问您的存储桶 的正确权限。

也可以按照官方文档:


假设:

  • 项目 (ID) 命名为:awesome-project <- 这只是示例
  • Kubernetes 命名空间命名为:bucket-namespace
  • Kubernetes 服务帐户名为: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 service account created earlier should be present in the output!

还需要将服务帐户的权限添加到存储桶中。您可以:

  • 使用云控制台
  • 运行:$ 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!

关于node.js - 如何通过 GKE pod 访问 Google Cloud Storage 中的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63664800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com