Azure Kubernetes Service で Azure Active Directory ポッドマネージド ID を使用する (プレビュー)

Azure Active Directory ポッドマネージド ID では、Kubernetes プリミティブを使用して Azure リソース用マネージド ID と Azure Active Directory (AAD) の ID をポッドに関連付けます。 管理者は、ID とバインドを Kubernetes プリミティブとして作成し、ID プロバイダーとして AAD に依存する Azure リソースにポッドがアクセスできるようにします。

注意

このドキュメントに記載されている機能、ポッドマネージド ID (プレビュー) は、ポッドマネージド ID V2 (プレビュー) に置き換えられます。 AADPODIDENTITY が既にインストールされている場合は、V2 への移行オプションがあります。 移行の詳細は、2022 年第 2 四半期に予定されているパブリック プレビューが近づくにつれて提供される予定です。 この機能を有効にすると、MIC コンポーネントは不要になります。

重要

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿のまま" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。

開始する前に

次のリソースがインストールされている必要があります。

  • Azure CLI バージョン 2.20.0 以降
  • aks-preview 拡張機能バージョン 0.5.5 以降

制限事項

  • クラスターに対して最大 200 のポッド ID が許可されます。
  • クラスターに対して最大 200 のポッド ID の例外が許可されます。
  • ポッドマネージド ID は、Linux ノード プールでのみ使用できます。

EnablePodIdentityPreview を登録する

EnablePodIdentityPreview 機能を登録します。

az feature register --name EnablePodIdentityPreview --namespace Microsoft.ContainerService

aks-preview Azure CLI をインストールする

aks-preview Azure CLI 拡張機能バージョン 0.5.5 以降も必要です。 aks-preview Azure CLI 拡張機能は、az extension add コマンドを使用してインストールします。 または、az extension update コマンドを使用すると、使用可能な更新プログラムをインストールできます。

# Install the aks-preview extension
az extension add --name aks-preview

# Update the extension to make sure you have the latest version installed
az extension update --name aks-preview

Azure Container Networking Interface (CNI) を使用して AKS クラスターを作成する

注意

これは、推奨される既定の構成です。

Azure CNI とポッドマネージド ID が有効になっている AKS クラスターを作成します。 次のコマンドを実行すると、az group create を使用して myResourceGroup という名前のリソース グループが作成され、az aks create コマンドを使用して myResourceGroup リソース グループに myAKSCluster という名前の AKS クラスターが作成されます。

az group create --name myResourceGroup --location eastus
az aks create -g myResourceGroup -n myAKSCluster --enable-pod-identity --network-plugin azure

注意

Azure Active Directory ポッド ID では、次の 2 つの操作モードがサポートされます。

  1. 標準モード: このモードでは、次の 2 つのコンポーネントが AKS クラスターにデプロイされます。
    • Managed Identity Controller (MIC): Kubernetes API サーバーを介してポッド、AzureIdentity、および AzureIdentityBinding の変更を監視する Kubernetes コントローラー。 MIC は関連する変更を検出すると、必要に応じて AzureAssignedIdentity を追加または削除します。 具体的には、ポッドがスケジュールされている場合、MIC は、作成フェーズ中にノード プールによって使用される基になる VMSS に Azure 上のマネージド ID を割り当てます。 ID を使用しているすべてのポッドが削除された場合、同じマネージド ID が他のポッドによって使用されていない限り、ノード プールの VMSS から ID が削除されます。 MIC は、AzureIdentity または AzureIdentityBinding が作成または削除された場合にも同様のアクションを実行します。
    • Node Management Identity (NMI) は、AKS クラスターの各ノードで DaemonSet として実行されるポッドです。 NMI は、各ノード上の Azure Instance Metadata Service に対するセキュリティ トークン要求をインターセプトし、それをそれ自体にリダイレクトし、トークンを要求している ID にポッドがアクセスできるか検証し、アプリケーションに代わって Azure Active Directory テナントからトークンをフェッチします。
  2. マネージド モード: このモードでは、NMI のみがあります。 ID は、ユーザーが手動で割り当て、管理する必要があります。 詳細については、マネージド モードのポッド ID に関するページをご覧ください。

インストール ガイドに示すように Helm chart または YAML マニフェストを介して Azure Active Directory のポッド ID をインストールする場合、standard または managed モードを選択できます。 そうではなく、この記事に示すように、AKS クラスター アドオンを使用して Azure Active Directory のポッド ID をインストールする場合、セットアップでは managed モードが使用されます。

az aks get-credentials を使用して、AKS クラスターにサインインします。 また、このコマンドにより、ご使用の開発用コンピューターに kubectl クライアント証明書がダウンロードされて構成されます。

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

Azure CNI で既存の AKS クラスターを更新する

ポッドマネージド ID が含まれるように、Azure CNI で既存の AKS クラスターを更新します。

az aks update -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity

Azure Active Directory ポッドマネージド ID で Kubernet ネットワーク プラグインを使用する

重要

Kubernet を使用してクラスターで aad-pod-identity を実行すると、セキュリティに影響するため、推奨される構成ではありません。 Kubernet を使用してクラスターで aad-pod-identity を有効にする前に、対応策の手順に従い、ポリシーを構成してください。

対応策

クラスター レベルでこの脆弱性を緩和するには、Azure の組み込みのポリシー "Kubernetes cluster containers should only use allowed capabilities" (Kubernetes クラスター コンテナーには許可された機能のみを使用する) を使用して、CAP_NET_RAW 攻撃を制限することができます。

NET_RAW を [必須のドロップ機能] に追加します

image

Azure Policy を使用していない場合は、OpenPolicyAgent アドミッション コントローラーと Gatekeeper Validating Webhook を併用することができます。 クラスターに既にゲートキーパーがインストールされている場合は、K8sPSPCapabilities タイプの ConstraintTemplate を追加します。

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/capabilities/template.yaml

NET_RAW 機能を使用してポッドの生成を制限するテンプレートを追加します。

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPCapabilities
metadata:
  name: prevent-net-raw
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    excludedNamespaces:
      - "kube-system"
  parameters:
    requiredDropCapabilities: ["NET_RAW"]

Kubernet ネットワーク プラグインを使用して AKS クラスターを作成する

Kubenet ネットワーク プラグインとポッドマネージド ID が有効になっている AKS クラスターを作成します。

az aks create -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity --enable-pod-identity-with-kubenet

Kubernet ネットワーク プラグインを使用して既存の AKS クラスターを更新する

ポッドマネージド ID が含まれるように、Kubenet ネットワーク プラグインを使用して、既存の AKS クラスターを更新します。

az aks update -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity --enable-pod-identity-with-kubenet

ID の作成

az identity create を使用して ID を作成し、IDENTITY_CLIENT_ID および IDENTITY_RESOURCE_ID の変数を設定します。

az group create --name myIdentityResourceGroup --location eastus
export IDENTITY_RESOURCE_GROUP="myIdentityResourceGroup"
export IDENTITY_NAME="application-identity"
az identity create --resource-group ${IDENTITY_RESOURCE_GROUP} --name ${IDENTITY_NAME}
export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query clientId -otsv)"
export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)"

マネージド ID にアクセス許可を割り当てる

デモを実行するには、IDENTITY_CLIENT_ID マネージド ID に、AKS クラスターの仮想マシン スケール セットを含むリソース グループに対する仮想マシン共同作成者のアクセス許可が付与されている必要があります。

NODE_GROUP=$(az aks show -g myResourceGroup -n myAKSCluster --query nodeResourceGroup -o tsv)
NODES_RESOURCE_ID=$(az group show -n $NODE_GROUP -o tsv --query "id")
az role assignment create --role "Virtual Machine Contributor" --assignee "$IDENTITY_CLIENT_ID" --scope $NODES_RESOURCE_ID

ポッド ID を作成する

az aks pod-identity add を使用して、クラスターのポッド ID を作成します。

重要

ID を作成し、クラスター ID にロール バインドを割り当てるには、サブスクリプションに対して関連するアクセス許可 (所有者など) が必要です。

クラスター ID には、割り当てられる ID のためのマネージド ID オペレーター アクセス許可が必要です。

export POD_IDENTITY_NAME="my-pod-identity"
export POD_IDENTITY_NAMESPACE="my-app"
az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME} --identity-resource-id ${IDENTITY_RESOURCE_ID}

注意

AKS クラスターでポッドマネージド ID を有効にすると、aks-addon-exception という名前の AzurePodIdentityException が kube-system 名前空間に追加されます。 AzurePodIdentityException を使用すると、Node Managed Identity (NMI) サーバーによって傍受されることなく、特定のラベルを持つポッドから Azure Instance Metadata Service (IMDS) エンドポイントにアクセスできます。 aks-addon-exception を使用すると、AAD ポッドマネージド ID などの AKS ファーストパーティのアドオンを、AzurePodIdentityException を手動で設定しなくても動作させることができます。 必要に応じて、az aks pod-identity exception addaz aks pod-identity exception deleteaz aks pod-identity exception update、または kubectl を使用して、AzurePodIdentityException を追加、削除、更新することができます。 "POD_IDENTITY_NAME" は RFC 1123 に定義されている有効な DNS サブドメイン名にする必要があります。

注意

pod-identity add を使用してポッド ID を割り当てると、Azure CLI はポッド ID (IDENTITY_RESOURCE_ID) を介して、マネージド ID オペレーター ロールをクラスター ID に付与しようとします。

サンプル アプリケーションを実行する

ポッドで AAD ポッドマネージド ID を使用すには、ポッドに AzureIdentityBinding のセレクターと一致する値を持つ aadpodidbinding ラベルが必要です。 AAD ポッドマネージド ID を使用してサンプル アプリケーションを実行するには、次の内容を含む demo.yaml ファイルを作成します。 POD_IDENTITY_NAMEIDENTITY_CLIENT_ID、および IDENTITY_RESOURCE_GROUP を、前の手順の値に置き換えます。 SUBSCRIPTION_ID を実際のサブスクリプション ID に置き換えます。

注意

前の手順では、POD_IDENTITY_NAMEIDENTITY_CLIENT_ID、および IDENTITY_RESOURCE_GROUP の変数を作成しました。 echo などのコマンドを使用して、変数に設定した値 (echo $IDENTITY_NAME など) を表示できます。

apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    aadpodidbinding: $POD_IDENTITY_NAME
spec:
  containers:
  - name: demo
    image: mcr.microsoft.com/oss/azure/aad-pod-identity/demo:v1.6.3
    args:
      - --subscriptionid=$SUBSCRIPTION_ID
      - --clientid=$IDENTITY_CLIENT_ID
      - --resourcegroup=$IDENTITY_RESOURCE_GROUP
    env:
      - name: MY_POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: MY_POD_NAMESPACE
        valueFrom:
          fieldRef:
            fieldPath: metadata.namespace
      - name: MY_POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
  nodeSelector:
    kubernetes.io/os: linux

ポッド定義には、前の手順で実行した az aks pod-identity add のポッド ID の名前と一致する値を持つ aadpodidbinding ラベルが含まれていることに注目してください。

kubectl apply を使用して、ポッド ID と同じ名前空間に demo.yaml をデプロイします。

kubectl apply -f demo.yaml --namespace $POD_IDENTITY_NAMESPACE

kubectl logs を使用して、サンプル アプリケーションが正常に実行されていることを確認します。

kubectl logs demo --follow --namespace $POD_IDENTITY_NAMESPACE

ログに、トークンが正常に取得されたこと、および GET 操作が正常に完了したことが表示されていることを確認します。

...
successfully doARMOperations vm count 0
successfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)
successfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
successfully made GET on instance metadata
...

複数の ID を使用してアプリケーションを実行する

複数の ID を作成する

az identity create を使用して ID を作成し、IDENTITY_CLIENT_ID および IDENTITY_RESOURCE_ID の変数を設定します。

az group create --name myIdentityResourceGroup --location eastus
export IDENTITY_RESOURCE_GROUP="myIdentityResourceGroup"
export IDENTITY_NAME_1="application-identity_1"
az identity create --resource-group ${IDENTITY_RESOURCE_GROUP} --name ${IDENTITY_NAME_1}
export IDENTITY_NAME_2="application-identity_2"
az identity create --resource-group ${IDENTITY_RESOURCE_GROUP} --name ${IDENTITY_NAME_2}
export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME_1} --query clientId -otsv)"
export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME_1} --query id -otsv)"
export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME_2} --query clientId -otsv)"
export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME_2} --query id -otsv)"

マネージド ID にアクセス許可を割り当てる

IDENTITY_CLIENT_ID マネージド ID には、AKS クラスターの仮想マシン スケール セットを含むリソース グループに対する閲覧者のアクセス許可が付与されている必要があります。

NODE_GROUP=$(az aks show -g myResourceGroup -n myAKSCluster --query nodeResourceGroup -o tsv)
NODES_RESOURCE_ID=$(az group show -n $NODE_GROUP -o tsv --query "id")
az role assignment create --role "Reader" --assignee "$IDENTITY_CLIENT_ID_1" --scope $NODES_RESOURCE_ID
az role assignment create --role "Reader" --assignee "$IDENTITY_CLIENT_ID_2" --scope $NODES_RESOURCE_ID

ポッド ID を作成する

az aks pod-identity add を使用してクラスターのポッド ID を作成します。

重要

ID とロールのバインドを作成するには、サブスクリプションに対する適切なアクセス許可 (Owner など) が必要です。

export POD_IDENTITY_NAME="my-pod-identity"
export POD_IDENTITY_NAMESPACE="my-app"
az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME} --identity-resource-id ${IDENTITY_RESOURCE_ID_1} --binding-selector foo
az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME} --identity-resource-id ${IDENTITY_RESOURCE_ID_2} --binding-selector foo

注意

AKS クラスターでポッドマネージド ID を有効にすると、aks-addon-exception という名前の AzurePodIdentityException が kube-system 名前空間に追加されます。 AzurePodIdentityException を使用すると、Node Managed Identity (NMI) サーバーによって傍受されることなく、特定のラベルを持つポッドから Azure Instance Metadata Service (IMDS) エンドポイントにアクセスできます。 aks-addon-exception を使用すると、AAD ポッドマネージド ID などの AKS ファーストパーティのアドオンを、AzurePodIdentityException を手動で設定しなくても動作させることができます。 必要に応じて、az aks pod-identity exception addaz aks pod-identity exception deleteaz aks pod-identity exception update、または kubectl を使用して、AzurePodIdentityException を追加、削除、更新することができます。

複数の ID を使用してサンプル アプリケーションを実行する

ポッドで AAD ポッドマネージド ID を使用すには、ポッドに AzureIdentityBinding のセレクターと一致する値を持つ aadpodidbinding ラベルが必要です。 AAD ポッドマネージド ID を使用してサンプル アプリケーションを実行するには、次の内容を含む demo.yaml ファイルを作成します。 POD_IDENTITY_NAMEIDENTITY_CLIENT_ID、および IDENTITY_RESOURCE_GROUP を、前の手順の値に置き換えます。 SUBSCRIPTION_ID を実際のサブスクリプション ID に置き換えます。

注意

前の手順では、POD_IDENTITY_NAMEIDENTITY_CLIENT_ID、および IDENTITY_RESOURCE_GROUP の変数を作成しました。 echo などのコマンドを使用して、変数に設定した値 (echo $IDENTITY_NAME など) を表示できます。

apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    aadpodidbinding: foo
spec:
  containers:
  - name: demo
    image: mcr.microsoft.com/oss/azure/aad-pod-identity/demo:v1.6.3
    args:
      - --subscriptionid=$SUBSCRIPTION_ID
      - --clientid=$IDENTITY_CLIENT_ID
      - --resourcegroup=$IDENTITY_RESOURCE_GROUP
    env:
      - name: MY_POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: MY_POD_NAMESPACE
        valueFrom:
          fieldRef:
            fieldPath: metadata.namespace
      - name: MY_POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
  nodeSelector:
    kubernetes.io/os: linux

ポッド定義には、前の手順で実行した az aks pod-identity add のポッド ID の名前と一致する値を持つ aadpodidbinding ラベルが含まれていることに注目してください。

kubectl apply を使用して、ポッド ID と同じ名前空間に demo.yaml をデプロイします。

kubectl apply -f demo.yaml --namespace $POD_IDENTITY_NAMESPACE

kubectl logs を使用して、サンプル アプリケーションが正常に実行されていることを確認します。

kubectl logs demo --follow --namespace $POD_IDENTITY_NAMESPACE

ログに、トークンが正常に取得されたこと、および GET 操作が正常に完了したことが表示されていることを確認します。

...
successfully doARMOperations vm count 0
successfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)
successfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
successfully made GET on instance metadata
...

export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query clientId -otsv)" export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)"


## Clean up

To remove AAD pod-managed identity from your cluster, remove the sample application and the pod identity from the cluster. Then remove the identity.

```azurecli-interactive
kubectl delete pod demo --namespace $POD_IDENTITY_NAMESPACE
az aks pod-identity delete --name ${POD_IDENTITY_NAME} --namespace ${POD_IDENTITY_NAMESPACE} --resource-group myResourceGroup --cluster-name myAKSCluster
az identity delete -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME}

次の手順

マネージド ID の詳細については、Azure リソースのマネージド ID に関するページを参照してください。