btd*_*337 6 node.js google-cloud-storage kubernetes google-kubernetes-engine axios
我正在尝试使用 Axios 客户端在 Node.js 应用程序中获取 Google Cloud Storage (GCS) 的图像文件。在使用我的 PC 的开发模式下,我传递了一个不记名令牌,并且一切正常。
但是,我需要在 Google Kubernetes Engine (GKE) 托管的集群的生产中使用它。
我推荐了创建服务帐户(GSA)的教程,然后通过工作负载身份方法与 kubernetes 帐户(KSA)建立了联系,但是当我尝试通过应用程序上的一个端点获取文件时,我收到:
{"statusCode":401,"message":"Unauthorized"}
Run Code Online (Sandbox Code Playgroud)
缺少什么?
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
Run Code Online (Sandbox Code Playgroud)
kubectl apply -f gke-access-gcs.ksa.yaml
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
kubectl annotate serviceaccount \
--namespace k8s_namespace \
ksa_name \
iam.gke.io/gcp-service-account=gsa_name@gsa_project.iam.gserviceaccount.com
Run Code Online (Sandbox Code Playgroud)
gcloud projects add-iam-policy-binding project-id \
--member=serviceAccount:gsa-account@project-id.iam.gserviceaccount.com \
--role=roles/storage.objectAdmin
Run Code Online (Sandbox Code Playgroud)
kubectl run -it \
--image google/cloud-sdk:slim \
--serviceaccount ksa-name \
--namespace k8s-namespace \
workload-identity-test
Run Code Online (Sandbox Code Playgroud)
上面的命令工作正常。请注意,已通过--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
描述如下:
API认证
要使用 OAuth 2.0 向 Cloud Storage XML API 或 JSON API发出请求,请在每个需要身份验证的请求的标头中包含应用程序的访问令牌
Authorization
。您可以从OAuth 2.0 Playground生成访问令牌 。Run Code Online (Sandbox Code Playgroud)Authorization: Bearer OAUTH2_TOKEN
以下是列出存储桶中的对象的请求示例。
使用 对象资源的列表方法。
Run Code Online (Sandbox Code Playgroud)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
(需要):
Authorization: Bearer OAUTH2_TOKEN
Run Code Online (Sandbox Code Playgroud)
我在下面留下了带有 Node.js 官方库代码片段的 Workload Identity 设置示例,因为它可能对其他社区成员有用。
发布这个答案是因为我设法使用Workload Identity
一个简单的nodejs
应用程序来发送和检索数据GCP bucket
。
我添加了一些用于解决潜在问题的要点。
GKE
集群是否已Workload Identity
启用。Kubernetes service account
与您的 相关联Google Service account
。Google Service account
检查连接到 API 时示例工作负载是否使用正确。Google Service account
具有访问您的bucket
.也可以参考官方文档:
假如说:
awesome-project
<-这只是示例bucket-namespace
bucket-service-account
google-bucket-service-account
workload-bucket-example
<-这只是示例我已经包含了命令:
GET /storage/v1/b/example-bucket/o HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg
Run Code Online (Sandbox Code Playgroud)
使用上面链接的指南检查对 API 进行身份验证的服务帐户:
$ kubectl run -it --image google/cloud-sdk:slim --serviceaccount bucket-service-account --namespace bucket-namespace workload-identity-test
的输出$ gcloud auth list
应显示:
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!
}
);
Run Code Online (Sandbox Code Playgroud)
之前创建的 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
可以使用以下代码来下载文件:
$ 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
Run Code Online (Sandbox Code Playgroud)
该代码完全复制自:
运行此代码应产生输出:
Credentialed Accounts
ACTIVE ACCOUNT
* google-bucket-service-account@AWESOME-PROJECT.iam.gserviceaccount.com
To set the active account, run:
$ gcloud config set account `ACCOUNT`
Run Code Online (Sandbox Code Playgroud)
// 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));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11648 次 |
最近记录: |