繁体   English   中英

如何通过 GKE pod 访问 Google Cloud Storage 中的文件

[英]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"}

缺少什么?


更新:我所做的:

  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 检查:

  • 如果设置了环境变量GOOGLE_APPLICATION_CREDENTIALS ,ADC 将使用该变量指向的服务帐户文件。
  • 如果未设置环境变量GOOGLE_APPLICATION_CREDENTIALS ,ADC 将使用 Compute Engine、Google Kubernetes Engine、App Engine、Cloud Run 和 Cloud Functions 提供的默认服务帐号。

-- Cloud.google.com:身份验证:生产

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

官方文档中描述了使用Bearer token的身份验证如下:

接口认证

要使用 OAuth 2.0 向 Cloud Storage XML APIJSON API发出请求,请在每个需要身份验证的请求的Authorization标头中包含您应用的访问令牌。 您可以从OAuth 2.0 Playground生成访问令牌。

 Authorization: Bearer OAUTH2_TOKEN

以下是列出存储桶中对象的请求示例。

JSON API

使用对象资源的 列表方法。

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

-- Cloud.google.com:存储:文档:Api 身份验证


我已经包含了使用 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相关联。
  • 检查示例工作负载在连接到 API 时是否使用了正确的Google Service account
  • 检查您的Google Service account是否具有访问您的bucket正确权限。

也可以参考官方文档:


假如说:

  • 项目 (ID) 名为: awesome-project <-这只是示例
  • Kubernetes 命名空间命名为: bucket-namespace
  • Kubernetes 服务帐户名为: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM