Как я могу смонтировать корзину GCS в пользовательском образе Docker на платформе AI?

Я использую платформу искусственного интеллекта Google для обучения моделей машинного обучения с помощью собственного образа 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 и монтирую корзину. Мой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 ответа

Решение

Вместо того, чтобы использовать gcloud auth login который в первую очередь предназначен для аутентификации человека / пользователя, рассмотрите возможность использования gcloud auth activate-service-accountи предоставление ключевого файла. Подробнее см. Здесь:

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

Я бы рекомендовал не размещать файл ключей внутри изображения, а вместо этого предоставлять его извне. Другой альтернативой является осознание того, что аутентификация может быть неявной через переменные среды. Поэтому, следуя нативным практикам облачных вычислений, пусть среда предоставляет необходимые учетные данные и вообще не пытается пройти аутентификацию внутри вашей среды. Если вы планируете запускать свой контейнер внутри GCP Compute Engine или GKE, вы можете неявно предоставить сервисную учетную запись для контейнера извне.

Если учетная запись службы по умолчанию соответствует вашим потребностям, вы можете настроить свой контейнер для использования таким образом. Вы также можете дать ему то, что ему нужно, предоставив ему дополнительные разрешения.


Если вы хотите использовать свою собственную учетную запись службы, вам необходимо пройти аутентификацию в качестве учетной записи службы через:

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

Таким образом, контейнер не зависнет, когда вас попросят пройти аутентификацию через браузер. Итак, очевидный следующий вопрос:

Как мне вставить ключ моей сервисной учетной записи в контейнер?

Стратегия

Во-первых, вам нужно сгенерировать ключевой файл для любой учетной записи службы, которую вы хотите использовать.

Хранить учетные данные в образах докеров - не лучшая идея, поэтому я помещаю ключ в сценарий, который затем помещаю в корзину. Таким образом, контейнер загружает и запускает сценарий, который переключает настроенное удостоверение на учетную запись службы по моему выбору.

Точка входа

# 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 вашего хоста будет настроен для использования учетной записи службы, поэтому вам может потребоваться переключить ее обратно на себя vigcloud 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