当前位置: 首页 > 知识库问答 >
问题:

如何通过GKE pods访问谷歌云存储中的文件

古刚洁
2023-03-14

我正在尝试在我的节点中获取谷歌云存储(GCS)的图像文件。使用Axios客户端的js应用程序。在使用PC的开发模式下,我传递了一个承载令牌,所有这些都正常工作。

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

我做了推荐的教程来创建一个服务号(GSA),然后我vinculed与kubernetes帐户(KSA),通过工作负载身份方法,但当我尝试通过我的应用程序上的一个endpoint获取文件时,我收到:

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

缺什么做什么?

  1. 创建谷歌服务账户

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工作负载标识。这对GKE有必要吗?

PS:我不知道这是否会影响,但我在项目中使用了带有代理的SQL Cloud。

共有1个答案

易星纬
2023-03-14

问题中描述的问题与axios客户端不使用工作负载身份利用的应用程序默认凭据(作为官方谷歌库)机制有关。ADC检查:

  • 如果设置了环境变量GOOGLE_APPLICATION_CREDENTIALS,ADC将使用该变量指向的服务帐户文件

Cloud.google.com:认证:生产

这意味着axios客户端需要退回到承载令牌身份验证方法,才能针对谷歌云存储进行身份验证。

使用承载令牌的身份验证在官方留档中描述如下:

要使用OAuth 2.0向云存储XML API或JSON API发出请求,请在每个需要身份验证的请求的Authorization头中包含应用程序的访问令牌。您可以从OAuth 2.0平台生成访问令牌。

Authorization: Bearer OAUTH2_TOKEN

下面是一个列出bucket中对象的请求示例。

JSON API

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

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

--云。谷歌。com:存储:文档:Api身份验证

我已经提供了一个使用Axios查询云存储的代码片段的基本示例(需要$npm安装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和一个简单的nodejs应用程序,从GCP bucket发送和检索数据,因此发布了这个答案。

我包含了一些解决潜在问题的要点。

  • 检查GKE群集是否启用了工作负载标识
  • 检查您的库伯内特斯服务号是否与您的Google服务帐户相关联。
  • 当连接到API时,检查示例工作负载是否使用正确的Google Service帐户
  • 检查您的Google服务帐户是否具有正确的权限来访问您的代码桶。

您也可以遵循官方文件:

  • 云。谷歌。com:Kubernetes引擎:工作负载标识

假设:

  • 项目(ID)名称:jayy-project

我包含了以下命令:

$ 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--service帐户back-service-帐户--namespace back-namespace工作负载-身份测试

$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`

之前创建的谷歌服务账户应该出现在输出中!

还需要将服务帐户的权限添加到bucket中。你可以:

  • 使用控制
  • 运行:$gsutil iam ch serviceAccount:google bucket服务-account@awesome-项目。国际机械师协会。gserviceaccount。com:角色/存储。管理员gs://workload bucket示例

要从工作负载桶示例下载文件,可以使用以下代码:

// 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));

代码是精确的复制从:

  • 古格里皮斯。dev:NodeJS:Storage

运行此代码应产生一个输出:

root@ubuntu:/# nodejs app.js 
gs://workload-bucket-example/hello.txt downloaded to /hello.txt.
root@ubuntu:/# cat hello.txt 
Hello there!
 类似资料:
  • 我试图设计一个应用程序,从我的谷歌云存储帐户下载适当的声音文件。该应用程序不访问用户帐户,但我自己的帐户。 我的阅读让我相信,最合适的模式是服务账户https://code.google.com/p/google-api-java-client/wiki/OAuth2#Service_Accounts 不幸的是,开发人员决定不提供Android的例子。他们确实提供了一个很好的例子,只是简单的Jav

  • 在学习如何使用谷歌计算引擎和谷歌云存储时,我遇到了一个ACL问题。在我自己的计算机上,使用我自己的SSH凭据,我可以用我的bucket做任何我想做的事情。但是当我使用基于Web的SSH客户机登录到我的compute实例时,我只能从bucket中读取。将数据复制到bucket时会出现“AccessDeniedException:403权限不足”错误。(我正在用Gsutil做所有这些复制实验。) 这对

  • 我正在使用请求将文件上传到谷歌云存储。 请求是: 我得到以下错误作为响应: 我在某处读到,我需要打开谷歌云存储JSON API。是否必须打开谷歌云存储JSON API,或者是否有其他解决方案来修复此错误?

  • 我想从Google Play Analytics获取数据,它存储在Google云存储中。经过研究,洛特发现,并没有直接的API来获取谷歌播放分析报告数据。因此,我找到了通过GoogleAPI客户端PHP库链接访问GooglePlay帐户报告的方法,并遵循了给定的方法。我已经创建了服务帐户,授予了所有者权限,并启用了谷歌云api。 在链接中显示的代码中,如果我使用var_dump($bucket),

  • 我使用Reactjs创建一个网站并将其托管在Firebase上,并使用google cloud函数上的和设置,以处理函数。网站有一个

  • 我正在尝试,在一个Java的环境中,将日志文件以块的形式写入Google云存储。我有一个解析原始日志文件并生成JSON行的进程;我将JSON行存储在缓冲区中,每次缓冲区达到5MGB左右时,我都希望写入GCS中的同一文件,直到原始raw源代码被完全解析。我有一个类似的设置写入AWS3。由于内存问题,大块写作是完成的。 我设法向GCS写入了一个文件,如下所示(gcsService是一个配置了身份验证等