如何在GKE(Go)中为Google云存储对象生成签名URL 目标:
在GKE POD中生成签名URL,而无需手动注入服务帐户JSON密钥。生成它们的语法需要服务帐户电子邮件和私钥如何在GKE(Go)中为Google云存储对象生成签名URL 目标:,go,google-cloud-platform,google-cloud-storage,google-kubernetes-engine,Go,Google Cloud Platform,Google Cloud Storage,Google Kubernetes Engine,在GKE POD中生成签名URL,而无需手动注入服务帐户JSON密钥。生成它们的语法需要服务帐户电子邮件和私钥 //导入“cloud.google.com/go/storage” url,err:=storage.SignedURL(bucketName、objectName和storage.SignedURLOptions{ ContentType:ContentType, GoogleAccessID:saEmail, 私钥:saPrivateKey, }) 换句话说,我想从GKE节点中自
//导入“cloud.google.com/go/storage”
url,err:=storage.SignedURL(bucketName、objectName和storage.SignedURLOptions{
ContentType:ContentType,
GoogleAccessID:saEmail,
私钥:saPrivateKey,
})
换句话说,我想从GKE节点中自动可用的默认凭据加载saEmail
和saPrivateKey
尝试:
ctx:=context.Background()
//为简洁起见,错误被忽略
//导入“golang.org/x/oauth2/google”
creds,u:=google.FindDefaultCredentials(ctx、storage.ScopeReadWrite)
cfg,\:=google.JWTConfigFromJSON(creds.JSON)
url,:=storage.SignedURL(bucketName、objectName和storage.SignedURLOptions{
ContentType:ContentType,
GoogleAccessID:cfg.Email,
PrivateKey:cfg.PrivateKey,
})
当我在GKE pod中运行google.FindDefaultCredentials()
时,结果JSON为空
环境:
1.13Go
1.14.10-GKE.36GKE
v0.58.0cloud.google.com/go
v1.8.0cloud.google.com/go/storage
- 将服务帐户密钥写入文件,并将
GOOGLE\u应用程序\u凭据设置为其路径。完成此操作后,
将加载电子邮件和私钥google.FindDefaultCredentials()
- 将服务帐户密钥作为字符串传递到pod中,并使用
对其进行解析google.JWTConfigFromJSON()
curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
或标识令牌(访问群体在参数中)
因此,在没有任何秘密或私钥的情况下,库能够生成用于访问外部API的令牌(访问或标识)
但是,元数据服务器不提供秘密(私钥),您不能将其用于生成已签名的URL
此处需要服务帐户密钥文件
您有几种方法可以安全地将其提供给pod
- 标准K8S方式:
- GCP托管解决方案:。由于有了元数据服务器,您可以实例化secret manager客户端并获取您的机密(您的服务帐户密钥文件),然后像以前一样使用它。另一种选择是,我,因此,您只需使用env var,而不必与秘密管理服务进行交互
- 您可以在集群上部署服务时生成它。就像这样,你不必存储秘密,它每次都是动态生成的
- 您可以在容器启动时生成密钥,将其设置在服务帐户中,并将其保存在内存中李>
但是,您还需要考虑如何清除旧的和无用的密钥。要生成签名URL,您需要有一个私钥 当您使用GCP服务(这里是计算实例,K8S集群的节点,但云运行、云函数等其他GCP服务也是如此)并且您使用默认凭证(并且没有定义GOOGLE_应用程序_凭证env var)时,库使用 元数据服务器允许您生成访问令牌
curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
或标识令牌(访问群体在参数中)
因此,在没有任何秘密或私钥的情况下,库能够生成用于访问外部API的令牌(访问或标识)
但是,元数据服务器不提供秘密(私钥),您不能将其用于生成已签名的URL
此处需要服务帐户密钥文件
您有几种方法可以安全地将其提供给pod
- 标准K8S方式:
- GCP托管解决方案:。由于有了元数据服务器,您可以实例化secret manager客户端并获取您的机密(您的服务帐户密钥文件),然后像以前一样使用它。另一种选择是,我,因此,您只需使用env var,而不必与秘密管理服务进行交互
- 您可以在集群上部署服务时生成它。就像这样,你不必存储秘密,它每次都是动态生成的
- 您可以在容器启动时生成密钥,将其设置在服务帐户中,并将其保存在内存中李>
但是,您还需要考虑如何清理旧的和无用的钥匙。我遇到了同样的问题,并在这里找到了解决方案: TL;博士 我
//import (
// "cloud.google.com/go/storage"
// credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
// credentials "cloud.google.com/go/iam/credentials/apiv1"
//)
ctx := context.Background()
saEmail := "your-service-account-email@something-something.iam.gserviceaccount.com"
c, err := credentials.NewIamCredentialsClient(ctx)
if err != nil {
panic(err)
}
url, err := storage.SignedURL(bucketName, objectName, &storage.SignedURLOptions{
ContentType: contentType,
GoogleAccessID: saEmail,
SignBytes: func(b []byte) ([]byte, error) {
req := &credentialspb.SignBlobRequest{
Payload: b,
Name: saEmail,
}
resp, err := c.SignBlob(ctx, req)
if err != nil {
panic(err)
}
return resp.SignedBlob, err
}
})