Azure Kubernetes Service (AKS) から Azure Container Registry (ACR) で認証する

Azure Kubernetes Service (AKS) で Azure Container Registry (ACR) を使用する場合は、認証メカニズムを確立する必要があります。 ACR と AKS の間で必要なアクセス許可は、Azure CLI、Azure PowerShell、またはAzure ポータルを使用して構成できます。 この記事では、Azure CLIまたはAzure PowerShellを使用して、これらのAzure サービス間の認証を構成する例を示します。

AKS から ACR への統合では、AKS クラスター内のエージェント プールに関連付けられている AcrPull ロールMicrosoft Entra ID マネージド ID に割り当てます。 AKS マネージド ID について詳しくは、「マネージド ID の概要」をご覧ください。

重要

ACR をアタッチするときに、Microsoft Entra グループに待機時間の問題があります。 AcrPull ロールがMicrosoft Entra グループに付与され、kubelet ID がグループに追加され、Azureロールベースのアクセス制御 (Azure RBAC) の構成が完了した場合、RBAC グループが有効になるまでに遅延が発生する可能性があります。 Azure RBAC 構成を完了する必要がある自動化を実行している場合は、回避策として 独自の kubelet ID を使用することをお勧めします。 ユーザー割り当て ID を事前に作成し、Microsoft Entra グループに追加してから、その ID を kubelet ID として使用して AKS クラスターを作成できます。 このメソッドにより、kubelet によってトークンが生成される前に ID が Microsoft Entra グループに追加され、待機時間の問題が回避されます。

注記

この記事では、AKS と ACR の間の自動認証について説明します。 プライベート外部レジストリからイメージをプルする必要がある場合は、イメージのプル シークレットを使用します。

注意事項

ロールの割り当てアクセス許可モードが "RBAC レジストリ + ABAC リポジトリのアクセス許可" に設定されている ABAC 対応 ACR レジストリでは、az aks --attach-acrを介した AKS-ACR 統合はサポートされていません。ABAC 対応 ACR レジストリでは、イメージプルアクセス許可を付与するためにContainer Registry Repository Readerロールではなく、AcrPullロールが必要です。 ABAC 対応 ACR レジストリの場合は、az aks --attach-acr を使用するのではなく、Azure ポータル、Container Registry Repository Reader CLI、またはAzure Resource Managerを使用して、az role assignment ロールの割り当てを手動で割り当てる必要があります。 ABAC 対応 ACR レジストリの詳細については、「Azure属性ベースのアクセス制御」を参照してください。

このチュートリアルでは、Azure Container Registry (ACR) からイメージを安全にプルするようにAzure Kubernetes Service (AKS) クラスターを構成します。 Azure CLIでは、--attach-acr を使用します。 Terraform で、 AcrPull ロールを AKS kubelet マネージド ID に割り当てます。 このガイドは、インフラストラクチャ のプロビジョニングに Terraform を使用する際のAzure CLI ワークフローと同じフローに従います。

開始する前に

  • OwnerAzure アカウント管理者、またはAzure 共同管理者のロールがあなたのAzureサブスクリプションに必要です。
    • これらのロールの必要性を回避するために、代わりに既存のマネージド ID を使用して AKS から ACR を認証できます。 詳細については、「ACRに対して認証するためにAzureマネージド ID を使用する」を参照してください。
  • Azure CLIを使用している場合、この記事ではバージョン 2.7.0 以降Azure CLI実行している必要があります。 バージョンを検索するには、 az --version コマンドを実行します。 インストールまたはアップグレードする必要がある場合は、「Install Azure CLIを参照してください。
  • Azure PowerShellを使用している場合、この記事ではバージョン 5.9.0 以降Azure PowerShell実行している必要があります。 バージョンを確認するには、Get-InstalledModule -Name Az コマンドを実行します。 インストールまたはアップグレードする必要がある場合は、「Install Azure PowerShellを参照してください。
  • ACR の構成に Terraform を使用する例と構文については、Terraform リファレンスを参照してください。
  • Terraform がインストールされている (>= 1.6)。
  • Azure CLIインストールされ、サブスクリプションにサインインします。
  • ロールを割り当てるための権限 (オーナーまたはユーザーアクセス管理者)。

この記事では、Azure Container Registry (ACR) からイメージを安全にプルするようにAzure Kubernetes Service (AKS) クラスターを構成します。 Azure CLIでは、--attach-acr を使用します。 Terraform で、 AcrPull ロールを AKS kubelet マネージド ID に割り当てます。

この記事は、インフラストラクチャのプロビジョニングに Terraform を使用する際のAzure CLI ワークフローと同じフローに従います。 正しいサブスクリプションにサインインしていることを確認するには、次のAzure CLIコマンドを使用します。

az login
az account show

新しい ACR を作成する

ACR がまだない場合は、az acr create コマンドを使用して作成します。

レジストリ名は、Azure内でグローバルに一意である必要があり、ダッシュ (-) 文字を除く 5 ~ 50 文字の英数字が含まれている必要があります。 この名前は、レジストリの完全修飾 DNS 名の一部です。

export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export MYACR="mycontainerregistry$RANDOM_STRING"
export ACR_RESOURCE_GROUP="myContainerRegistryResourceGroup"
export LOCATION="westcentralus"

az group create \
  --name $ACR_RESOURCE_GROUP \
  --location $LOCATION

az acr create \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --sku basic

RANDOM_STRING変数には、ランダムな 10 桁の文字列が格納されます。 MYACR値はRANDOM_STRING値と連結され、一意の名前が作成されます。

ACR がまだない場合は、New-AzContainerRegistry コマンドレットを使用して作成します。

レジストリ名は、Azure内でグローバルに一意である必要があり、ダッシュ (-) 文字を除く 5 ~ 50 文字の英数字が含まれている必要があります。 この名前は、レジストリの完全修飾 DNS 名の一部です。

$RandomString = (Get-Random -Minimum 1000000000 -Maximum 10000000000).ToString()
$MyAcr = "mycontainerregistry$RandomString"
$AcrResourceGroup = "myContainerRegistryResourceGroup"
$Location = "westcentralus"

New-AzResourceGroup -Name $AcrResourceGroup -Location $Location

$NewAcr = @{
 Name = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 Location = $Location
 Sku = "Basic"
}

New-AzContainerRegistry @NewAcr

$RandomString変数には、ランダムな 10 桁の文字列が格納されます。 $MyAcr値は$RandomString値と連結され、一意の名前が作成されます。

構成用 の main.tf ファイルを作成し、まず Terraform プロバイダーを定義し、グローバルに一意のリソース名の一意のサフィックスを生成します。 グローバルに一意の名前を指定すると、Azure Container Registry名が既存のレジストリと競合しないようにします。

terraform {
 required_version = ">= 1.6.0"
 required_providers {
   azurerm = {
     source  = "hashicorp/azurerm"
     version = "~> 4.0"
   }
   random = {
     source  = "hashicorp/random"
     version = "~> 3.6"
   }
 }
}
provider "azurerm" {
 features {}
}
resource "random_string" "suffix" {
 length  = 6
 upper   = false
 special = false
}

新しい AKS クラスターを作成して既存の ACR と統合する

az aks create コマンドと --attach-acr パラメーターを使用して、新しい AKS クラスターを作成し、既存の ACR と統合します。 このコマンドを使用すると、サブスクリプション内の既存の ACR を承認し、マネージド ID の適切な AcrPull ロールを構成できます。

export CLUSTER_NAME="myAKSCluster"
export CLUSTER_RESOURCE_GROUP="myClusterResourceGroup"

az group create \
  --name $CLUSTER_RESOURCE_GROUP \
  --location $LOCATION

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $MYACR

別のサブスクリプションで ACR を使用するか、リソース ID を使用してアタッチする

AKS クラスターとは別のサブスクリプションにある ACR を使用している場合、または ACR 名の代わりに ACR リソース ID を 使用する場合は、次の構文を使用します。 この例では、前のセクションで作成したコンテナー レジストリを使用して、 ACR_RESOURCE_ID 変数を作成します。

ACR_RESOURCE_ID=$(az acr show \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --query id --output tsv)

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $ACR_RESOURCE_ID

New-AzAksCluster コマンドレットと -AcrNameToAttach パラメーターを使用して、新しい AKS クラスターを作成し、既存の ACR と統合します。 このコマンドを使用すると、サブスクリプション内の既存の ACR を承認し、マネージド ID の適切な AcrPull ロールを構成できます。

$ClusterName = "myAKSCluster"
$ClusterResourceGroup = "myClusterResourceGroup"

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

$NewCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 GenerateSshKey = $true
 AcrNameToAttach = $MyAcr
}

New-AzAksCluster @NewCluster

別のサブスクリプションで ACR を使用するか、リソース ID を使用してアタッチする

Azure PowerShellでは、-AcrNameToAttach パラメーターを使用した ACR の AKS へのアタッチのみがサポートされ、resource ID による ACR へのアタッチはサポートされません。

次に、リソース グループとAzure Container Registryを作成します。 このレジストリには、AKS クラスターが後でプルするコンテナー イメージが格納されます。

locals {
 location           = "westcentralus"
 acr_name           = "myacr${random_string.suffix.result}"
 acr_resource_group = "myContainerRegistryResourceGroup"
}
resource "azurerm_resource_group" "acr_rg" {
 name     = local.acr_resource_group
 location = local.location
}
resource "azurerm_container_registry" "acr" {
 name                = local.acr_name
 resource_group_name = azurerm_resource_group.acr_rg.name
 location            = azurerm_resource_group.acr_rg.location
 sku                 = "Basic"
 admin_enabled       = false
}

次に、レジストリからイメージを使用する AKS クラスターを作成します。 このクラスターでは、 システム割り当てマネージド ID が使用されます。これにより、イメージをプルするアクセス許可が付与されます。

locals {
 aks_name           = "myAKSCluster"
 aks_resource_group = "myClusterResourceGroup"
}
resource "azurerm_resource_group" "aks_rg" {
 name     = local.aks_resource_group
 location = local.location
}
resource "azurerm_kubernetes_cluster" "aks" {
 name                = local.aks_name
 location            = azurerm_resource_group.aks_rg.location
 resource_group_name = azurerm_resource_group.aks_rg.name
 dns_prefix          = local.aks_name
 identity {
   type = "SystemAssigned"
 }
 default_node_pool {
   name       = "systempool"
   node_count = 2
   vm_size    = "Standard_DS2_v2"
 }
}

この段階では、AKS クラスターは存在しますが、コンテナー レジストリにまだアクセスできません。 Azure CLIでは、--attach-acr パラメーターを使用します。 Terraform では、 AcrPull ロールを明示的に割り当てます。

resource "azurerm_role_assignment" "aks_acr_pull" {
 scope                = azurerm_container_registry.acr.id
 role_definition_name = "AcrPull"
 principal_id         = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
}

既存の AKS クラスターに対する ACR 統合を構成する

既存の AKS クラスターに ACR をアタッチすることも、クラスターがレジストリにアクセスできないようにする場合は、AKS クラスターから ACR をデタッチすることもできます。

この記事の前の例では、ACR に接続されたAzure Container RegistryとAzure Kubernetes Service クラスターを作成しました。 クラスターからコンテナー レジストリをアタッチまたはデタッチし、この記事で作成した ACR および AKS クラスターを使用する方法の例を次に示します。 変数の値は、独自の ACR および AKS クラスターの値に置き換えることができます。

ACR を既存の AKS クラスターにアタッチする

az aks update コマンドと --attach-acr パラメーターを使用して、既存の ACR を既存の AKS クラスターと統合します。

# Attach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $MYACR


# Attach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $ACR_RESOURCE_ID

az aks update --attach-acr コマンドでは、コマンドを実行しているユーザーのアクセス許可を使って、ACR ロール割り当てが作成されます。 このロールは、kubelet マネージド ID に割り当てられます。 AKS マネージド ID について詳しくは、「マネージド ID の概要」をご覧ください。

Set-AzAksCluster コマンドと -AcrNameToAttach パラメーターを使用して、既存の ACR を既存の AKS クラスターと統合します。

$AttachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToAttach = $MyAcr
}

Set-AzAksCluster @AttachCluster

Set-AzAksCluster -AcrNameToAttach コマンドレットは、コマンドを実行しているユーザーのアクセス許可を使用して、ロール ACR の割り当てを作成します。 このロールは、kubelet マネージド ID に割り当てられます。 AKS マネージド ID について詳しくは、「マネージド ID の概要」をご覧ください。

AKS クラスターが既に存在する場合は、両方のリソースを参照し、同じロールの割り当てを作成することで、ACR をアタッチできます。

data "azurerm_kubernetes_cluster" "existing_aks" {
 name                = "myAKSCluster"
 resource_group_name = "myClusterResourceGroup"
}
data "azurerm_container_registry" "existing_acr" {
 name                = "mycontainerregistry"
 resource_group_name = "myContainerRegistryResourceGroup"
}
resource "azurerm_role_assignment" "existing_aks_acr_pull" {
 scope                = data.azurerm_container_registry.existing_acr.id
 role_definition_name = "AcrPull"
 principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
}

AKS クラスターから ACR をデタッチする

az aks update パラメーターを指定して --detach-acr コマンドを使用して、ACR と AKS クラスターの統合を削除します。

# Detach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $MYACR

# Detach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $ACR_RESOURCE_ID

Set-AzAksCluster パラメーターを指定して -AcrNameToDetach コマンドを使用して、ACR と AKS クラスターの統合を削除します。

$DetachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToDetach = $MyAcr
}

Set-AzAksCluster @DetachCluster

アクセスを削除するには、イメージをプルするアクセス許可をクラスターに付与するロールの割り当てを削除します。

# Remove this resource to revoke access
# resource "azurerm_role_assignment" "existing_aks_acr_pull" {
#   scope                = data.azurerm_container_registry.existing_acr.id
#   role_definition_name = "AcrPull"
#   principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
# }

構成を初期化してデプロイする

構成が完了したら、Terraform を初期化し、実行プランを確認してから適用します。

terraform fmt
terraform init
terraform validate
terraform plan
terraform apply

この時点で、AKS クラスターは ACR からイメージをプルするように構成されます。

次のことが可能になりました。

  • ACR にイメージをインポートします。
  • ワークロードを AKS にデプロイします。
  • ポッド デプロイを確認します。

ACR と AKS の操作

イメージを ACR にインポートし、そのイメージを AKS クラスターにデプロイします。

イメージを ACR にインポートする

az acr import コマンドを使用して、Docker Hubから ACR にイメージをインポートします。

az acr import \
  --name $MYACR \
  --source docker.io/library/nginx:latest \
  --image nginx:v1

次のコマンドを実行して、イメージがインポートされたことを確認します。

az acr repository show --name $MYACR --repository nginx
az acr repository show-tags --name $MYACR --repository nginx

Import-AzContainerRegistryImage コマンドレットを使用して、Docker Hubから ACR にイメージをインポートします。

$ImportImage = @{
 RegistryName = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 SourceRegistryUri = 'docker.io'
 SourceImage = 'library/nginx:latest'
 TargetTag = 'nginx:v1'
}

Import-AzContainerRegistryImage @ImportImage

次のコマンドを実行して、イメージがインポートされたことを確認します。

Get-AzContainerRegistryRepository -RegistryName $MyAcr

Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx

デプロイ ファイルを作成する

ACR にインポートしたイメージを参照する Kubernetes デプロイを作成します。 デプロイが成功し、イメージが正しくプルされた場合、AKS クラスターは ACR と適切に統合されます。

次のサンプル YAML を使用して 、acr-nginx.yaml という名前のファイルを作成します。 image プロパティで、acr-name を ACR の名前に置き換えます。 Azure CLIで、echo $MYACR を実行して ACR 名を表示します。 Azure PowerShellで、$MyAcr を実行して ACR 名を表示します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx0-deployment
  labels:
    app: nginx0-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx0
  template:
    metadata:
      labels:
        app: nginx0
    spec:
      containers:
      - name: nginx
        image: <acr-name>.azurecr.io/nginx:v1
        ports:
        - containerPort: 80

資格情報を取得してデプロイを実行する

  1. az aks get-credentials コマンドを使用して、適切な AKS 資格情報を持っていることを確認します。

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. kubectl apply コマンドを使用して、AKS クラスターでデプロイを実行します。

    kubectl apply -f acr-nginx.yaml
    
  3. kubectl get pods コマンドを使用してデプロイをモニターします。

    kubectl get pods
    

    次の出力例に示すように、出力には 2 つの実行中のポッドが表示されます。

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    
  1. Import-AzAksCredential コマンドレットを使用して、適切な AKS 資格情報を持っていることを確認します。

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. kubectl apply コマンドを使用して、AKS クラスターでデプロイを実行します。

    kubectl apply -f acr-nginx.yaml
    
  3. kubectl get pods コマンドを使用してデプロイをモニターします。

    kubectl get pods
    

    次の出力例に示すように、出力には 2 つの実行中のポッドが表示されます。

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    

トラブルシューティング

リソースをクリーンアップする

この記事で作成したリソースが不要になったら、リソース グループを削除して、関連付けられているすべてのリソースを削除できます。 これらのコマンドは、ACR と AKS クラスター、および MC_ で始まるクラスター ノード リソース グループを削除します。

az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force