Identityに権限を与える方法(AKSからACRを利用する状況を例に)
- 初めに
- 1.ACRの用意
- 2.ACRにDocker Imageをpushする
- 3.AKSがACRからimage pullできるようにする
- 4.AKSがACRからイメージをpullできるか試す
- 5.クリーンアップ
- 参考資料
初めに
ACR(Azure Container Registry)に格納済みのコンテナイメージを用いて、AKS(Azure Kubernetes Service)にPodをデプロイしようとした際に、権限周りの設定方法が色々あり、頭が混乱してきたので、まとめてみました。
まず前提の話を少しだけすると、
AzureにはRBAC(role-based access control)という概念が存在し、Azureリソースから他のAzureリソースにアクセスするためには、アクセス側のIdentityに対して、必要な権限を与える必要があります。
Identityには、
①service principal
②system-assigned managed identity
③user-assigned managed identity
の三種類が存在し、それぞれ権限付与手順が異なるので、順番に見ていきたいと思います。
上記三つの違いはこちらを参照ください
Demystifying Service Principals - Managed Identities | Azure DevOps Blog
1.ACRの用意
#ResourceGroupの作成 $ RG="test" $ az group create -g $RG -l japaneast #ACRを作成 #注:ACR名は全世界でユニークである必要性がある $ ACR_NAME="testACRXXX" $ az acr create -g $RG -n $ACR_NAME --sku Basic
2.ACRにDocker Imageをpushする
#acrにログインしてdocker pushできるように $ az acr login -n $ACR_NAME #acrのサーバ名を確認 #注:ACR名の一部に大文字が含まれていても、小文字に変換されてしまう $ az acr show -n $ACR_NAME --query loginServer -o table Result ------------------------------ testacrXXX.azurecr.io #変数ACR_NAMEを大文字から小文字へ変更 $ ACR_NAME=`echo $ACR_NAME | tr '[:upper:]' '[:lower:]'` #ACRにpushする用のImageをpull #今回は実験用なのでサイズが小さいalpineイメージを使用 $ docker pull alpine #Imageにタグ付けする #注:"testACR"ではなく"testacr"である $ docker tag alpine $ACR_NAME.azurecr.io/alpine:v1 #ACRにイメージをpush $ docker push $ACR_NAME.azurecr.io/alpine:v1 #ACRにちゃんとpushできたか確認 #ACRに存在するrepositoryを全表示 $ az acr repository list -n $ACR_NAME -otable Result -------- alpine #ACRのalpineリポジトリに存在するタグを全表示 $ az acr repository show-tags -n $ACR_NAME --repository alpine -otable Result -------- v1
※”unauthorized: authentication required”と表示されてimage pushできない人はおそらくタグ付けの段階でスペル間違えてます。(経験談)
1章2章の参考資料:
Tutorial - Prepare container registry to deploy image - Azure Container Instances | Microsoft Docs
3.AKSがACRからimage pullできるようにする
3章の共通部分
#AKSの名前設定 $ AKS_NAME="testaks"
3-1.AKSのIdentityにservice principalを使用する場合
service principalを利用する場合は、AKSに紐づけられたservice principalに当該ACRのAcrPull権限が必要。
①service principalを自動作成する場合
(ⅰ)AKS作成時にACR設定する場合
#AKS作成時に、利用するACRを指定 $ az aks create -g $RG -n $AKS_NAME --attach-acr $ACR_NAME
(ⅱ)AKS作成後に設定を更新して、ACRを利用できるようにする場合
#AKS作成 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s #ACRを利用できるように、設定を更新 $ az aks update -g $RG -n $AKS_NAME --attach-acr $ACR_NAME
②service principalを手動作成する場合
3-1-②の共通部分
#AKSと紐づけるservice principalを生成し、そのID及びPASSWORDを変数に格納 $ APP_ID=$(az ad sp create-for-rbac --skip-assignment -n test-aks-sp --query appId -otsv) $ PASSWORD=$(az ad sp credential reset --name $APP_ID --query password -otsv)
(ⅰ)AKS作成時にACR設定する場合
#AKS作成時にserviceprincipal、password、利用するACRを指定 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --service-principal $APP_ID --client-secret $PASSWORD --attach-acr $ACR_NAME
(ⅱ)AKS作成後に設定を更新して、ACRを利用できるようにする場合
#AKS作成時にservice principal、passwordを指定 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --service-principal $APP_ID --client-secret $PASSWORD #ACRを利用できるように、設定を更新 $ az aks update -g $RG -n $AKS_NAME --attach-acr $ACR_NAME
(ⅲ)AKSに紐づけられたservice principalに適切なRoleを割り当てる場合
#AKS作成時にservice principal、passwordを指定 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --service-principal=$APP_ID --client-secret=$PASSWORD #ACRのresource idを取得 $ ACR_ID=$(az acr show -g $RG -n $ACR_NAME --query id -otsv) #AKSのServicePrincipalに”ACRからイメージをpullする権限”を付与 $ az role assignment create --assignee $APP_ID --scope $ACR_ID --role AcrPull
3-1の参考資料:
Service principals for Azure Kubernetes Services (AKS) - Azure Kubernetes Service | Microsoft Docs
3-2.AKSのIdentityにmanaged identityを使用する場合
AKSのmanaged identityにはContorolPlaneとKubeletの二つがある。
ACRのコンテナイメージを利用する場合は、AKSのkubeletのmanaged identityに当該ACRのAcrPull権限が必要。
Use managed identities in Azure Kubernetes Service - Azure Kubernetes Service | Microsoft Docs
①system-assigned managed identityを使用する場合
(ⅰ)AKS作成時にACR設定する場合
#AKS作成時に、managed identityを有効化、利用するACRを指定 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --enable-managed-identity --attach-acr $ACR_NAME
(ⅱ)AKS作成後に設定を更新して、ACRを利用できるようにする場合
#AKS作成時に、managed identityを有効化 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --enable-managed-identity #ACRを利用できるように、設定を更新 $ az aks update -g $RG -n $AKS_NAME --attach-acr $ACR_NAME
(ⅲ)AKSのmanaged identity(kubelet)に適切なRoleを割り当てる場合
#AKS作成時に、managed identityを有効化 $ az aks create -g $RG -n $AKS_NAME --node-count 1 --node-vm-size Standard_B2s --enable-managed-identity #kubeletのmanaged identityを取得 #kubeletのmanaged identityは"${AKSの名前}-agentpool"で表示されるので、下記のように検索 $ MI=$(az ad sp list --all --filter "displayName eq 'test-aks-agentpool'" --query [].objectId -otsv) #kubeletのmanaged identityに対して”ACRからイメージをpullする権限”を付与 $ ACR_ID=$(az acr show -g $RG -n $ACR_NAME --query id -otsv) $ az role assignment create --assignee $MI --scope $ACR_ID --role AcrPull
②user-assigned managed identityを使用する場合
3-2-②の共通部分
#各managed identityを作成し、それぞれのIDを変数へ代入しておく $ ID=$(az identity create -n test-identity -g $RG --query id -otsv) $ KUBELET_ID=$(az identity create -n test-kubelet-identity -g $RG --query id -otsv) $ SUBNET_ID=$(az network vnet create -g $RG -n test-vnet --address-prefixes 10.0.0.0/8 --subnet-name test-subnet --subnet-prefixes 10.0.0.0/16 --query 'newVNet.subnets[0].id' -otsv)
(ⅰ)AKS作成時にACR設定する場合
#AKS作成時、kubelet用のidentityを指定、利用するACRを指定 $ az aks create -g $RG -n $AKS_NAME --network-plugin azure --vnet-subnet-id $SUBNET_ID --docker-bridge-address 172.17.0.1/16 --dns-service-ip 10.2.0.10 --service-cidr 10.2.0.0/24 --enable-managed-identity --assign-identity $ID --assign-kubelet-identity $KUBELET_ID --attach-acr $ACR_NAME
(ⅱ)AKS作成後に設定を更新して、ACRを利用できるようにする場合
#AKS作成時、kubelet用のidentityを指定 $ az aks create -g $RG -n $AKS_NAME --network-plugin azure --vnet-subnet-id $SUBNET_ID --docker-bridge-address 172.17.0.1/16 --dns-service-ip 10.2.0.10 --service-cidr 10.2.0.0/24 --enable-managed-identity --assign-identity $ID --assign-kubelet-identity $KUBELET_ID #ACRを利用できるように、設定を更新 $ az aks update -g $RG -n $AKS_NAME --attach-acr $ACR_NAME
(ⅲ)AKSに紐づけられたmanaged identity(kubelet)に適切なRoleを割り当てる場合
#AKS作成時、kubelet用のidentityを指定 $ az aks create -g $RG -n $AKS_NAME --network-plugin azure --vnet-subnet-id $SUBNET_ID --docker-bridge-address 172.17.0.1/16 --dns-service-ip 10.2.0.10 --service-cidr 10.2.0.0/24 --enable-managed-identity --assign-identity $ID --assign-kubelet-identity $KUBELET_ID #kubeletのmanaged identityに対して”ACRからイメージをpullする権限”を付与 $ ACR_ID=$(az acr show -g $RG -n $ACR_NAME --query id -otsv) $ az role assignment create --assignee $KUBELET_ID --scope $ACR_ID --role AcrPull
上記のことを行うためには、azure-cliのversion2.26.0以上が要求されるのですが、
現在、azure-cli 2.26.0のバグのため、実際には実行不可能な模様。
(自身の環境では、az ask create実行時に下記のようなエラーが発生してしまう)
az acr build results in "TypeError: 'NoneType' object is not callable" - githubmemory
3-2-②の参考資料:
Azure Kubernetes Service (AKS) with Bring-Your-Own Identity (BYOID) | by Jonathan | Jun, 2021 | Medium
4.AKSがACRからイメージをpullできるか試す
#AKSにアクセスするために認証する $ az aks get-credentials -g $RG -n $AKS_NAME #ACRに先ほどpushしたイメージを用いてPodを作成し、適当なコマンドを実行させる $ k run test --image $ACR_NAME.azurecr.io/alpine:v1 --command sleep 3600 pod/test created #無事、イメージのpullが成功し、Podがrunning状態であることを確認 $ k get po --watch NAME READY STATUS RESTARTS AGE test 1/1 Running 0 2m31s
5.クリーンアップ
#現在存在しているResourceGroupを全部表示する az group list -otable #test ResourceGroupを削除 #--no-waitを指定すると、削除中でもターミナルが使うことが可能 az group delete -g $RG --no-wait -y #VNet作成時に自動で作成されたResourceGruopも削除 az group delete -g NetworkWatcherRG --no-wait -y #全てのResourceGroupが削除中になっているか確認 az group list -otable
参考資料
Managed identities for Azure resources | Microsoft Docs
Assign Azure roles using Azure CLI - Azure RBAC | Microsoft Docs