在 Docker 容器内的容器操作系统上访问 Google Cloud 服务帐户凭据



使用 Google Cloud Compute 上的容器优化操作系统 (COS),从 Docker 容器中访问虚拟机项目的默认服务帐户凭据的最佳方式是什么?

$ 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 上且可装载,则选项似乎包括:

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

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

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

感觉这将是一个需要用 COS、Docker 和 Kubernetes 解决的常规问题,所以我认为我错过了一些简单的东西——但从文档中我并没有明显找到解决方案。

编辑 — 注意设置服务帐户API — 这个问题可以简化为"如何在容器操作系统中使用设置服务帐户 API? 如果不可能(因为容器操作系统缺乏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]

问题确实出在 API 中为 VM 实例设置的范围,特别是默认帐户禁用了datastoreAPI(在 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 身份验证激活服务帐户

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

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

一般来说,谷歌建议每个需要调用的实例 谷歌 API 应作为服务帐号运行,最低 该实例完成其工作所需的权限。在实践中, 这意味着您应该为实例配置服务账户 通过以下过程:

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

更新

我不确定设置服务帐户是否满足您的需求/需求。有了它,您可以更改实例使用的服务帐户(但必须停止该实例,因此您不能使用它来更改正在更改的实例的服务帐户)。但是,您可以将其通常用于其他实例,请参阅:

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].

我认为这个问题在今天的日期并不完全有效。因此,我想分享我的2美分。

对于容器优化操作系统,如果 VM 使用默认服务帐户运行,则会在 cloud-sdk 容器中自动配置相同的帐户。

user@instance-1 ~ $ docker run -it gcr.io/google.com/cloudsdktool/cloud-sdk:alpine /bin/bash
bash-5.1# gcloud config list
[component_manager]
disable_update_check = true
[core]
account = *************-compute@developer.gserviceaccount.com
disable_usage_reporting = true
project = my-project-id
[metrics]
environment = github_docker_image
Your active configuration is: [default]
bash-5.1# gcloud compute instances list
NAME        ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
instance-1  us-central1-a  e2-medium                  10.128.0.3   34.**.**.***  RUNNING

因此,无需执行gcloud auth login,可以直接执行所有gcloud命令,前提是默认服务帐户具有权限并且 VM 已显式启用特定 API。

但是,如果 VM 在创建期间选择了no service account选项运行,则此用例有效。

我认为这是相关的计算引擎配置。DevopsTux已经说过了

This is related to the instance scopes, 
not the service account permissions. 
Set the instance scope to "allow full access to all cloud APIs" 
and try again. Here is how: cloud.google.com/compute/docs/access/… – 
DevopsTux May 17, 2018 at 12:48
  1. 停止实例。
  2. 更改访问范围,如下所示。

在此处输入图像描述

最新更新