Внешняя проверка подлинности в задаче ACR с управляемым удостоверением Azure

В задаче ACR можно включить управляемое удостоверение для ресурсов Azure. В задаче это удостоверение будет использоваться для получения доступа к другим ресурсам Azure без необходимости предоставлять учетные данные или управлять ими.

Из этой статьи вы узнаете, как включить управляемое удостоверение в задаче, получающей доступ к секретам в хранилище ключей Azure.

Для создания ресурсов Azure с помощью инструкций из этой статьи требуется Azure CLI версии 2.0.68 или более поздней версии. Чтобы узнать версию, выполните команду az --version. Если вам необходимо выполнить установку или обновление, см. статью Установка Azure CLI 2.0.

Обзор сценария

Задача в примере читает учетные данные Docker Hub из хранилища ключей Azure. Учетные данные к учетной записи Docker Hub c разрешениями на запись (push) в частном репозитории Docker Hub. Чтобы прочитать учетные данные, необходимо настроить в параметрах задачи управляемое удостоверение и назначить соответствующие разрешения. Задача, связанная с удостоверением, создает образ и входит в Docker Hub для отправки образа в частный репозиторий.

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

В реальном сценарии компания может опубликовать образы в частном репозитории Docker Hub в ходе сборки.

Предварительные требования

Вам необходим реестр контейнеров Azure, в котором вы запустите задачу. В этой статье ему присвоено имя myregistry. На последующих шагах замените его на имя своего реестра.

Если у вас еще нет реестра контейнеров Azure, см. Практическое руководство. Создание реестра частного контейнера с помощью Azure CLI. На этом этапе не нужно отправлять образы в реестр.

Вам также понадобится частный репозиторий в Docker Hub и учетная запись Docker Hub с разрешениями на запись в репозиторий. В этом примере, этот репозиторий называется hubuser/hubrepo.

Создание хранилища ключей и хранение секретов

При необходимости создайте группу ресурсов с именем myResourceGroup в расположении eastus с помощью следующей команды az group create:

az group create --name myResourceGroup --location eastus

Используйте команду az keyvault create, чтобы создать хранилище ключей. Обязательно укажите уникальное имя хранилища ключей.

az keyvault create --name mykeyvault --resource-group myResourceGroup --location eastus

Сохраните необходимые учетные данные Docker Hub в хранилище ключей, используя команду az keyvault secret set. В этих командах значения передаются через переменные среды:

# Store Docker Hub user name
az keyvault secret set \
  --name UserName \
  --value $USERNAME \
  --vault-name mykeyvault

# Store Docker Hub password
az keyvault secret set \
  --name Password \
  --value $PASSWORD \
  --vault-name mykeyvault

В реальном сценарии, секреты, скорее всего, будут указываться и поддерживаться в отдельном процессе.

Определение шагов задачи в файле YAML

Шаги для этой задачи, выступающей примером, определены в файле YAML. Создайте файл и именем dockerhubtask.yaml в локальном рабочем каталоге и вставьте в него следующее содержимое. Обязательно замените имя хранилища ключей в файле на имя своего хранилища.

version: v1.1.0
# Replace mykeyvault with the name of your key vault
secrets:
  - id: username
    keyvault: https://mykeyvault.vault.azure.net/secrets/UserName
  - id: password
    keyvault: https://mykeyvault.vault.azure.net/secrets/Password
steps:
# Log in to Docker Hub
  - cmd: bash echo '{{.Secrets.password}}' | docker login --username '{{.Secrets.username}}' --password-stdin 
# Build image
  - build: -t {{.Values.PrivateRepo}}:$ID https://github.com/Azure-Samples/acr-tasks.git -f hello-world.dockerfile
# Push image to private repo in Docker Hub
  - push:
    - {{.Values.PrivateRepo}}:$ID

В задаче выполняются следующие действия:

  • управление секретными учетными данными для проверки подлинности с помощью Docker Hub;
  • проверка подлинности с помощью Docker Hub путем передачи секретов в команду docker login;
  • создание образа, c использованием примера Dockerfile из репозитория Azure-Samples/acr-tasks;
  • отправка образа в частный репозиторий Docker Hub.

Вариант 1. Создание задачи с удостоверением, назначаемым пользователем

В этом разделе описано, как создать задачу и включить удостоверение, назначаемое пользователем. Если вы хотите включить удостоверение, назначаемое системой, см. раздел Вариант 2. Создание задачи с удостоверением, назначаемым системой.

Создание назначаемого пользователем удостоверения

Создайте в подписке удостоверение с именем myACRTasksId, используя команду az identity create. Вы можете использовать ту же группу ресурсов, которую указали ранее для создания реестра контейнеров, либо другую.

az identity create \
  --resource-group myResourceGroup \
  --name myACRTasksId

Чтобы настроить назначаемое пользователем удостоверение на следующих шагах, выполните команду az identity show для сохранения идентификаторов ресурса, субъекта и клиента удостоверения в переменных.

# Get resource ID of the user-assigned identity
resourceID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query id --output tsv)

# Get principal ID of the task's user-assigned identity
principalID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query principalId --output tsv)

# Get client ID of the user-assigned identity
clientID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query clientId --output tsv)

Создание задачи

Создайте задачу dockerhubtask, выполнив следующую команду az acr task create. Задача выполняется без контекста исходного кода, а команда ссылается на файл dockerhubtask.yaml в рабочей папке. Параметр --assign-identity передает идентификатор ресурса для удостоверения, назначаемого пользователем.

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity $resourceID

В выходных данных команды в разделе identity показано, что в задаче задано удостоверение типа UserAssigned:

[...]
"identity": {
    "principalId": null,
    "tenantId": null,
    "type": "UserAssigned",
    "userAssignedIdentities": {
      "/subscriptions/xxxxxxxx-d12e-4760-9ab6-xxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRTasksId": {
        "clientId": "xxxxxxxx-f17e-4768-bb4e-xxxxxxxxxxxx",
        "principalId": "xxxxxxxx-1335-433d-bb6c-xxxxxxxxxxxx"
      }
[...]

Предоставление удостоверению доступа к хранилищу ключей

Выполните следующую команду az keyvault set-policy для настройки политики доступа к хранилищу ключей. Следующий пример разрешает удостоверению чтение секретов в хранилище ключей.

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

Перейдите к разделу Выполнение задачи вручную.

Вариант 2. Создание задачи с удостоверением, назначаемым системой

В этом разделе описано, как создать задачу и включить удостоверение, назначаемое системой. Если вы хотите включить удостоверение, назначаемое пользователем, см. раздел Вариант 1. Создание задачи с удостоверением, назначаемым пользователем.

Создание задачи

Создайте задачу dockerhubtask, выполнив следующую команду az acr task create. Задача выполняется без контекста исходного кода, а команда ссылается на файл dockerhubtask.yaml в рабочей папке. Параметр --assign-identity без значений включает удостоверение, назначаемое системой, в задаче.

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity 

В выходных данных команды в разделе identity показано, что в задаче задано удостоверение типа SystemAssigned. principalId — это идентификатор субъекта для удостоверения задачи.

[...]
  "identity": {
    "principalId": "xxxxxxxx-2703-42f9-97d0-xxxxxxxxxxxx",
    "tenantId": "xxxxxxxx-86f1-41af-91ab-xxxxxxxxxxxx",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  },
  "location": "eastus",
[...]

С помощью команды az acr task show сохраните principalId в переменной, что использовать это значение в следующих командах. Подставьте имя задачи и реестра в следующей команде:

principalID=$(az acr task show \
  --name <task_name> --registry <registry_name> \
  --query identity.principalId --output tsv)

Предоставление удостоверению доступа к хранилищу ключей

Выполните следующую команду az keyvault set-policy для настройки политики доступа к хранилищу ключей. Следующий пример разрешает удостоверению чтение секретов в хранилище ключей.

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

Выполнение задачи вручную

Чтобы проверить, выполняется ли задача, в которой включено управляемое удостоверение, запустите ее вручную с помощью команды az acr task run. Параметр --set используется для передачи в задачу имени частного репозитория. В этом примере подстановочное имя репозитория — hubuser/hubrepo.

az acr task run --name dockerhubtask --registry myregistry --set PrivateRepo=hubuser/hubrepo

При успешном выполнении задачи, в ее выводе отображается успешная проверка подлинности в Docker Hub, а также успешное создание образа и его передача в частный репозиторий:

Queued a run with ID: cf24
Waiting for an agent...
2019/06/20 18:05:55 Using acb_vol_b1edae11-30de-4f2b-a9c7-7d743e811101 as the home volume
2019/06/20 18:05:58 Creating Docker network: acb_default_network, driver: 'bridge'
2019/06/20 18:05:58 Successfully set up Docker network: acb_default_network
2019/06/20 18:05:58 Setting up Docker configuration...
2019/06/20 18:05:59 Successfully set up Docker configuration
2019/06/20 18:05:59 Logging in to registry: myregistry.azurecr.io
2019/06/20 18:06:00 Successfully logged into myregistry.azurecr.io
2019/06/20 18:06:00 Executing step ID: acb_step_0. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:00 Launching container with name: acb_step_0
[...]
Login Succeeded
2019/06/20 18:06:02 Successfully executed container: acb_step_0
2019/06/20 18:06:02 Executing step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:02 Scanning for dependencies...
2019/06/20 18:06:04 Successfully scanned dependencies
2019/06/20 18:06:04 Launching container with name: acb_step_1
Sending build context to Docker daemon    129kB
[...]
2019/06/20 18:06:07 Successfully pushed image: hubuser/hubrepo:cf24
2019/06/20 18:06:07 Step ID: acb_step_0 marked as successful (elapsed time in seconds: 2.064353)
2019/06/20 18:06:07 Step ID: acb_step_1 marked as successful (elapsed time in seconds: 2.594061)
2019/06/20 18:06:07 Populating digests for step ID: acb_step_1...
2019/06/20 18:06:09 Successfully populated digests for step ID: acb_step_1
2019/06/20 18:06:09 Step ID: acb_step_2 marked as successful (elapsed time in seconds: 2.743923)
2019/06/20 18:06:09 The following dependencies were found:
2019/06/20 18:06:09
- image:
    registry: registry.hub.docker.com
    repository: hubuser/hubrepo
    tag: cf24
    digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
  runtime-dependency:
    registry: registry.hub.docker.com
    repository: library/hello-world
    tag: latest
    digest: sha256:0e11c388b664df8a27a901dce21eb89f11d8292f7fca1b3e3c4321bf7897bffe
  git:
    git-head-revision: b0ffa6043dd893a4c75644c5fed384c82ebb5f9e

Run ID: cf24 was successful after 15s

Чтобы удостовериться, отправлен ли образ, проверьте тег (cf24 в этом примере) в частном репозитории Docker Hub.

Дальнейшие действия