GKE ワークロードから Google Cloud APIs に対する認証を行う


このドキュメントでは、GKE 用 Workload Identity 連携を使用して、Google Kubernetes Engine(GKE)クラスタで実行されているワークロードから Google Cloud APIs に安全にアクセスする方法について説明します。詳細については、GKE 用 Workload Identity 連携についてをご覧ください。

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API を有効にします。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得します。

クラスタとノードプールで GKE 用 Workload Identity 連携を有効にする

Autopilot では、GKE 用 Workload Identity 連携がデフォルトで有効になっています。GKE 用 Workload Identity 連携を使用するようアプリケーションを構成するセクションに進みます。

Standard では、Google Cloud CLI または Google Cloud コンソールを使用して、クラスタとノードプールで GKE 用 Workload Identity 連携を有効にします。ノードプールで GKE 用 Workload Identity 連携を有効にするには、クラスタレベルで GKE 用 Workload Identity 連携を有効にする必要があります

新しいクラスタを作成する

新しい Standard クラスタで GKE 用 Workload Identity 連携を有効にするには、gcloud CLI または Google Cloud コンソールを使用します。

gcloud

  1. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  2. 新しいクラスタで GKE 用 Workload Identity 連携を有効にするには、次のコマンドを実行します。

    gcloud container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --workload-pool=PROJECT_ID.svc.id.goog
    

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

コンソール

新しいクラスタで GKE 用 Workload Identity 連携を有効にするには、次の操作を行います。

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. [クラスタを作成] ダイアログで、GKE Standard の [構成] をクリックします。

  4. ナビゲーション メニューの [クラスタ] セクションで、[セキュリティ] をクリックします。

  5. [Workload Identity を有効にする] チェックボックスをオンにします。

  6. クラスタの構成を続行し、[作成] をクリックします。

既存のクラスタを更新する

既存の Standard クラスタで GKE 用 Workload Identity 連携を有効にするには、gcloud CLI または Google Cloud コンソールを使用します。既存のノードプールは影響を受けませんが、クラスタ内の新しいノードプールでは GKE 用 Workload Identity 連携が使用されます。

gcloud

  1. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  2. 既存のクラスタで GKE 用 Workload Identity 連携を有効にするには、次のコマンドを実行します。

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --workload-pool=PROJECT_ID.svc.id.goog
    

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

コンソール

既存のクラスタで GKE 用 Workload Identity 連携を有効にするには、次の操作を行います。

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. クラスタの詳細ページの [セキュリティ] セクションで、 [Workload Identity の編集] をクリックします。

  4. [Workload Identity の編集] ダイアログで、[Workload Identity を有効にする] チェックボックスをオンにします。

  5. [保存] をクリックします。

既存のワークロードを GKE 用 Workload Identity 連携に移行する

既存のクラスタで GKE 用 Workload Identity 連携を有効にした後、GKE 用 Workload Identity 連携を使用するように実行中のワークロードを移行することをおすすめします。ご使用の環境に適した移行方法を選択します。GKE 用 Workload Identity 連携を有効にして新しいノードプールを作成することも、既存のノードプールを更新して GKE 用 Workload Identity 連携を有効にすることもできます。

GKE 用 Workload Identity 連携に対応するためにアプリケーションの変更も必要な場合は、新しいノードプールを作成することをおすすめします。

クラスタで GKE 用 Workload Identity 連携が有効になっている場合、新しいノードプールを作成すると、そのプールではデフォルトで GKE 用 Workload Identity 連携が使用されます。GKE 用 Workload Identity 連携を有効にした新しいノードプールを作成するには、次のコマンドを実行します。

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --workload-metadata=GKE_METADATA

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

  • NODEPOOL_NAME: 新しいノードプールの名前。
  • CLUSTER_NAME: GKE 用 Workload Identity 連携が有効になっている既存のクラスタの名前。

--workload-metadata=GKE_METADATA フラグにより、GKE メタデータ サーバーを使用するようにノードプールが構成されます。GKE 用 Workload Identity 連携がクラスタで有効になっていない場合にノードプールの作成が失敗するように、このフラグを含めることをおすすめします。

既存のノードプールを更新する

クラスタで GKE 用 Workload Identity 連携を有効にした後、既存のノードプールで GKE の Workload Identity 連携を手動で有効にできます。

gcloud

  1. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  2. GKE 用 Workload Identity 連携を使用するように既存のノードプールを変更するには、次のコマンドを実行します。

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --region=COMPUTE_REGION \
        --workload-metadata=GKE_METADATA
    

    クラスタで GKE 用 Workload Identity 連携が有効になっている場合、--workload-metadata=GCE_METADATA を明示的に指定することで、この機能を特定のノードプールで選択的に無効にできます。詳しくは、クラスタ メタデータの保護をご覧ください。

コンソール

GKE 用 Workload Identity 連携を使用するように既存のノードプールを変更するには、次の操作を行います。

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. [ノード] タブをクリックします。

  4. [ノードプール] セクションで、変更するノードプールの名前をクリックします。

  5. [ノードプールの詳細] ページで、[ 編集] をクリックします。

  6. [ノードプールの編集] ページの [セキュリティ] セクションで、[GKE メタデータ サーバーを有効にする] チェックボックスをオンにします。

  7. [保存] をクリックします。

GKE 用 Workload Identity 連携を使用するようにアプリケーションを構成する

GKE アプリケーションが GKE 用 Workload Identity 連携を使用して Google Cloud APIs に対して認証できるようにするには、特定の API の IAM ポリシーを作成します。これらのポリシーのプリンシパルは、ワークロード、名前空間、または ServiceAccount に対応する IAM プリンシパル識別子です。

認可とプリンシパルを構成する

  1. クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    

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

    • CLUSTER_NAME: GKE 用 Workload Identity 連携が有効になっているクラスタの名前。
    • LOCATION: クラスタのロケーション。
  2. Kubernetes サービス アカウントに使用する Namespace を作成します。default Namespace を使用することも、既存の Namespace を使用することもできます。

    kubectl create namespace NAMESPACE
    
  3. アプリケーションで使用する Kubernetes ServiceAccount を作成します。任意の Namespace で既存の Kubernetes ServiceAccount を使用することもできます。ワークロードに ServiceAccount を割り当てなかった場合、Kubernetes は Namespace に default ServiceAccount を割り当てます。

    kubectl create serviceaccount KSA_NAME \
        --namespace NAMESPACE
    

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

    • KSA_NAME: 新しい Kubernetes ServiceAccount の名前。
    • NAMESPACE: ServiceAccount の Kubernetes Namespace の名前。
  4. Kubernetes ServiceAccount を参照する IAM 許可ポリシーを作成します。アプリケーションがアクセスする必要がある特定の Google Cloud リソースに、権限を付与することをおすすめします。プロジェクトで許可ポリシーを作成するには、関連する IAM 権限が必要です。

    たとえば、次のコマンドは、作成した ServiceAccount に Kubernetes Engine Cluster 閲覧者roles/container.clusterViewer)のロールを付与します。

    gcloud projects add-iam-policy-binding projects/PROJECT_ID \
        --role=roles/container.clusterViewer \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
        --condition=None
    

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

    • PROJECT_ID: Google Cloud プロジェクト ID。
    • PROJECT_NUMBER: 数値による Google Cloud プロジェクト番号。

    IAM 許可ポリシーをサポートする任意の Google Cloud リソースにロールを付与できます。プリンシパル ID の構文は、Kubernetes リソースによって異なります。サポートされている ID のリストについては、GKE 用 Workload Identity 連携のプリンシパル ID をご覧ください。

GKE 用 Workload Identity 連携の設定を確認する

このセクションでは、Cloud Storage バケットを作成し、前のセクションで作成した Kubernetes ServiceAccount にバケットの閲覧権限を付与します。次に、ワークロードをデプロイし、コンテナがプロジェクト内のクラスタを一覧表示できるかどうかをテストします。

  1. 空の Cloud Storage バケットを作成します。

    gcloud storage buckets create gs://BUCKET
    

    BUCKET は、新しいバケットの名前に置き換えます。

  2. 作成した ServiceAccount に Storage オブジェクト閲覧者roles/storage.objectViewer)のロールを付与します。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET \
        --role=roles/storage.objectViewer \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
        --condition=None
    

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

    • PROJECT_ID: Google Cloud プロジェクト ID。
    • PROJECT_NUMBER: 数値による Google Cloud プロジェクト番号。
    • NAMESPACE: ServiceAccount を含む Kubernetes Namespace。
    • KSA_NAME: ServiceAccount の名前。
  3. 次のマニフェストを test-app.yaml として保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      containers:
      - name: test-pod
        image: google/cloud-sdk:slim
        command: ["sleep","infinity"]
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
            ephemeral-storage: 10Mi
    
  4. Standard クラスタの場合のみtemplate.spec フィールドに以下を追加して、GKE 用 Workload Identity 連携を使用するノードプールに Pod を配置します。

    すべてのノードが GKE 用 Workload Identity 連携を使用するので、Autopilot クラスタではこの手順をスキップします。Autopilot クラスタではこの nodeSelector が拒否されます。

    spec:
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true"
    
  5. クラスタに構成ファイルを適用します。

    kubectl apply -f test-app.yaml
    
  6. Pod の準備ができるまで待ちます。Pod のステータスを確認するには、次のコマンドを実行します。

    kubectl get pods --namespace=NAMESPACE
    

    Pod の準備が整うと、出力は次のようになります。

    NAME       READY   STATUS    RESTARTS   AGE
    test-pod   1/1     Running   0          5m27s
    
  7. Pod でシェル セッションを開きます。

    kubectl exec -it pods/test-pod --namespace=NAMESPACE -- /bin/bash
    
  8. バケット内のオブジェクトのリストを取得します。

    curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        "https://storage.googleapis.com/storage/v1/b/BUCKET/o"
    

    次のような出力が表示されます。

    {
      "kind": "storage#objects"
    }
    

    この出力は、Pod がバケット内のオブジェクトにアクセスできることを示しています。

代替方法: Kubernetes ServiceAccount を IAM にリンクする

IAM プリンシパル ID を使用して、GKE 用 Workload Identity 連携を構成することをおすすめします。ただし、この連携 ID には、サポートされている Google Cloud API ごとに固有の制限があります。制限の一覧については、サポートされているプロダクトと制限事項をご覧ください。

これらの制限が適用される場合は、次の手順で GKE ワークロードからこれらの API へのアクセスを構成します。

  1. Kubernetes Namespace を作成します。

    kubectl create namespace NAMESPACE
    
  2. Kubernetes ServiceAccount を作成します。

    kubectl create serviceaccount KSA_NAME \
        --namespace=NAMESPACE
    
  3. IAM サービス アカウントを作成します。組織内の任意のプロジェクトで既存の IAM サービス アカウントを使用することもできます。

    gcloud iam service-accounts create IAM_SA_NAME \
        --project=IAM_SA_PROJECT_ID
    

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

    • IAM_SA_NAME: 新しい IAM サービス アカウントの名前。
    • IAM_SA_PROJECT_ID: IAM サービス アカウントのプロジェクト ID。

    IAM サービス アカウントから Google Cloud APIs へのアクセスを承認する方法については、サービス アカウントについてをご覧ください。

  4. IAM サービス アカウントに、特定の Google Cloud APIs で必要なロールを付与します。

    gcloud projects add-iam-policy-binding IAM_SA_PROJECT_ID \
        --member "serviceAccount:IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com" \
        --role "ROLE_NAME"
    

    ROLE_NAME は、ロールの名前(roles/spanner.viewer など)に置き換えます。

  5. Kubernetes ServiceAccount に IAM サービス アカウントの権限の借用を許可する IAM ポリシーを作成します。

    gcloud iam service-accounts add-iam-policy-binding IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
    
  6. GKE がサービス アカウント間のリンクを認識できるように、Kubernetes ServiceAccount にアノテーションを付けます。

    kubectl annotate serviceaccount KSA_NAME \
        --namespace NAMESPACE \
        iam.gke.io/gcp-service-account=IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com
    

コードから GKE 用 Workload Identity 連携を使用する

コードで Google Cloud サービスに対する認証を行うプロセスは、Compute Engine のメタデータ サーバーを使用した認証と同じです。GKE 用 Workload Identity 連携を使用すると、インスタンス メタデータ サーバーへのリクエストが GKE メタデータ サーバーに転送されます。インスタンス メタデータ サーバーを使用して認証する既存のコードは(Google Cloud クライアント ライブラリを使用したコードと同様)、変更せずにそのまま使用できます。

GKE 用 Workload Identity 連携で別のプロジェクトの割り当てを使用する

GKE バージョン 1.24 以降を実行しているクラスタでは、IAM Service Account Credentials APIGenerateAccessToken メソッドと GenerateIdToken メソッドの呼び出し時に、別の Google Cloud プロジェクトの割り当てを使用するように、Kubernetes サービス アカウントを必要に応じて構成できます。これにより、メイン プロジェクトで割り当てのすべてを使用することを避け、クラスタ内のこれらのサービスに他のプロジェクトの割り当てを使用できます。

GKE 用 Workload Identity 連携を使用して割り当てプロジェクトを構成するには、次の操作を行います。

  1. 割り当てプロジェクトの serviceusage.services.use 権限を Kubernetes サービス アカウントに付与します。

    gcloud projects add-iam-policy-binding QUOTA_PROJECT_ID \
        --role=roles/serviceusage.serviceUsageConsumer \
        --member='principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/serviceaccount/NAMESPACE/KSA_NAME' \
    

    QUOTA_PROJECT_ID は、割り当てプロジェクトのプロジェクト ID に置き換えます。

  2. 割り当てプロジェクトを使用して Kubernetes サービス アカウントにアノテーションを付けます。

    kubectl annotate serviceaccount KSA_NAME \
        --namespace NAMESPACE \
        iam.gke.io/credential-quota-project=QUOTA_PROJECT_ID
    

構成が正しく機能することを確認するには、次の操作を行います。

  1. Pod を作成し、シェル セッションを開始します。実行中のコンテナにシェルを用意する方法については、Kubernetes のドキュメントをご覧ください。

  2. メタデータ サーバーにリクエストを行います。

    curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
    
  3. Google Cloud コンソールで、割り当てプロジェクトの IAM Service Accounts Credentials API ページに移動します。

    [API] に移動

  4. トラフィックの変化を確認します。

クリーンアップ

GKE 用 Workload Identity 連携の使用を停止するには、IAM サービス アカウントへのアクセス権を取り消して、クラスタで GKE 用 Workload Identity 連携を無効にします。

アクセス権の取り消し

プリンシパルへのアクセス権を取り消すには、GKE 用 Workload Identity 連携を使用するようにアプリケーションを構成するで作成した IAM 許可ポリシーを削除します。

たとえば、Artifact Registry リポジトリへのアクセス権を取り消すには、次のコマンドを実行します。

gcloud artifacts repositories remove-iam-policy-binding REPOSITORY_NAME \
    --location=REPOSITORY_LOCATION \
    --member='principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/serviceaccount/NAMESPACE/KSA_NAME' \
    --role='roles/artifactregistry.reader' \
    --all

GKE 用 Workload Identity 連携を無効にする

GKE 用 Workload Identity 連携は、GKE Standard クラスタでのみ無効にできます。

gcloud

  1. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  2. 各ノードプールで GKE 用 Workload Identity 連携を無効にします。

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --workload-metadata=GCE_METADATA
    

    クラスタ内の各ノードプールに対してこのコマンドを繰り返します。

  3. クラスタで GKE 用 Workload Identity 連携を無効にします。

    gcloud container clusters update CLUSTER_NAME \
        --disable-workload-identity
    

コンソール

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. [ノード] タブをクリックします。

  4. 各ノードプールで GKE 用 Workload Identity 連携を無効にするには、[ノードプール] セクションで、ノードプールごとに次の操作を行います。

    1. 変更するノードプールの名前をクリックします。
    2. [ノードプールの詳細] ページで、[ 編集] をクリックします。
    3. [ノードプールの編集] ページの [セキュリティ] セクションで、[GKE メタデータ サーバーを有効にする] チェックボックスをオフにします。
    4. [保存] をクリックします。
  5. クラスタで GKE 用 Workload Identity 連携を無効にするには、次の操作を行います。

    1. [詳細] タブをクリックします。
    2. [セキュリティ] セクションで、[Workload Identity] の横にある [ 編集] をクリックします。
    3. [Workload Identity の編集] ダイアログで、[Workload Identity を有効にする] チェックボックスをオフにします。
    4. [保存] をクリックします。

組織で GKE 用 Workload Identity 連携を無効にする

セキュリティの面から見ると、GKE 用 Workload Identity 連携により、GKE は Google Cloud リソースの認証と認可が可能な Kubernetes サービス アカウント ID であることを表明しています。サービス アカウントの作成の無効化サービス アカウント キーの作成の無効化など、ワークロードを Google Cloud リソースから分離するための措置を講じた場合、組織の GKE 用 Workload Identity 連携の無効化が必要になる場合もあります。

組織の GKE 用 Workload Identity 連携を無効にする手順をご覧ください。

トラブルシューティング

トラブルシューティング情報については、GKE 用 Workload Identity 連携のトラブルシューティングをご覧ください。

次のステップ