在Docker Container内的Container OS上访问Google Cloud服务帐户凭据

Bri*_*unt 11 google-compute-engine google-cloud-platform google-container-registry google-container-os google-iam

在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.
Run Code Online (Sandbox Code Playgroud)

如果凭据在VM上,那么Doc​​ker可以安装这些凭据.通常凭证将在.config/gcloud/,并执行此操作docker run -v ~/.config/gcloud:~/.config/gcloud image.容器操作系统中是否有这样的凭证,特别是因为缺少这些凭证,这一点并不明显gcloud.

如果VM上的凭据失败并且可安装,则选项似乎包括:

  1. 将凭据放在容器元数据/环境变量中;
  2. .json然后,为服务帐户创建凭证文件
    1. 将其上传到VM,然后挂载; 要么
    2. 添加.json到容器;
  3. 运行Docker容器(例如cloud-sdk-docker)获取凭据并通过例如共享挂载分区与主机共享.理想情况下,这将是gcloud auth activate-service-account

是否有规范或最佳实践方法为Docker容器提供VM项目的服务帐户凭据?

Google Cloud已经拥有了一个安全策略模型,即所需的模型:项目中的VM应具有服务帐户提供的访问权限.为了避免复杂性以及错误配置或事故的可能性,正确的解决方案将采用此现有安全模型,即不涉及创建,下载,分发和维护凭证文件.

感觉这将是一个需要用COS,Docker和Kubernetes解决的常规问题,所以我假设我错过了一些直截了当的东西 - 但是解决方案对我来说并不明显.

编辑 - 注意set-service-account API - 这个问题可以简化为"你如何在Container OS中使用set-service-account API?" 如果不可能(因为Container OS缺乏gcloudgsutil),我认为应该注意这一点,以便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]
Run Code Online (Sandbox Code Playgroud)

问题确实是在VM实例的API中设置的范围,特别datastore是为默认帐户禁用了API(在VM 的标题Cloud API访问范围下).可以找到范围和必要的datastore行如下:

> gcloud compute instances describe test-instance
...
serviceAccounts:
- email: *****-compute@developer.gserviceaccount.com
  scopes:
  - https://www.googleapis.com/auth/datastore
  ...
...
Run Code Online (Sandbox Code Playgroud)

请注意,服务帐户本身具有数据存储区的权限(因此,通常可以使用服务密钥的json凭据密钥访问数据存储区).服务帐户权限受VM范围的限制.

Jor*_*les 7

通常的身份验证方式是出现在Google云端SDK Docker自述文件中.

从COS实例中运行一次:

docker run -ti --name gcloud-config google/cloud-sdk gcloud auth login
Run Code Online (Sandbox Code Playgroud)

这会将您的凭据存储在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
Run Code Online (Sandbox Code Playgroud)

服务帐户通常意味着使用他们必须从某个地方获取的凭据集,密钥文件,环境变量或令牌:

gcloud auth activate-service-account

如果您希望gcloud(以及Cloud SDK中的其他工具)使用服务帐户凭据发出请求,请使用此命令从包含私有授权密钥的文件导入这些凭据,并激活它们以在gcloud中使用.此命令提供与gcloud auth login相同的功能,但用于使用服务帐户而不是Google用户凭据.

此外,最佳做法是为不同的实例创建不同的服务帐户,而不是获取默认服务帐户的密钥并使用它:

通常,Google建议每个需要调用Google API的实例应作为服务帐户运行,并具有该实例执行其工作所需的最低权限.实际上,这意味着您应该使用以下过程为您的实例配置服务帐户:

1 - 创建新的服务帐户,而不是使用计算引擎默认服务帐户.
2 - 仅为该服务帐户授予IAM角色所需的资源.
3 - 将实例配置为以该服务帐户运行.
4 - 授予实例 https://www.googleapis.com/auth/cloud-platform范围.
5 - 避免授予超出必要的访问权限,并定期检查您的服务帐户权限,以确保它们是最新的.

UPDATE

我不确定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].
Run Code Online (Sandbox Code Playgroud)

  • 谢谢乔迪。这里有几点。1. `gcloud auth login` 将授予个人凭据,这是必须避免的。2. 谷歌提供了[set-service-account API](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes),显然是为了确定凭据——但是如果这些凭据不可用,那么带有容器操作系统的 API 有什么意义呢?我会更新问题以注意这一点。感谢您的帮助。 (2认同)
  • 嗨 Jordi,感谢您的更新。所以我想要的是 Docker 容器继承其实例的权限/服务帐户。 (2认同)