Создание файла учетных данных на сервере с помощью Dockerfile и менеджера секретов облака Google

Я использую облачную сборку Google для CI/CD для моего приложения django, и одно из моих требований - настроить GOOGLE_APPLICATION_CREDENTIALS так, чтобы я мог выполнять аутентифицированные действия в моей сборке Docker. Например, мне нужно запустить RUN python manage.py collectstatic --noinput, который требует доступа к моим ведрам облачного хранилища Google.

Я создал учетные данные, и они хорошо работают, если просто включить их в мое (в настоящее время приватное) репо в виде .json-файла, так что они попадают в мой контейнер Docker с помощью команды COPY . . и установки переменной env с помощью ENV GOOGLE_APPLICATION_CREDENTIALS=credentials.json. В конечном итоге я хочу получить значение учетных данных из менеджера secret и создать файл учетных данных на этапе сборки, чтобы полностью удалить учетные данные из репозитория. Я пытался сделать это с помощью редактирования cloudbuild.yaml (ссылаясь на this doc) с различными реализациями конфига availableSecrets, синтаксиса $$SECRET и build-args в команде сборки docker и попыткой доступа в Dockerfile с помощью

ARG GOOGLE_BUILD_CREDS
RUN echo "$GOOGLE_BUILD_CREDS" >> credentials.json
ENV GOOGLE_APPLICATION_CREDENTIALS=credentials.json

безрезультатно.

Если кто-то может подсказать мне, как реализовать это в моем cloudbuild.yaml и Dockerfile, если это возможно, или если есть другое лучшее решение, буду очень признателен.

Это соответствующая часть моего cloudbuild.yaml

steps:
  - name: gcr.io/cloud-builders/docker
    args:
      - build
      - '--no-cache'
      - '-t'
      - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
      - .
      - '-f'
      - Dockerfile
    id: Build
availableSecrets:
  secretManager:
  - versionName: projects/PROJECT_ID/secrets/CREDENTIALS/versions/latest
    env: 'CREDENTIALS'

Если ваш контейнер будет работать на Cloud Run, это очень просто: Удалите файл ключа учетной записи службы (и, грубо говоря, в большинстве случаев использования он вам никогда не понадобится).

Помните, что файл ключа учетной записи службы - это секрет с закрытым ключом. И если вы поместите его в свой контейнер, вы просто будете хранить его в виде обычного текста. Так плохо для секрета!!! (с помощью dive вы можете исследовать содержимое вашего контейнера и украсть секрет, если у вас есть доступ непосредственно к контейнеру)

Но, я уверен, вы знаете это, потому что хотите хранить секрет в менеджере секретов. Теперь вопрос? Как вы получаете доступ к секретному менеджеру? Нужен ли вам файл ключа учетной записи службы для аутентификации, чтобы получить к нему доступ?

На самом деле нет.


Решением является использование ADC (Application default credentials). В клиентских библиотеках используйте метод get default credential, чтобы библиотека автоматически определила платформу и используемый мандат

В Cloud Run (как и в других сервисах Google Cloud) есть сервер метаданных, который позволяет клиентским библиотекам получать информацию об учетных данных из учетной записи сервиса runtime service.

В вашей локальной среде у вас есть 2 варианта:

  • Используйте собственные учетные данные. Для этого выполните команду gcloud auth application-default login. Это ваши собственные учетные данные и разрешения, не совсем такие же, как в среде выполнения Cloud Run
  • .
  • Персонифицируйте учетную запись службы среды выполнения Cloud Run и действуйте как она сама для локального запуска вашего контейнера/кода. Для этого выполните команду gcloud auth application-default login --impersonate-service-account=<service account email>, Убедитесь, что у учетной записи службы есть роль service account token creator.

Затем запустите свое приложение локально, и пусть ADC использует учетные данные

Кажется, я нашел решение. Чтобы решить ошибку, о которой я упоминал в своем ответе @guillaume-blaquiere, я обновил build args в cloudbuild.yaml, чтобы включить --network=cloudbuild, что позволило мне получить доступ к правильным учетным данным учетной записи сервиса (заслуга этого ответа ). Следующая проблема, с которой я столкнулся, связана с библиотекой django-storages, возвращающей следующее исключение

AttributeError: you need a private key to sign credentials.the credentials you are currently using <class 'google.auth.compute_engine.credentials.Credentials'> just contains a token. see https://googleapis.dev/python/google-api-core/latest/auth.html#setting-up-a-service-account for more details.

Затем я наткнулся на это предложение добавить параметр GS_QUERYSTRING_AUTH = False в конфигурацию django, и это, похоже, помогло. Единственное, что меня беспокоит, это то, что документация не слишком подробно описывает последствия или риски отключения этого параметра (ведро является общедоступным - читайте, как он рекомендует). Однако кажется, что все работает, как задумано. Так что я буду использовать эту конфигурацию, если не будет предложено лучшего решения.

Вернуться на верх