Uwierzytelnianie zewnętrzne w zadaniu usługi ACR przy użyciu tożsamości zarządzanej przez platformę Azure

W zadaniu usługi ACR można włączyć tożsamość zarządzaną dla zasobów platformy Azure. Zadanie może używać tożsamości do uzyskiwania dostępu do innych zasobów platformy Azure bez konieczności udostępniania poświadczeń ani zarządzania nimi.

W tym artykule dowiesz się, jak włączyć tożsamość zarządzaną w zadaniu, które uzyskuje dostęp do wpisów tajnych przechowywanych w magazynie kluczy platformy Azure.

Aby utworzyć zasoby platformy Azure, ten artykuł wymaga uruchomienia interfejsu wiersza polecenia platformy Azure w wersji 2.0.68 lub nowszej. Uruchom polecenie az --version, aby dowiedzieć się, jaka wersja jest używana. Jeśli konieczna będzie instalacja lub uaktualnienie, zobacz Instalowanie interfejsu wiersza polecenia platformy Azure.

Omówienie scenariusza

Przykładowe zadanie odczytuje poświadczenia Docker Hub przechowywane w magazynie kluczy platformy Azure. Poświadczenia są przeznaczone dla konta Docker Hub z uprawnieniami zapisu (wypychania) do prywatnego repozytorium Docker Hub. Aby odczytać poświadczenia, należy skonfigurować zadanie przy użyciu tożsamości zarządzanej i przypisać do niego odpowiednie uprawnienia. Zadanie skojarzone z tożsamością tworzy obraz i loguje się do Docker Hub, aby wypchnąć obraz do prywatnego repozytorium.

W tym przykładzie przedstawiono kroki wykonywane przy użyciu tożsamości zarządzanej przypisanej przez użytkownika lub przypisanej przez system. Wybór tożsamości zależy od potrzeb organizacji.

W rzeczywistym scenariuszu firma może publikować obrazy w prywatnym repozytorium w Docker Hub w ramach procesu kompilacji.

Wymagania wstępne

Potrzebujesz rejestru kontenerów platformy Azure, w którym uruchamiasz zadanie. W tym artykule ten rejestr nosi nazwę myregistry. Zastąp ciąg własną nazwą rejestru w kolejnych krokach.

Jeśli nie masz jeszcze rejestru kontenerów platformy Azure, zobacz Szybki start: tworzenie prywatnego rejestru kontenerów przy użyciu interfejsu wiersza polecenia platformy Azure. Nie musisz jeszcze wypychać obrazów do rejestru.

Potrzebujesz również prywatnego repozytorium w Docker Hub, a konto Docker Hub z uprawnieniami do zapisu w repozytorium. W tym przykładzie to repozytorium ma nazwę hubuser/hubrepo.

Tworzenie magazynu kluczy i przechowywanie wpisów tajnych

Najpierw utwórz grupę zasobów o nazwie myResourceGroup w lokalizacji eastus za pomocą następującego polecenia az group create :

az group create --name myResourceGroup --location eastus

Użyj polecenia az keyvault create , aby utworzyć magazyn kluczy. Pamiętaj, aby określić unikatową nazwę magazynu kluczy.

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

Zapisz wymagane poświadczenia Docker Hub w magazynie kluczy przy użyciu polecenia az keyvault secret set. W tych poleceniach wartości są przekazywane w zmiennych środowiskowych:

# 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

W rzeczywistym scenariuszu wpisy tajne prawdopodobnie zostaną ustawione i zachowane w osobnym procesie.

Definiowanie kroków zadania w pliku YAML

Kroki tego przykładowego zadania są definiowane w pliku YAML. Utwórz plik o nazwie dockerhubtask.yaml w lokalnym katalogu roboczym i wklej następującą zawartość. Pamiętaj, aby zastąpić nazwę magazynu kluczy w pliku nazwą magazynu kluczy.

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

Kroki zadania wykonują następujące czynności:

  • Zarządzanie poświadczeniami tajnymi w celu uwierzytelniania za pomocą Docker Hub.
  • Uwierzytelnij się za pomocą Docker Hub, przekazując wpisy tajne do docker login polecenia .
  • Skompiluj obraz przy użyciu przykładowego pliku Dockerfile w repozytorium Azure-Samples/acr-tasks .
  • Wypchnij obraz do prywatnego repozytorium Docker Hub.

Opcja 1. Tworzenie zadania przy użyciu tożsamości przypisanej przez użytkownika

Kroki opisane w tej sekcji umożliwiają utworzenie zadania i włączenie tożsamości przypisanej przez użytkownika. Jeśli zamiast tego chcesz włączyć tożsamość przypisaną przez system, zobacz Opcja 2: Tworzenie zadania z tożsamością przypisaną przez system.

Tworzenie tożsamości przypisanej przez użytkownika

Utwórz tożsamość o nazwie myACRTasksId w subskrypcji przy użyciu polecenia az identity create . Możesz użyć tej samej grupy zasobów użytej wcześniej do utworzenia rejestru kontenerów lub innej.

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

Aby skonfigurować tożsamość przypisaną przez użytkownika w poniższych krokach, użyj polecenia az identity show , aby zapisać identyfikator zasobu tożsamości, identyfikator podmiotu zabezpieczeń i identyfikator klienta w zmiennych.

# 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)

Tworzenie zadania

Utwórz zadanie dockerhubtask , wykonując następujące polecenie az acr task create . Zadanie jest uruchamiane bez kontekstu kodu źródłowego, a polecenie odwołuje się do pliku dockerhubtask.yaml w katalogu roboczym. Parametr --assign-identity przekazuje identyfikator zasobu tożsamości przypisanej przez użytkownika.

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

W danych wyjściowych identity polecenia sekcja pokazuje tożsamość typu UserAssigned ustawioną w zadaniu:

[...]
"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"
      }
[...]

Udzielanie tożsamości dostępu do magazynu kluczy

Uruchom następujące polecenie az keyvault set-policy , aby ustawić zasady dostępu w magazynie kluczy. Poniższy przykład umożliwia tożsamości odczytywanie wpisów tajnych z magazynu kluczy.

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

Przejdź do obszaru Ręcznie uruchom zadanie.

Opcja 2. Tworzenie zadania z tożsamością przypisaną przez system

Kroki opisane w tej sekcji umożliwiają utworzenie zadania i włączenie tożsamości przypisanej przez system. Jeśli zamiast tego chcesz włączyć tożsamość przypisaną przez użytkownika, zobacz Opcja 1: Tworzenie zadania z tożsamością przypisaną przez użytkownika.

Tworzenie zadania

Utwórz zadanie dockerhubtask , wykonując następujące polecenie az acr task create . Zadanie jest uruchamiane bez kontekstu kodu źródłowego, a polecenie odwołuje się do pliku dockerhubtask.yaml w katalogu roboczym. Parametr --assign-identity bez wartości włącza tożsamość przypisaną przez system w zadaniu.

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

W danych wyjściowych identity polecenia sekcja pokazuje tożsamość typu SystemAssigned ustawioną w zadaniu. Jest to principalId identyfikator podmiotu zabezpieczeń tożsamości zadania:

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

Użyj polecenia az acr task show , aby zapisać identyfikator principalId w zmiennej, aby użyć w kolejnych poleceniach. Zastąp nazwę zadania i rejestr w następującym poleceniu:

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

Udzielanie tożsamości dostępu do magazynu kluczy

Uruchom następujące polecenie az keyvault set-policy , aby ustawić zasady dostępu w magazynie kluczy. Poniższy przykład umożliwia tożsamości odczytywanie wpisów tajnych z magazynu kluczy.

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

Ręczne uruchamianie zadania

Aby sprawdzić, czy zadanie, w którym włączono tożsamość zarządzaną, działa pomyślnie, ręcznie wyzwól zadanie za pomocą polecenia az acr task run . Parametr --set służy do przekazywania nazwy prywatnego repozytorium do zadania. W tym przykładzie nazwa repozytorium zastępczego to hubuser/hubrepo.

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

Po pomyślnym uruchomieniu zadania dane wyjściowe pokazują pomyślne uwierzytelnienie w celu Docker Hub, a obraz został pomyślnie skompilowany i wypchnięty do prywatnego repozytorium:

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

Aby potwierdzić wypchnięcie obrazu, sprawdź tag (cf24w tym przykładzie) w prywatnym repozytorium Docker Hub.

Następne kroki