AKS と EKS で Workload Identity 連携を有効にする

このトピックでは、AKS プラットフォームと EKS プラットフォームで Apigee ハイブリッドのインストール用に Workload Identity 連携を有効にする方法について説明します。

GKE へのインストールの場合は、GKE で Workload Identity を有効にするの手順に沿って操作します。

概要

Workload Identity 連携を使用すると、Google Cloud の外部で実行されているアプリケーションが、外部 ID プロバイダの認証情報を使用して Google Cloud Platform サービス アカウントの権限を借用できます。

Workload Identity 連携を使用すると、外部環境の認証メカニズムをアプリケーションで使用できるようになり、セキュリティを強化できます。また、サービス アカウント キーを置き換えることもできます。

概要については、Workload Identity 連携の使用に関するベスト プラクティスをご覧ください。

Workload Identity 連携を設定する

Apigee ハイブリッドで Workload Identity 連携を使用するには、まずクラスタを構成してから、Apigee ハイブリッド インストールに機能を適用します。

始める前に

以下の手順は、Apigee ハイブリッドのインストールがすでに設定されていることを前提としています。IAM サービス アカウントと Kubernetes サービス アカウントは、初回インストール時に作成されます。Apigee ハイブリッドのインストールの概要については、全体像をご覧ください。

AKS へのインストールの場合は、OpenID Connect(OIDC)発行元が有効になっていることを確認します。Workload Identity 連携が OpenID Connect メタデータとクラスタの JSON Web Key Set(JWKS)にアクセスできるように、この機能を有効にする必要があります。

Workload Identity 連携を使用するようにクラスタを構成します。

  1. 次のコマンドを使用して、Google Cloud プロジェクト ID に設定されている現在の gcloud 構成を確認します。
    gcloud config get project
  2. 必要に応じて、現在の gcloud 構成を設定します。

    gcloud config set project PROJECT_ID
  3. Security Token Service API を有効にします。

    次のコマンドを使用して、Security Token Service API が有効になっていることを確認します。

    gcloud services list --enabled --project PROJECT_ID | grep sts.googleapis.com

    API が有効になっていない場合:

    Console

    Enable the Security Token Service API.

    Enable the API

    コマンドライン

    次のコマンドで API を有効にします。

    gcloud services enable sts.googleapis.com --project PROJECT_ID
  4. Workload Identity のプールとプロバイダを作成します。

    必要なロール

    Workload Identity 連携の構成に必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。

    ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

    必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

    また、IAM オーナー(roles/owner)の基本ロールには ID 連携を構成する権限も含まれています。本番環境では基本ロールを付与すべきではありません。基本ロールは、開発環境またはテスト環境で付与してください。

    Workload Identity のプールとプロバイダを作成する手順は次のとおりです。

    1. AKS クラスタの発行元 URL を確認します。

      AKS

      az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv

      次のように置き換えます。

      • NAME: クラスタの名前。
      • RESOURCE_GROUP: クラスタのリソース グループ。

      このコマンドによって発行元の URL が出力されます。次のいずれかの手順で発行元の URL が必要になります。

      コマンドで発行元の URL が返されない場合は、OIDC 発行者機能が有効になっていることを確認します。

      EKS

      aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
      

      NAME は、クラスタの名前に置き換えます。

      このコマンドによって発行元の URL が出力されます。次のいずれかの手順で発行元の URL が必要になります。

      その他の Kubernetes

      1. Kubernetes クラスタに接続し、kubectl を使用してクラスタの発行元 URL を確認します。
        kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
        

        次のいずれかの手順で発行元の URL が必要になります。

    2. 省略可: OIDC 発行元が一般公開されていない場合は、クラスタの JSON Web Key Set(JWKS)をダウンロードします。
      kubectl get --raw /openid/v1/jwks > cluster-jwks.json
      

      OIDC プロバイダが一般公開されているかどうかを確認するには、CURL コマンドを使用してプロバイダの URL にアクセスし、200 レスポンスを受信する必要があります。

    3. 新しい Workload Identity プールを作成します。
      gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
                  

      次のように置き換えます。

      • POOL_ID: プールの一意の ID。
      • DISPLAY_NAME: (省略可)プールの名前。
      • DESCRIPTION: 選択したプールの説明(省略可)。この説明は、プール ID へのアクセス権を付与するときに表示されます。

      次に例を示します。

      gcloud iam workload-identity-pools create my-wi-pool --display-name="My workload pool" --description="My workload pool description"
    4. クラスタを Workload Identity プール プロバイダとして追加します。OIDC 発行者が一般公開されている一般公開されていないかに応じて、プロバイダを作成するコマンドを選択します。

      一般公開されている

      OIDC 発行者が一般公開されている場合は、次のコマンドを使用してプロバイダを作成します。

      gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="google.subject=assertion.sub"

      一般公開されていない

      OIDC 発行者が一般公開されていない場合は、次のコマンドを使用してプロバイダを作成します。

        gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --jwks-file="cluster-jwks.json" \
        --attribute-mapping="google.subject=assertion.sub"

      以下を置き換えます。

      • WORKLOAD_PROVIDER_ID: 一意の Workload Identity プール プロバイダ ID。
      • POOL_ID: 前に作成した Workload Identity プール ID。
      • ISSUER: 発行元 URI には、前に確認した発行元 URL を使用します。

      attribute-mapping="google.subject=assertion.sub" は、Kubernetes サブジェクトを IAM サブジェクトにマッピングします。

認証情報構成ファイルを作成する

Google Cloud リソースにアクセスできる Kubernetes ワークロードをデプロイするには、まず IAM サービス アカウントごとに認証情報構成ファイルを作成する必要があります。

  1. 次のコマンドを使用して、IAM サービス アカウント「Google サービス アカウント」とも呼ばれます)を一覧表示します。
    gcloud iam service-accounts list --project PROJECT_ID

    次の IAM サービス アカウントの認証情報構成ファイルを作成する必要があります。

    本番

    本番環境の場合:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-cassandra     apigee-cassandra@my_project_id.iam.gserviceaccount.com     False
    apigee-mart          apigee-mart@my_project_id.iam.gserviceaccount.com          False
    apigee-metrics       apigee-metrics@my_project_id.iam.gserviceaccount.com       False
    apigee-runtime       apigee-runtime@my_project_id.iam.gserviceaccount.com       False
    apigee-synchronizer  apigee-synchronizer@my_project_id.iam.gserviceaccount.com  False
    apigee-udca          apigee-udca@my_project_id.iam.gserviceaccount.com          False
    apigee-watcher       apigee-watcher@my_project_id.iam.gserviceaccount.com       False
    

    本番以外の環境

    非本番環境の場合:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-non-prod      apigee-non-prod@my_project_id.iam.gserviceaccount.com      False
    
  2. 前のリストの IAM サービス アカウントごとに認証情報構成ファイルを作成します。Workload Identity 連携を使用するように Apigee ハイブリッドを構成するには、次の認証情報構成ファイルが必要です。

    コード

    gcloud iam workload-identity-pools create-cred-config \
      projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID \
      --service-account=SERVICE_ACCOUNT_EMAIL \
      --credential-source-file=/var/
      --credential-source-type=text \
      --output-file=SERVICE_ACCOUNT_NAME-credential-configuration.json
      

    gcloud iam workload-identity-pools create-cred-config \
      projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider \
      --service-account=apigee-cassandra@myhybridporg.iam.gserviceaccount.com \
      --credential-source-file=/var/
      --credential-source-type=text \
      --output-file=apigee-cassandra-credential-configuration.json
      

    ここで

    • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号。これはプロジェクト ID ではなく、プロジェクト番号にする必要があります。
    • POOL_ID: Workload Identity プールの ID
    • WORKLOAD_PROVIDER_ID: Workload Identity プール プロバイダの ID
    • SERVICE_ACCOUNT_EMAIL: IAM サービス アカウントの権限借用を使用するように Kubernetes ServiceAccount を構成した場合は、サービス アカウントのメールアドレス。

    認証情報の構成ファイルを使用すると、[Cloud クライアント ライブラリ](/apis/docs/cloud-client-libraries)、gcloud CLI、Terraform で次の情報を確認できます。

    • 外部認証情報の取得元
    • 使用する Workload Identity プールとプロバイダ
    • 権限を借用するサービス アカウント

    Workload Identity 連携を使用するように Apigee ハイブリッドを構成する

    1. 各出力ファイル(SERVICE_ACCOUNT_NAME-credential-configuration.json)を次のチャート ディレクトリ(またはそのサブディレクトリ)にコピーまたは移動します。これらのファイルは、認証情報構成ファイルを作成する手順で作成したものです。

      本番

      サービス アカウント Apigee Helm チャートのディレクトリ
      apigee-cassandra apigee-datastore/
      apigee-mart apigee-org/
      apigee-metrics apigee-telemetry/
      apigee-runtime apigee-env/
      apigee-synchronizer apigee-env/
      apigee-udca apigee-org/
      apigee-env/
      apigee-watcher apigee-org/

      非本番環境

      サービス アカウント Apigee Helm チャート
      apigee-non-prod apigee-datastore/
      apigee-telemetry/
      apigee-org/
      apigee-env/
    2. クラスタのオーバーライド ファイルに次のグローバルな変更を加えます。

      コード

      gcp:
        workloadIdentity:
          enabled: false # must be set to false to use Workload Identity Federation
        federatedWorkloadIdentity:
          enabled: true
          audience: "AUDIENCE"
          credentialSourceFile: "/var/run/service-account/token"
      

      gcp:
        workloadIdentity:
          enabled: false
        federatedWorkloadIdentity:
          enabled: true
          audience: "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider"
          credentialSourceFile: "/var/run/service-account/token"
      

      ここで、AUDIENCE は Workload Identity プロバイダの許可されたオーディエンスです。この値は、認証情報構成ファイルで audience: というキーワードを検索すると確認できます。オーディエンスの値は、各認証情報構成ファイルで同じです。

      たとえば、次のサンプル apigee-udca-credential-configuration.json ファイルでは、

      {
        "universe_domain": "googleapis.com",
        "type": "external_account:,"
        "audience": "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider",
        "subject_token_type": "urn:ietf:params:oauth: token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "service
        "impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/apigee-udca@myhybridproject.iam.gserviceaccount.com:generateAccessToken",
        "credential_source": {
          "file": "/var/run/service-account/token",
          "format": {
            "type": "text"
          }
        }
      }

      オーディエンスの値は //iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider です。

    3. Workload Identity 連携を使用して、各コンポーネントのオーバーライドを構成します。インストールに応じて、証明書ファイル、Kubernetes Secret、Vault の手順を選択します。

      証明書ファイル

      serviceAccountPath の値は、対応する IAM サービス アカウントの認証情報のソースファイルに置き換えます。これは、チャート ディレクトリからの相対パスにする必要があります。例:

      envs:
      - name: ENVIRONMENT_NAME
        serviceAccountPaths:
          synchronizer: apigee-synchronizer-credential-configuration.json
          runtime: apigee-runtime-credential-configuration.json
          udca: udca-credential-configuration.json
      
      mart:
        serviceAccountPath: mart-credential-configuration.json
      
      connectAgent:
        serviceAccountPath: mart-credential-configuration.json
      
      metrics:
        serviceAccountPath: metrics-credential-configuration.json
      
      udca:
        serviceAccountPath: UDCA_SERVICE_ACCOUNT_FILEPATH
      
      watcher:
        serviceAccountPath: WATCHER_SERVICE_ACCOUNT_FILEPATH
      

      K8s Secret

      1. 認証情報構成ファイルごとに認証情報ソースファイルを使用して、新しい Kubernetes Secret を作成します。
        kubectl create secret -n APIGEE_NAMESPACE generic SECRET_NAME --from-file="client_secret.json=CREDENTIAL_CONFIGURATION_FILE"

        次に例を示します。

        kubectl create secret -n apigee generic udca-workoad-identity-secret --from-file="client_secret.json=./apigee-udca-credential-configuration.json"
      2. serviceAccountRef の値を新しい Secret に置き換えます。次に例を示します。
        udca:
          serviceAccountRef: udca-workoad-identity-secret
        

      Vault

      Vault 内の各サービス アカウントのサービス アカウント キー SAKEY を、対応する認証情報ソースファイルで更新します。手順はすべてのコンポーネントで同様です。たとえば、UDCA の場合:

      SAKEY=$(cat .apigee-udca-credential-configuration.json); kubectl -n APIGEE_NAMESPACE exec vault-0 -- vault kv patch secret/apigee/orgsakeys udca="$SAKEY"

      詳細については、Storing service account keys in Hashicorp Vault をご覧ください。

    4. helm upgrade コマンドを使用して、影響を受ける各コンポーネントに変更を適用します。

      Vault サービス アカウント キーを更新した場合は、apigee-operator チャートも更新します。

      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      影響を受ける残りのチャートを次の順序で更新します。

      helm upgrade datastore apigee-datastore/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade telemetry apigee-telemetry/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade $ORG_NAME apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      環境ごとに apigee-env チャートを更新し、毎回 $ENV_RELEASE_NAMEENV_NAME を置き換えます。

      helm upgrade $ENV_RELEASE_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        --set env=$ENV_NAME \
        -f overrides.yaml
      

      コンポーネントと対応するチャートのリストについては、Apigee ハイブリッド Helm リファレンスをご覧ください。

    Kubernetes サービス アカウントへのアクセス権を付与する

    1. 次のコマンドを使用して、Kubernetes サービス アカウントを一覧表示します。
      kubectl get sa -n APIGEE_NAMESPACE
    2. 次の表に示すように、Kubernetes サービス アカウントに、関連付けられた IAM サービス アカウントの権限借用を許可します。次の表に、デフォルトの Apigee IAM サービス アカウント名を示します。カスタム サービス アカウント名を使用している場合は、対応する IAM サービス アカウントを使用します。
      Kubernetes サービス アカウント IAM サービス アカウント
      組織レベルの Kubernetes サービス アカウント
      apigee-connect-agent-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-mart-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-metrics-apigee-telemetry apigee-metrics
      apigee-open-telemetry-collector-apigee-telemetry apigee-metrics
      apigee-udca-ORG_NAME-ORG_HASH_ID apigee-udca
      apigee-watcher-ORG_NAME-ORG_HASH_ID apigee-watcher
      環境レベルの Kubernetes サービス アカウント
      apigee-runtime-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-runtime
      apigee-synchronizer-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-synchronizer
      Cassandra のバックアップと復元(有効な場合)
      apigee-cassandra-backup-sa apigee-cassandra
      apigee-cassandra-restore-sa apigee-cassandra

      ここで

      • ORG_NAME: 組織の名前の最初の 15 文字。
      • ORG_HASH_ID: 組織名全体の一意のハッシュ ID。
      • ENV_NAME: 環境の名前の最初の 15 文字。
      • ENV_HASH_ID: 組織名と環境名の一意のハッシュ ID。

      次に例を示します。

      • apigee-connect-agent-myhybridorg-123abcd
      • apigee-runtime-myhybridorg-prodenv-234bcde

      次のコマンドを使用して、各 Kubernetes サービス アカウントに適切な IAM サービス アカウントの権限借用を許可します。

      gcloud iam service-accounts add-iam-policy-binding \
        IAM_SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \
          --role=roles/iam.workloadIdentityUser

      ここで

      • IAM_SA_NAME: サービス アカウントの名前。
      • PROJECT_ID: Apigee 組織に関連付けられているプロジェクトの ID。
      • PROJECT_NUMBER: Workload Identity プールを作成したプロジェクトのプロジェクト番号
      • POOL_ID: Workload Identity プール ID。
      • MAPPED_SUBJECT: google.subject にマッピングした ID トークンのクレームから取得した Kubernetes ServiceAccount。たとえば、google.subject=assertions.sub をマッピングし、ID トークンに "sub": "system:serviceaccount:default:my-kubernetes-serviceaccount" が含まれている場合、MAPPED_SUBJECTsystem:serviceaccount:default:my-kubernetes-serviceaccount です。

    Workload Identity 連携とベスト プラクティスの詳細については、Workload Identity 連携の使用に関するベスト プラクティスをご覧ください。