Note
この記事では、独自のを作成し、サンプル ポッドを介して Secrets Store CSI Driver のAzure Key Vault プロバイダーをマウントし、結果の Kubernetes シークレットをGateway リスナーのSecretProviderClassで直接参照することで、Gateway リソースで TLS 終了をcertificateRefsで構成する方法について説明します。 この方法は、証明書同期ワークフローを完全に制御する必要がある場合や、これらのリソースを自分で管理する場合に便利です。
ほとんどのユーザーにとって推奨されるパスは、アプリケーション ルーティング オペレーターを利用した自動化されたAzure DNSとAzure Key Vault統合です。この統合により、SecretProviderClass、同期された Kubernetes シークレット、リスナー certificateRefsのペアに基づいてリスナーtls.optionsがプロビジョニングおよび調整されます。 自動化されたワークフローを使用するには、アプリケーション ルーティング ゲートウェイ API の実装を使用したAzure DNSと TLS の構成に関する記事を参照してください。
アプリケーション ルーティング アドオンでは、TLS 終端を使用してゲートウェイ API イングレス トラフィックをセキュリティで保護するために、Azure Key Vault (AKV) からのシークレットの同期がサポートされています。 ゲートウェイで TLS トラフィックを終了する証明書とキーを作成するには、次の手順に従います。
前提条件
- アプリケーション ルーティング ゲートウェイ API の実装を有効にする
- Managed Gateway API のインストールを有効にする
- 環境変数を設定します。
export CLUSTER=<cluster-name> export RESOURCE_GROUP=<resource-group-name> export LOCATION=<location>
必要なクライアント/サーバーの証明書とキー
- サンプル サービスの証明書に署名するためのルート証明書と秘密キーを作成します。
mkdir httpbin_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout httpbin_certs/example.com.key -out httpbin_certs/example.com.crt
-
httpbin.example.comの証明書と秘密キーを生成します。
openssl req -out httpbin_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
openssl x509 -req -sha256 -days 365 -CA httpbin_certs/example.com.crt -CAkey httpbin_certs/example.com.key -set_serial 0 -in httpbin_certs/httpbin.example.com.csr -out httpbin_certs/httpbin.example.com.crt
TLS イングレス ゲートウェイを構成する
Azure Key Vault を設定してシークレットをクラスターに同期する
Azure Key Vault を作成する
アプリケーション ルーティング アドオンに証明書とキー入力を提供するには、 Azure Key Vault リソース が必要です。
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATIONクラスターに対して、シークレット ストア CSI ドライバー用の Azure Key Vault プロバイダー アドオンを有効にします。
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTERKey Vault がアクセス許可モデルに Azure RBAC を使用している場合は、 次 の手順に従って、アドオンのユーザー割り当てマネージド ID に Key Vault シークレット ユーザーの Azure ロールを割り当てます。 または、キー ボルトがボルト アクセス ポリシーのアクセス許可モデルを使用している場合は、アクセス ポリシーを使用して、アドオンのユーザー割り当てマネージド ID が Azure Key Vault リソースにアクセスできるよう承認します。
OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId') az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get listTLS 証明書を指定する方法を選択します。
Azure Key Vaultでは、さまざまなオブジェクトの種類がサポートされています。 このチュートリアルでは、 次のいずれかのエンド ツー エンド オプションを選択し、一般的な検証とゲートウェイの手順に進みます。
Option このオプションは、次の場合に使用します。 Key Vault ストア Kubernetes シークレットの結果 オプション 1: 証明書とキーをKey Vaultシークレットとして格納する この記事で前に生成したファイルなど、個別の PEM 証明書 ( .crt) ファイルと秘密キー (.key) ファイルがあります。2 つのKey Vaultシークレット。 httpbin-credentialという名前の同期された 1 つの Kubernetes TLS シークレット。オプション 2: Key Vault証明書オブジェクトを直接参照する 証明書は、インポートされた .pfxなどの証明書オブジェクトとしてKey Vaultに既に格納されています。1 つのKey Vault証明書オブジェクト。 httpbin-credentialという名前の同期された 1 つの Kubernetes TLS シークレット。Important
両方のオプションに従ってはいけません。 オプション 1 を使用する場合は、証明書とキー ファイルをKey Vaultシークレットとしてアップロードし、オプション 1
SecretProviderClassマニフェストを適用します。 オプション 2 を使用する場合は、Key Vault シークレットのアップロード手順をスキップし、オプション 2SecretProviderClassマニフェストを適用します。
オプション 1: 証明書とキーをKey Vaultシークレットとして格納する
このオプションは、この記事で前に生成したファイルなど、個別の PEM 証明書 (.crt) ファイルと秘密キー (.key) ファイルがある場合に使用します。
証明書とキー ファイルをKey Vaultシークレットとしてアップロードします。
az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-key --file httpbin_certs/httpbin.example.com.key az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-crt --file httpbin_certs/httpbin.example.com.crtNote
証明書またはキーをローテーション (変更) するたびに、この手順を再実行して、新しいバージョンをシークレットとしてアップロードします。 更新された値をクラスターに自動的に同期するには、シークレット ストア CSI ドライバーのAzure Key Vault プロバイダーで自動ローテーションを有効にします。 詳細については、「 自動ローテーションとシークレット同期の概要」を参照してください。 証明書のライフサイクルをKey Vault管理する場合は、代わりにオプション 2 を使用します。
Key Vaultで作成した 2 つのシークレットを参照する
SecretProviderClassを作成します。cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-key objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-crt objectType: secret objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOF
オプション 2: Key Vault証明書オブジェクトを直接参照する
証明書が既に証明書オブジェクトとしてAzure Key Vaultに格納されている場合は、このオプションを使用します。
.crtファイルと.keyファイルを個別のKey Vaultシークレットとしてアップロードする必要はありません。
この例では、 test-httpbin-cert-pfx は Azure Key Vault 内の証明書オブジェクトの名前です。 既存の証明書を証明書オブジェクトとしてKey Vaultにインポートするには、「証明書をKey Vaultにインポートする」を参照してください。 オブジェクト パラメーターの詳細については、「 証明書とキーの取得」を参照してください。
Key Vault証明書オブジェクトを参照する
SecretProviderClassを作成します。cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: cert objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOF
シークレットをクラスターに同期する
オプション 1 またはオプション 2 を完了したら、サンプル ポッドをデプロイしてシークレットをクラスターに同期します。 シークレット ストア CSI ドライバーでは、シークレットがAzure Key Vaultからクラスターに同期されるように、SecretProviderClass リソースを参照するポッドが必要です。
サンプル ポッドをデプロイするには、次のマニフェストを使用します。
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-httpbin spec: containers: - name: busybox image: mcr.microsoft.com/oss/busybox/busybox:1.33.1 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "httpbin-credential-spc" EOFSecretProviderClass リソースで定義されている
httpbin-credential名前空間にdefaultシークレットが作成されていることを確認します。kubectl describe secret/httpbin-credential出力例:
Name: httpbin-credential Namespace: default Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: kubernetes.io/tls Data ==== tls.crt: 1180 bytes tls.key: 1675 bytes
TLS ゲートウェイをデプロイする
TLS 構成で
httpbin-credentialシークレットを参照する Kubernetes ゲートウェイを作成します。cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: approuting-istio listeners: - name: https hostname: "httpbin.example.com" port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: httpbin-credential allowedRoutes: namespaces: from: Selector selector: matchLabels: kubernetes.io/metadata.name: default EOF次に、対応する
HTTPRouteを作成して、ゲートウェイのイングレス トラフィック ルートを構成します。cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin spec: parentRefs: - name: httpbin-gateway hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /status - path: type: PathPrefix value: /delay backendRefs: - name: httpbin port: 8000 EOFゲートウェイ のアドレスとポートを取得します。
kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.status.addresses[0].value}') export SECURE_INGRESS_PORT=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')httpbinサービスにアクセスするための HTTPS 要求を送信します。curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \ --cacert httpbin_certs/example.com.crt "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"httpbin サービスが 418 I'm a Teapot コードを返すことが期待されます。