google-cloud-platform - 在 Docker Container 内的 Container OS 上访问 Google Cloud 服务帐户凭据
问题描述
在 Google Cloud Compute 上使用容器优化操作系统(COS),从 Docker 容器中访问 VM 项目默认服务帐户凭据的最佳方法是什么?
$ gcloud compute instances create test-instance \
--image=cos-stable --image-project=cos-cloud
$ ssh (ip of the above)
# gcloud ...
Command not found
# docker run -ti google/cloud-sdk:alpine /bin/sh
# gcloud auth activate-service-account
... --key-file: Must be specified.
如果凭据在 VM 上,那么 Docker 可以挂载这些凭据。通常凭证会在 中.config/gcloud/
,并使用docker run -v ~/.config/gcloud:~/.config/gcloud image
. 目前尚不清楚容器操作系统中是否以及在何处提供此类凭据,特别是因为缺少gcloud
.
如果凭证在 VM 上且可挂载失败,选项似乎包括:
- 将凭证放入容器元数据/环境变量中;
- 为服务帐户创建一个
.json
凭据文件,然后- 上传到虚拟机,然后挂载;或者
- 添加
.json
到容器中;
- 运行一个 Docker 容器(例如cloud-sdk-docker),它获取凭据并通过例如共享挂载分区与主机共享它们。理想情况下,这将与
gcloud auth activate-service-account
是否有规范或最佳实践方法为 Docker 容器提供 VM 项目的服务帐户凭据?
谷歌云已经有一个安全策略模型,这是理想的模型:项目中的虚拟机应该具有服务帐户提供的访问权限。为避免复杂性和错误配置或事故的可能性,正确的解决方案将采用这种现有的安全模型,即不涉及创建、下载、分发和维护凭证文件。
感觉这将是一个需要用 COS、Docker 和 Kubernetes 解决的常规问题,所以我认为我错过了一些简单的东西——但是从文档中我看不出解决方案。
编辑——注意set-service-account API——这个问题可以简化为“你如何在容器操作系统中使用 set-service-account API?” 如果不可能(因为 Container OS 缺少gcloud
和gsutil
),我认为应该注意这一点,以便 VM 用户可以做出相应的计划。
编辑对于接下来的人来说:
为了复制这个问题,我使用了:
[local] $ ssh test-instance-ip
[test-instance] $ docker run -it gcr.io/google-appengine/python /bin/bash
[test-instance] $ pip install --upgrade google-cloud-datastore
[test-instance] $ python
>>> from google.cloud import datastore
>>> datastore_client = datastore.Client()
>>> q = datastore.query.Query(datastore_client, kind='MODEL-KIND')
>>> list(q.fetch())
[... results]
问题确实是在 API 中为 VM 实例设置的范围,特别datastore
是默认帐户的 API 被禁用(在 VM 的云 API 访问范围标题下)。可以找到范围和必要的datastore
行,如下所示:
> gcloud compute instances describe test-instance
...
serviceAccounts:
- email: *****-compute@developer.gserviceaccount.com
scopes:
- https://www.googleapis.com/auth/datastore
...
...
请注意,服务帐户本身有权访问数据存储(因此通常可以使用服务密钥的 json 凭证密钥访问数据存储)。服务帐户权限受 VM 范围的限制。
解决方案
通常的身份验证方式是出现在Google cloud SDK Docker 自述文件中的方式。
在 COS 实例中运行一次:
docker run -ti --name gcloud-config google/cloud-sdk gcloud auth login
这会将您的凭据存储在gcloud-config
容器卷中。
这个卷应该只安装有你想访问你的凭证的容器,这可能不是任何东西cloud-sdk
docker run --rm -ti --volumes-from gcloud-config google/cloud-sdk:alpine gcloud compute instances create test-docker --project [PROJECT]
Created [https://www.googleapis.com/compute/v1/projects/project/zones/us-east1-b/instances/test-docker].
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
test-docker us-east1-b n1-standard-1 10.142.0.8 X.X.X.X RUNNING
服务帐户通常意味着使用他们自己的一组凭据,他们必须从某个地方获取这些凭据,作为密钥文件,以及环境变量或令牌:
如果您希望 gcloud(和 Cloud SDK 中的其他工具)使用服务帐户凭据发出请求,请使用此命令从包含私有授权密钥的文件中导入这些凭据,并激活它们以在 gcloud 中使用。此命令的功能与 gcloud auth login 相同,但用于使用服务帐户而不是您的 Google 用户凭据。
此外,最佳实践是为不同的实例创建不同的服务帐户,而不是获取默认服务帐户的密钥并使用它:
一般来说,Google 建议需要调用 Google API 的每个实例都应作为服务帐户运行,并具有该实例完成其工作所需的最低权限。实际上,这意味着您应该使用以下过程为您的实例配置服务帐户:
1 - 创建一个新的服务帐号,而不是使用 Compute Engine 默认服务帐号。
2 - 仅为该服务账户授予其需要的资源的 IAM 角色。
3 - 将实例配置为作为该服务帐户运行。
4 - 授予实例 https://www.googleapis.com/auth/cloud-platform范围。
5 - 避免授予不必要的访问权限,并定期检查您的服务帐户权限以确保它们是最新的。
更新
我不确定 set-service-account 能满足您的需要/想要的。使用它,您可以更改实例使用的服务帐户(但必须停止该实例,因此您不能使用它来更改服务帐户以防止正在更改的实例)。但是,您可以在其他情况下正常使用它,请参阅:
jordim@cos ~ $ docker run --rm -ti --volumes-from gcloud-config google/cloud-sdk:alpine gcloud compute instances set-service-account instance-1 --service-account xx-compute@developer.gserviceaccount.com
Did you mean zone [us-east1-b] for instance: [instance-1] (Y/n)?
Updated [https://www.googleapis.com/compute/v1/projects/XX/zones/us-east1-b/instances/instance-1].
推荐阅读
- typescript - 在 TypeScript 中导入外部 JavaScript 代码 - 找不到模块或其对应的类型声明
- shell - 如何使用 / 在 sed
- python - 查找图像中一条线上的像素坐标
- security - ImagickException:零大小的图像字符串传递
- c# - URL 忽略 GET 请求中的参数 (ASP.NET)
- vba - 如何使用“动态”文本框触发事件?
- javascript - Linking.addEventListener 不工作(使用博览会)
- macos - MacOS init 上的 nvm 说:zsh compinit:不安全的目录,为列表运行 compaudit
- python - 如何从另一个列表中添加嵌套字典(NodeDataView)中的键、值?
- javascript - Vue-Router 不在单页应用程序中重新路由(Vue/Laravel)