简体   繁体   English

无法使用默认服务帐户和Google云库从Google Kubernetes Engine访问Google Cloud Storage

[英]Unable to access Google Cloud Storage from Google Kubernetes Engine using default service account and google cloud libraries

I wrote an application that has a function to upload image through Google Kubernetes Engine using go lang. 我编写了一个应用程序,该应用程序具有使用go lang通过Google Kubernetes Engine上传图像的功能。 Everything else works fine, but I kept running into problems when I try to write image to Google Cloud Storage. 一切正常,但是当我尝试将图像写入Google Cloud Storage时,我一直遇到问题。

Here is my code in golang that actually uses the google storage api: 这是我在golang中实际使用google storage api的代码:

func putImage(imageURL string, image multipart.File) bool {
    fmt.Println("Putting into image location : " + imageURL)

    contextBackground := context.Background()
    storageClient, err := storage.NewClient(contextBackground)
    if err != nil {
        fmt.Println("No client.")
        return false
    }

    bucket := storageClient.Bucket("mytestbucketname")
    bucketWriter := bucket.Object(imageURL).NewWriter(contextBackground)
    bucketWriter.ContentType = "image/jpg"
    bucketWriter.CacheControl = "public, max-age=0"

    size, err := io.Copy(bucketWriter, image)
    if err != nil {
        fmt.Println("failed to put image")
        return false
    }

    fmt.Println(size)
    fmt.Println("Successfully put image")
    bucketWriter.Close()
    return true
}

The above function always returns true and size is always greater than 0. However, when I check the bucket, it does not actually have anything inside. 上面的函数始终返回true,并且大小始终大于0。但是,当我检查存储桶时,它实际上没有任何内容。 So I researched around and realized that the default service account only has a read permission to Cloud Storage. 因此,我研究并意识到默认服务帐户仅具有对Cloud Storage的读取权限。 Which is very weird because it should be returning false or size should be 0 or even outputting an error of permission denied. 这很奇怪,因为它应该返回false或size应该为0甚至输出拒绝权限错误。

The official cloud.google.com/go/storage API says Bucket() function returns a BucketHandle that does not actually perform any network operations, which makes sense as to why I was not getting permission denied error (?). 官方cloud.google.com/go/storage API表示Bucket()函数返回的BucketHandle实际上并未执行任何网络操作,这对于为什么我没有收到拒绝权限错误(?)很有道理。 And so I decided to check if I am actually getting anything from the Client or Bucket, just to see if the read permission is working. 因此,我决定检查我是否确实从客户端或存储桶中获取了任何东西,只是为了查看读取权限是否有效。 I added the following code : 我添加了以下代码:

attr, err := bucket.Attrs(contextBackground)
if err != nil {
    fmt.Println(err.Error())
}
fmt.Println("bucket name : " + attr.Name)

And at this point I started to get fatal errors that shuts down my application. 至此,我开始遇到致命错误,从而关闭了我的应用程序。 The error I got when trying to retrieve bucket's attributes is this : 我在尝试检索存储桶的属性时遇到的错误是:

Get https://www.googleapis.com/storage/v1/b/mytestbucketname?alt=json&prettyPrint=false&projection=full: oauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: x509: certificate signed by unknown authority

So I thought I need to add ca certificate to my image. 所以我认为我需要在图像中添加ca证书。 But it just does not sound logical to me because if I was running my image in Google Kubernetes Engine and it was accessing my Google Cloud Storage, given that it already has a default service account with read permission, why would I need a certificate? 但这对我来说听起来不合逻辑,因为如果我在Google Kubernetes Engine中运行映像并且正在访问我的Google Cloud Storage,鉴于它已经具有具有读取权限的默认服务帐户,为什么我需要证书? I made a new cluster with version 1.12.8-gke.10 and made sure to disable issue client certificate and made sure I had read permission to Storage and still got the same error. 我使用1.12.8-gke.10版本创建了一个新集群,并确保禁用了颁发客户端证书,并确保我对存储具有读取权限,但仍然遇到相同的错误。 And I added this line to my docker file and still got the same error: 我将此行添加到我的docker文件中,仍然出现相同的错误:

RUN apk --no-cache add ca-certificates && update-ca-certificates

I've been at it for two days and now I'm running out of ideas. 我已经待了两天了,但是现在我的想法已经用完了。 My question is what am I doing wrong that keeps giving me "x.509 certificate signed by unknown authority" error when trying to access the Storage bucket attributes from Kubernetes Engine when I am using default permission? 我的问题是,当我使用默认权限时,尝试从Kubernetes Engine访问存储桶属性时,为什么会一直显示“由未知授权机构签名的x.509证书”错误? Technically getting bucket attributes is just a read function, which I am supposed to be able to do with default permission right? 从技术上讲,获取存储桶属性只是一个读取功能,我应该能够使用默认权限对吗? If anyone has any ideas or has ever ran into the same problem, please give me some help! 如果有人有任何想法或遇到相同的问题,请给我一些帮助! Thanks! 谢谢!

So I finally figured it out, just leaving this here if anyone ever runs into this problem too. 所以我终于弄清楚了,如果有人也遇到这个问题,就把它留在这里。 It was my mistake of being very careless, but after reading this question : 我很粗心是我的错误,但是在阅读了这个问题之后:

Cannot exchange AccessToken from Google API inside Docker container 无法从Docker容器内的Google API交换AccessToken

I was able to narrow it down to a certificate problem. 我能够将其范围缩小到证书问题。 It was actually because I did not install the ca-certificate properly. 实际上是因为我没有正确安装ca证书。 Because I was using multi stage build in my docker file, I misplaced this line of code : 因为我在docker文件中使用了多阶段构建,所以我放错了以下代码行:

RUN apk --no-cache add ca-certificates && update-ca-certificates

After placing it correctly it worked! 正确放置后,它可以正常工作!

If you are using the default cluster service account, you need to make sure the cluster has sufficient scopes to write to storage . 如果您使用默认的集群服务帐户,则需要确保集群具有足够的作用域来写入storage By default , GKE clusters only have the read scope which blocks write attempts to GCS buckets. 默认情况下 ,GKE集群仅具有读取作用域,该作用域会阻止对GCS存储桶的写入尝试。

gke-default: GKE默认:
https://www.googleapis.com/auth/devstorage.read_only https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring https://www.googleapis.com/auth/monitoring
https://www.googleapis.com/auth/service.management.readonly https://www.googleapis.com/auth/service.management.readonly
https://www.googleapis.com/auth/servicecontrol https://www.googleapis.com/auth/servicecontrol
https://www.googleapis.com/auth/trace.append https://www.googleapis.com/auth/trace.append

Without the write scope enabled, regardless of the credentials, you won't be able to write to buckets. 如果未启用写入作用域,则无论使用何种凭据,都将无法写入存储桶。

Note: You can use the access token only for scopes that you specified when you created the instance. 注意:您只能将访问令牌用于创建实例时指定的范围。 For example, if the instance has been granted only the https://www.googleapis.com/auth/storage-full scope for Google Cloud Storage, then it can't use the access token to make a request to BigQuery. 例如,如果实例仅被授予Google Cloud Storage的https://www.googleapis.com/auth/storage-full范围,则它不能使用访问令牌向BigQuery发出请求。

If you want to bypass scopes, create a custom service account for the application, download the JWT token and mount these credentials directly into your code. 如果要绕过作用域,请为应用程序创建一个自定义服务帐户,下载JWT令牌并将这些凭据直接安装到您的代码中。 This is the recommended method to authenticate your application against Google APIs 建议使用此方法根据Google API对您的应用程序进行身份验证

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法从Google Kubernetes Engine群集访问Google Cloud Datastore - Can't access Google Cloud Datastore from Google Kubernetes Engine cluster 使用 Go 的 Google 云客户端库时出错:未知凭据类型:“impersonated_service_account”? - Getting error using Google cloud client libraries for Go: unknown credential type: "impersonated_service_account"? 在 Golang 中获取谷歌云服务帐户的访问令牌? - Get access token for a google cloud service account in Golang? 使用服务帐户域范围访问的 Google Cloud 函数调用 Gmail API - Google Cloud Function Calling Gmail API Using Service Account Domain-Wide Access 在灵活的环境中将Google App Engine与Google Cloud Storage相连接 - Connect Google App Engine with Google Cloud Storage in flexible environment 无法创建接口来模拟 Google Cloud Storage - Unable to create an interface to mock Google Cloud Storage 使用Go Runtime Google App Engine时出现Google云端存储客户端应用错误 - Google Cloud Storage Client App error using Go Runtime Google App Engine 在Appengine上使用Google Cloud Storage和Golang - Using Google Cloud Storage with Golang on Appengine 无法使用 Golang 使用服务帐户凭据访问 Google 电子表格 - Unable to access Google Spreadsheets with a service account credentials using Golang 在 Google Cloud Storage 中调整图像大小 - Resize image in Google Cloud Storage
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM