Kubernetes (SSE) 用 Azure Key Vault シークレット ストア拡張機能は、オフライン アクセスのために Azure Key Vault から Azure Arc 対応 Kubernetes クラスター にシークレットを自動的に同期します。 つまり、半切断状態で Kubernetes クラスターを実行している場合でも、Azure Key Vault を使用してシークレットを格納、維持、ローテーションできます。 同期されたシークレットは、クラスター シークレット ストアに格納され、Kubernetes シークレットとして使用できるようになり、データ ボリュームとしてマウントされるや、ポッド内のコンテナーに環境変数として公開されるなどのいつもの方法で使用できます。
同期されたシークレットは重要なビジネス資産であるため、SSE は分離された名前空間、ロールベースのアクセス制御 (RBAC) ポリシー、および同期コントローラーの制限付きアクセス許可を使用してセキュリティで保護します。 保護を強化するには、クラスター上の Kubernetes シークレット ストアを暗号化します。
この記事では、SSE を Azure Arc 対応 Kubernetes の拡張機能としてインストールして構成する方法について説明します。
ヒント
Azure Key Vault への接続が完璧ではない可能性がある Azure クラウドの外部のクラスターには、SSE をお勧めします。 SSE は、その性質上、Kubernetes シークレット ストアにシークレットのコピーを作成します。 シークレットのローカル コピーの作成を回避し、クラスターが Azure Key Vault に完全に接続されている場合は、Arc 対応 Kubernetes クラスターのシークレット アクセスにオンライン専用 の Azure Key Vault シークレット プロバイダー拡張機能 を使用できます。 オンラインの Azure Key Vault シークレット プロバイダー拡張機能とオフライン SSE の両方を同じクラスター内でサイド バイ サイドで実行することはお勧めしません。
前提条件
- Arc 対応クラスター。 これは 自分で接続した クラスタ(このガイドでは K3s クラスターを前提とし、Arc を有効にする方法に関するガイダンスを提供します)、または Azure Arc によって有効化された Microsoft 管理の AKS クラスター です。 クラスターで Kubernetes バージョン 1.27 以降が実行されている必要があります。
-
Azure CLI 拡張機能の最新バージョンを含め、
k8s-extensionを満たしていることを確認します。 - cert-manager は、クラスター内ログ通信の TLS をサポートするために必要です。 このガイドで後述する例で、手順を追ってインストールします。 cert-manager の詳細については、cert-manager.io を参照してください
Azure CLI をインストールしてサインインします (まだ行っていない場合)。
az login
開始する前に、Azure リソースとクラスター リソースの構成に使用する環境変数を設定します。 マネージド ID、Azure Key Vault、またはここに記載されているその他のリソースが既にある場合は、それらのリソースを反映するように環境変数の名前を更新します。 KEYVAULT_NAMEはグローバルに一意である必要があることに注意してください。この名前が Azure 内で既に使用されている場合、keyvault の作成は後で失敗します。
export RESOURCE_GROUP="AzureArcTest"
export CLUSTER_NAME="AzureArcTest1"
export LOCATION="EastUS"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export AZURE_TENANT_ID="$(az account show -s $SUBSCRIPTION --query tenantId --output tsv)"
export CURRENT_USER="$(az ad signed-in-user show --query userPrincipalName --output tsv)"
export KEYVAULT_NAME="my-UNIQUE-kv-name"
export KEYVAULT_SECRET_NAME="my-secret"
export USER_ASSIGNED_IDENTITY_NAME="my-identity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="my-credential"
export KUBERNETES_NAMESPACE="my-namespace"
export SERVICE_ACCOUNT_NAME="my-service-account"
必要に応じて、リソース グループを作成します。
az group create --name ${RESOURCE_GROUP} --___location ${LOCATION}
クラスターでワークロード ID フェデレーションをアクティブにする
SSE は、ワークロード ID フェデレーションという機能を使用して Azure Key Vault シークレットにアクセスし、同期しています。 このセクションでは、機能を設定する方法について説明します。 以降のセクションでは、その使用方法について詳しく説明します。
ヒント
以下の手順は、ワークロード ID フェデレーションを使用して Arc 対応 Kubernetes を構成するための攻略ガイドに基づいています。 その他のサポートについては、そのドキュメントを参照してください。
クラスターがまだ Azure Arc に接続されていない場合は、こちらの手順に従ってください。 この手順では、ワークロード ID フェデレーションを connect コマンドの一部として有効にします。
az connectedk8s connect --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer
クラスターが既に Azure Arc に接続されている場合は、update コマンドを使用してワークロード ID を有効にします。
az connectedk8s update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer
次に、新しい発行者 URL (service-account-issuer) を使用してサービス アカウント トークンを発行するようにクラスターを構成します。これにより、Microsoft Entra ID が、これらのトークンを検証するのに必要な公開キーを見つけることができます。 これらの公開キーは、クラスター独自のサービス アカウント トークン発行者用であり、前に設定した --enable-oidc-issuer オプションの結果として、この URL で取得され、クラウドでホストされました。
必要に応じて、OwnerReferencesPermissionEnforcementアドミッション コントローラーを構成することで、コントロール プレーンで実行される特権リソースとして SSE 独自のアクセス許可を構成することもできます。 このアドミッション コントローラーは、SSE がクラスター内の他のオブジェクトを変更できる量を制限します。
発行者の URL フィールドとアクセス許可の適用を使用して、 kube-apiserver を構成します。 k3s クラスターの例を次に示します。 クラスターには、API サーバーの引数を変更する方法が異なる場合があります:
--kube-apiserver-arg="--service-account-issuer=${SERVICE_ACCOUNT_ISSUER}", "--kube-apiserver-arg=service-account-max-token-expiration=24h" and --kube-apiserver-arg="--enable-admission-plugins=OwnerReferencesPermissionEnforcement"。サービス アカウントの発行者 URL を取得します。
export SERVICE_ACCOUNT_ISSUER="$(az connectedk8s show --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --query "oidcIssuerProfile.issuerUrl" --output tsv)" echo $SERVICE_ACCOUNT_ISSUERK3s クラスターの構成ファイル内の API サーバー引数を更新します。
cat <<EOF > /tmp/k3s-config.yaml kube-apiserver-arg: - 'service-account-issuer=${SERVICE_ACCOUNT_ISSUER}' - 'service-account-max-token-expiration=24h' - 'enable-admission-plugins=OwnerReferencesPermissionEnforcement' EOF sudo mv /tmp/k3s-config.yaml /etc/rancher/k3s/config.yaml
kube-apiserver を再起動します。
sudo systemctl restart k3s(省略可能)サービス アカウントの発行者が正しく構成されていることを確認します。
kubectl cluster-info dump | grep service-account-issuer
シークレットを作成し、それにアクセスするための ID を構成する
特定の Azure Key Vault シークレットにアクセスして同期するには、SSE では、そのシークレットにアクセスするための適切な Azure アクセス許可を持つ Azure マネージド ID へのアクセスが必要です。 マネージド ID は、前にアクティブ化したワークロード ID 機能を使用して、Kubernetes サービス アカウントにリンクされている必要があります。 SSE では、関連付けられているフェデレーションされた Azure マネージド ID を使用して、Azure Key Vault から Kubernetes シークレット ストアにシークレットをプルします。 以降のセクションでは、これを設定する方法について説明します。
Azure Key Vault を作成する
Azure Key Vault を作成してシークレットを追加します。 Azure Key Vault とシークレットが既にある場合は、このセクションをスキップしてください。
Azure Key Vault を作成します。
az keyvault create --resource-group "${RESOURCE_GROUP}" --___location "${LOCATION}" --name "${KEYVAULT_NAME}" --enable-rbac-authorizationシークレットを作成できるように、自分にコンテナーに対する 'Secrets Officer' アクセス許可を付与します:
az role assignment create --role "Key Vault Secrets Officer" --assignee ${CURRENT_USER} --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}シークレットを作成して更新し、次の 2 つのバージョンを使用できるようにします:
az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello!' az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello2'
ユーザー割り当てマネージド ID を作成する
次に、ユーザー割り当てマネージド ID を作成し、Azure Key Vault にアクセスするためのアクセス許可を付与します。 Azure Key Vault に対する Key Vault 閲覧者と Key Vault シークレット ユーザーのアクセス許可を持つマネージド ID が既にある場合は、このセクションをスキップできます。 詳細については、「 ユーザー割り当てマネージド ID の作成 」および「 Key Vault での Azure RBAC シークレット、キー、証明書のアクセス許可の使用」を参照してください。
ユーザー割り当てマネージド ID の作成:
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --___location "${LOCATION}" --subscription "${SUBSCRIPTION}"ID に Key Vault 閲覧者と Key Vault シークレット ユーザーのアクセス許可を付与します。 これらのコマンドが成功する前に、ID の作成のレプリケーションをしばらく待つ必要がある場合があります:
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)" az role assignment create --role "Key Vault Reader" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME} az role assignment create --role "Key Vault Secrets User" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
フェデレーション ID 資格情報を作成する
シークレットへのアクセスが必要なワークロードの Kubernetes サービス アカウントを作成します。 次に、マネージド ID、OIDC サービス アカウント発行者、および Kubernetes サービス アカウントの間でリンクする フェデレーション ID 資格情報 を作成します。
マネージド ID にフェデレーションされる Kubernetes サービス アカウントを作成します。 関連付けられているユーザー割り当てマネージド ID の詳細で注釈を付けます。
kubectl create ns ${KUBERNETES_NAMESPACE}cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: ${SERVICE_ACCOUNT_NAME} namespace: ${KUBERNETES_NAMESPACE} EOFフェデレーション ID 資格情報の作成:
az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name ${USER_ASSIGNED_IDENTITY_NAME} --resource-group ${RESOURCE_GROUP} --issuer ${SERVICE_ACCOUNT_ISSUER} --subject system:serviceaccount:${KUBERNETES_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange
SSE をインストールする
SSE は、Azure Arc 拡張機能として使用できます。 Azure Arc 対応の Kubernetes クラスター は、Azure Arc 対応 Kubernetes 拡張機能を使用して拡張できます。 拡張機能により、接続されたクラスターで Azure の機能が有効になり、拡張機能のインストールとライフサイクル管理に Azure Resource Manager 主導のエクスペリエンスが提供されます。
また、クラスター サービス間でログを安全に通信するには、cert-manager と trust-manager も必要であり、これらは Arc 拡張機能の前にインストールする必要があります。
cert-manager をインストールします。
helm repo add jetstack https://charts.jetstack.io/ --force-update helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=truetrust-manager をインストールします。
helm upgrade trust-manager jetstack/trust-manager --install --namespace cert-manager --wait次のコマンドを使用して、Arc 対応クラスターに SSE をインストールします。
az k8s-extension create \ --cluster-name ${CLUSTER_NAME} \ --cluster-type connectedClusters \ --extension-type microsoft.azure.secretstore \ --resource-group ${RESOURCE_GROUP} \ --name ssarcextension \ --scope cluster必要に応じて、
--configuration-settings rotationPollIntervalInSeconds=<time_in_seconds>を追加して既定の回転ポーリング間隔を変更できます (構成リファレンスを参照)。
SSE を構成する
Kubernetes カスタム リソースのインスタンスを定義して、Azure Key Vault とクラスターに同期するシークレットに関する情報を使用して、インストールされている拡張機能を構成します。 次の 2 種類のカスタム リソースを作成します:
- Key Vault への接続を定義する
SecretProviderClassオブジェクト。 - 同期する各シークレットの
SecretSyncオブジェクト。
SecretProviderClass リソースを作成する
SecretProviderClass リソースは、Azure Key Vault への接続、コンテナーへのアクセスに使用する ID、同期するシークレット、ローカルに保持する各シークレットのバージョンの数を定義するために使用されます。
同期する予定の Azure Key Vault ごとに、Azure Key Vault へのアクセスに使用される ID ごとに、およびターゲット Kubernetes 名前空間ごとに個別の SecretProviderClass が必要です。
この例に従って、Key Vault とシークレットの適切な値を持つ 1 つ以上の SecretProviderClass YAML ファイルを作成します。
cat <<EOF > spc.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: secret-provider-class-name # Name of the class; must be unique per Kubernetes namespace
namespace: ${KUBERNETES_NAMESPACE} # Kubernetes namespace to make the secrets accessible in
spec:
provider: azure
parameters:
clientID: "${USER_ASSIGNED_CLIENT_ID}" # Managed Identity Client ID for accessing the Azure Key Vault with.
keyvaultName: ${KEYVAULT_NAME} # The name of the Azure Key Vault to synchronize secrets from.
objects: |
array:
- |
objectName: ${KEYVAULT_SECRET_NAME} # The name of the secret to synchronize.
objectType: secret
objectVersionHistory: 2 # [optional] The number of versions to synchronize, starting from latest.
tenantID: "${AZURE_TENANT_ID}" # The tenant ID of the Key Vault
EOF
追加の構成ガイダンスについては、 SecretProviderClass リファレンスを参照 してください。
SecretSync オブジェクトを作成します
SecretSyncによってフェッチされた項目を Kubernetes に格納する方法を定義するには、SecretsProviderClass オブジェクトが必要です。 Kubernetes シークレットは、 ConfigMapsと同様にキー値マップであり、 SecretSync オブジェクトは、リンクされた SecretsProviderClass で定義された項目を Kubernetes シークレット内のキーにマップする方法を SSE に指示します。 SSE は、それを記述する SecretSync と同じ名前の Kubernetes シークレットを作成します。
このテンプレートに従って、kubernetes シークレットごとに 1 つの SecretSync オブジェクト YAML ファイルを作成します。 Kubernetes 名前空間は、 SecretProviderClassの名前空間と一致する必要があります。
cat <<EOF > ss.yaml
apiVersion: secret-sync.x-k8s.io/v1alpha1
kind: SecretSync
metadata:
name: secret-sync-name # Name of the object; must be unique per Kubernetes namespace
namespace: ${KUBERNETES_NAMESPACE} # Kubernetes namespace
spec:
serviceAccountName: ${SERVICE_ACCOUNT_NAME} # The Kubernetes service account to be given permissions to access the secret.
secretProviderClassName: secret-provider-class-name # The name of the matching SecretProviderClass with the configuration to access the AKV storing this secret
secretObject:
type: Opaque
data:
- sourcePath: ${KEYVAULT_SECRET_NAME}/0 # Name of the secret in Azure Key Vault with an optional version number (defaults to latest)
targetKey: ${KEYVAULT_SECRET_NAME}-data-key0 # Target name of the secret in the Kubernetes secret store (must be unique)
- sourcePath: ${KEYVAULT_SECRET_NAME}/1 # [optional] Next version of the AKV secret. Note that versions of the secret must match the configured objectVersionHistory in the secrets provider class
targetKey: ${KEYVAULT_SECRET_NAME}-data-key1 # [optional] Next target name of the secret in the K8s secret store
EOF
ヒント
SecretProviderClass
objectVersionHistory 2 の<からシークレットを参照する場合は、"/0" を含めないでください。 最新バージョンは暗黙的に使用されます。
追加の構成ガイダンスについては、 SecretSync リファレンスを参照 してください。
構成 CR を適用する
kubectl apply コマンドを使用して、構成カスタム リソース (CR) を適用します:
kubectl apply -f ./spc.yaml
kubectl apply -f ./ss.yaml
SSE は、シークレットを自動的に検索し、クラスターとの同期を開始します。
クラスターに同期しているシークレットを観察する
構成が適用されると、SSE のインストール時に指定した間隔で、シークレットがクラスターへの同期を自動的に開始します。
同期されたシークレットを表示する
次のコマンドを実行して、クラスターに同期されたシークレットを表示します:
# View a list of all secrets in the namespace
kubectl get secrets -n ${KUBERNETES_NAMESPACE}
ヒント
-o yamlまたは-o jsonを追加して、kubectl getコマンドとkubectl describeコマンドの出力形式を変更します。
シークレットの値を表示する
Kubernetes シークレット ストアに格納された、同期されたシークレットの値を表示するには、次のコマンドを使用します:
kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key0}" | base64 -d && echo
kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key1}" | base64 -d && echo
トラブルシューティング
問題の診断と解決については、 トラブルシューティング ガイド を参照してください。
SSE を削除する
SSE を削除し、シークレットの同期を停止するには、az k8s-extension delete コマンドを使用してアンインストールします。
az k8s-extension delete --name ssarcextension --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters
拡張機能をアンインストールしても、シークレット、SecretSync オブジェクト、または CRD はクラスターから削除されません。 これらのオブジェクトは、kubectl を使用して直接削除する必要があります。
SecretSync CRD を削除すると、すべての SecretSync オブジェクトが削除され、既定ではすべての所有シークレットが削除されますが、シークレットは次の場合に保持される場合があります:
このような場合は、 kubectlを使用してシークレットを直接削除する必要があります。
次のステップ
- Azure Arc 拡張機能の詳細を確認します。
- Azure Key Vault の詳細はこちらです。
- Azure Arc 対応 Kubernetes のセキュリティブックのガイダンスに従って、クラスターを他の方法で保護します。