如何在AI平台上的自定义Docker映像中安装GCS存储桶?

时间:2019-10-21 00:36:49

标签: google-cloud-platform ubuntu-18.04 nvidia-docker gcsfuse gcp-ai-platform-training

我正在使用Google的AI平台来使用自定义Docker映像训练机器学习模型。要运行现有代码而不进行任何修改,我想在容器内安装GCS存储桶。

我认为实现此目的的一种方法是将gcloud安装到身份验证中,然后将gcsfuse安装到容器中。我的Dockerfile看起来像这样:

FROM nvidia/cuda:10.1-cudnn7-runtime-ubuntu18.04

WORKDIR /root

# Install system packages.
RUN apt-get update
RUN apt-get install -y curl
# ...

# Install gcsfuse.
RUN echo "deb http://packages.cloud.google.com/apt gcsfuse-bionic main" | tee /etc/apt/sources.list.d/gcsfuse.list
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
RUN apt-get update
RUN apt-get install -y gcsfuse

# Install gcloud.
RUN apt-get install -y apt-transport-https
RUN apt-get install -y ca-certificates
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
RUN apt-get update
RUN apt-get install -y google-cloud-sdk

# ...

ENTRYPOINT ["entrypoint.sh"]

然后在入口点脚本中,我尝试通过Google Cloud进行身份验证并安装存储桶。我的entrypoint.sh看起来像这样:

#!/bin/sh
set -e

gcloud auth login
gcsfuse my-bucket-name /root/output
python3 script.py --logdir /root/output/experiment

然后我构建容器并在本地进行测试以进行测试,或者在AI平台上远程运行以进行完整的培训:

# Run locally for testing.
nvidia-docker build -t my-image-name .
nvidia-docker run -it --rm my-image-name

# Run on AI Platform for full training run.
nvidia-docker build -t my-image-name .
gcloud auth configure-docker
nvidia-docker push my-image-name
gcloud beta ai-platform jobs submit training --region us-west1 --scale-tier custom --master-machine-type standard_p100 --master-image-uri my-image-name

在本地和AI平台上,entrypoint.sh脚本都挂在行gcloud auth login上,可能是因为它等待用户输入。是否有更好的方法从容器内部通过Google Cloud进行身份验证?如果没有,如何使当前挂起的线自动化?

2 个答案:

答案 0 :(得分:3)

考虑使用gcloud auth login并提供密钥文件,而不是使用主要用于人员/用户身份验证的gcloud auth activate-service-account。详细信息请参见此处:

https://cloud.google.com/sdk/gcloud/reference/auth/activate-service-account

我建议不要将密钥文件放在图像内部,而应在外部提供。另一种选择是认识到身份验证可以通过环境变量隐含。因此,遵循云原生实践,让环境提供所需的凭据,并且完全不要尝试在环境内部进行身份验证。如果您打算在GCP Compute Engine或GKE中运行容器,则可以从容器外部隐式向容器提供服务帐户。

答案 1 :(得分:0)

如果default service account满足您的需求,则可以将容器配置为像this一样使用它。您也可以通过granting it extra permissions为其提供所需的信息。


如果要使用自己的服务帐户,则需要通过以下方式验证为服务帐户:

gcloud auth activate-service-account --key-file=somekey.json

这样,当您通过浏览器进行身份验证时,容器不会挂起。所以显而易见的下一个问题是:

如何将服务帐户的密钥插入容器?

策略

首先,您将要generate a key file来使用您想要使用的任何服务帐户。

将凭据存储在Docker映像中不是一个好主意,因此我将密钥放入脚本中,然后将其放入存储桶中。因此,容器下载并运行脚本,该脚本将配置的身份切换到我选择的服务帐户。

入口点

# runs as the default service account
gsutil cp "$1" /run/cmd
chmod +x /run/cmd
/run/cmd

运行脚本(在存储桶中)

cat << EOF!! > /dev/shm/sa_key
THE KEY FILE CONTENTS GO HERE
EOF!!

gcloud auth activate-service-account --key-file=/dev/shm/sa_key

# commands below this line are performed with the specified identity

默认服务帐户可以访问其项目中的存储桶,因此上面的脚本必须位于该存储桶中。确保该存储桶受到适当的保护,有权访问该存储桶的任何人都可以使用其包含密钥的服务帐户的身份。

本地测试

docker run -v "/home/me/.config/gcloud:/root/.config/gcloud" \
    theimagename gs://my-project_job1/run_script

这将使用您用户的活动gcloud凭据拉下脚本,然后它将切换到服务帐户。完成后,主机的gcloud将配置为使用该服务帐户-因此您可能需要通过gcloud auth login将其切换回自己。为了避免这种情况,您可以改为挂载该目录的副本,以使原始目录保持不变。

在GCP中运行

gcloud ai-platform jobs submit training job1 \    
  --region us-west2 \
  --master-image-uri us.gcr.io/my-project/theimagename:latest \
  -- gs://my-project_job1/run_script

我对此做了一点修改,以删除对项目中与此处无关的部分的引用,因此这可能不会按原样运行,但是我认为这表明了我如何使用它的要旨:

https://gist.github.com/MatrixManAtYrService/737cb408e5a27c2aaa19576b0f6ec18a

相关问题