将Google服务帐户凭据传递给Docker

我的使用案例与其他使用这个问题的使用案例稍有不同,所以稍加说明:

我在Google Cloud上工作,并有一个“dockerized”的Django应用程序。 部分应用程序取决于使用gsutil将文件移入/移出Google存储分区。 由于各种原因,我们不希望使用Google Container Engine来pipe理我们的容器。 相反,我们想通过启动额外的Google Compute虚拟机进行横向扩展,而后者又将运行此Docker容器。 类似于https://cloud.google.com/python/tutorials/bookshelf-on-compute-engine,除了我们将使用容器而不是拉一个git仓库。

虚拟机将从一个基本的Debian镜像构build​​,启动和安装依赖关系(例如Docker本身)将使用启动脚本(例如, gcloud compute instances create some-instance --metadata-from-file startup-script=/path/to/startup.sh )。

如果我手动创build一个虚拟机,用sudo -s提升,运行gsutil config -f (在/root/.boto创build一个凭证文件),然后运行我的docker容器(见下面的Dockerfile)

docker run -v /root/.boto:/root/.boto username/gs gsutil ls gs://my-test-bucket

那么它的工作。 但是,这需要我的交互来创buildboto文件。

我的问题是 :如何将默认服务凭证传递到将在新VM中启动的Docker容器?

gsutil即使在“全新的”Debian虚拟机上也能使用,因为它使用所有虚拟机加载的默认计算引擎凭证。 有没有办法使用这些凭据,并将它们传递到docker集装箱? 在第一次调用gsutil到一个新的VM之后,我注意到它创build了〜/ .gsutil和〜/ .config文件夹。 不幸的是,在Docker中安装这两个

docker run -v ~/.config/:/root/.config -v ~/.gsutil:/root/.gsutil username/gs gsutil ls gs://my-test-bucket

不解决我的问题。 它告诉我:

ServiceException: 401 Anonymous users does not have storage.objects.list access to bucket my-test-bucket.

一个最小的gsutil Dockerfile(不是我的):

 FROM alpine #install deps and install gsutil RUN apk add --update \ python \ py-pip \ py-cffi \ py-cryptography \ && pip install --upgrade pip \ && apk add --virtual build-deps \ gcc \ libffi-dev \ python-dev \ linux-headers \ musl-dev \ openssl-dev \ && pip install gsutil \ && apk del build-deps \ && rm -rf /var/cache/apk/* CMD ["gsutil"] 

增加:解决方法:

我已经解决了我的问题,但它是相当迂回的,所以如果可能的 ,我仍然对更简单的方法感兴趣 。 所有的细节如下:

首先是一个描述:我首先在Web控制台中创build了一个服务帐户。 然后将JSON密钥文件(称为credentials.json)保存到存储桶中。 在GCE VM的启动脚本中,我将该密钥文件复制到本地文件系统( gsutil cp gs://<bucket>/credentials.json /gs_credentials/ )。 然后我启动我的docker容器,安装该本地目录。 然后,当Docker容器启动时,它会运行一个脚本来validationcredentials.json(它在docker中创build一个.boto文件),导出BOTO_PATH =,最后我可以在Docker容器中执行gsutil操作。

下面是一个小例子的文件:

Dockerfile:

 FROM alpine #install deps and install gsutil RUN apk add --update \ python \ py-pip \ py-cffi \ py-cryptography \ bash \ curl \ && pip install --upgrade pip \ && apk add --virtual build-deps \ gcc \ libffi-dev \ python-dev \ linux-headers \ musl-dev \ openssl-dev \ && pip install gsutil \ && apk del build-deps \ && rm -rf /var/cache/apk/* # install the gcloud SDK- # this allows us to use gcloud auth inside the container RUN curl -sSL https://sdk.cloud.google.com > /tmp/gcl \ && bash /tmp/gcl --install-dir=~/gcloud --disable-prompts RUN mkdir /startup ADD gsutil_docker_startup.sh /startup/gsutil_docker_startup.sh ADD get_account_name.py /startup/get_account_name.py ENTRYPOINT ["/startup/gsutil_docker_startup.sh"] 

gsutil_docker_startup.sh:采用一个参数,即JSON格式服务帐户凭证文件的path。 该文件存在,因为主机上的目录被安装在容器中。

 #!/bin/bash CRED_FILE_PATH=$1 mkdir /results # List the bucket, see that it gives a "ServiceException:401" gsutil ls gs://<input bucket> > /results/before.txt # authenticate the credentials- this creates a .boto file: /root/gcloud/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file=$CRED_FILE_PATH # need to extract the service account which is like: # <service acct ID>@<google project>.iam.gserviceaccount.com" SERVICE_ACCOUNT=$(python /startup/get_account_name.py $CRED_FILE_PATH) # with that service account, we can locate the .boto file: export BOTO_PATH=/root/.config/gcloud/legacy_credentials/$SERVICE_ACCOUNT/.boto # List the bucket and copy the file to an output bucket for good measure gsutil ls gs://<input bucket> > /results/after.txt gsutil cp /results/*.txt gs://<output bucket>/ 

get_account_name.py:

 import json import sys j = json.load(open(sys.argv[1])) sys.stdout.write(j['client_email']) 

然后,GCE启动脚本(在VM启动时自动执行)是:

 #!/bin/bash # <SNIP> # Install docker, other dependencies # </SNIP> # pull docker image docker pull userName/containerName # get credential file: mkdir /cloud_credentials gsutil cp gs://<bucket>/credentials.json /cloud_credentials/creds.json # run container # mount the host machine directory where the credentials were saved. # Note that the container expects a single arg, # which is the path to the credential file IN THE CONTAINER docker run -v /cloud_credentials:/cloud_credentials \ userName/containerName /cloud_credentials/creds.json