GKE 用 Workload Identity 連携

GKE 用 Workload Identity 連携は、Google Kubernetes Engine(GKE)で実行されているワークロードが安全かつ管理しやすい方法で Google Cloud サービスにアクセスできるようにするために推奨される方法です。

GKE で GKE 用 Workload Identity 連携を有効にして使用する方法については、GKE 用 Workload Identity 連携を使用するをご覧ください。

フリート Workload Identity を使用すると、GKE Enterprise クラスタを含むフリートに登録されているクラスタに Workload Identity 連携のサポートを提供できます。

用語

このドキュメントでは、Kubernetes サービス アカウントIdentity and Access Management(IAM)サービス アカウントを区別しています。

Kubernetes サービス アカウント
GKE Pod で実行されるプロセスの ID を提供する Kubernetes リソース。
IAM サービス アカウント
アプリケーションが Google Cloud APIs に承認済みの呼び出しを実行できるようにする Google Cloud リソース。

GKE 用 Workload Identity 連携とは

GKE で実行されるアプリケーションで、Compute Engine API、BigQuery Storage API、ML API などの Google Cloud APIs へのアクセスが必要になる場合があります。

GKE 用 Workload Identity 連携を使用すると、GKE クラスタ内の Kubernetes サービス アカウントが IAM サービス アカウントとして機能します。構成された Kubernetes サービス アカウントを使用する Pod は、Google Cloud APIs にアクセスするときに IAM サービス アカウントとして自動的に認証されます。GKE 用 Workload Identity 連携を使用すると、クラスタ内のアプリケーションごとに詳細に設定した個別の ID と認可を割り当てることができます。

GKE 用 Workload Identity 連携はメタデータ隠蔽機能に代わるものです。メタデータ隠蔽機能で保護された機密メタデータは、GKE 用 Workload Identity 連携でも保護されます。

GKE 用 Workload Identity 連携の仕組み

クラスタで GKE 用 Workload Identity 連携を有効にし、IAM サービス アカウントの権限を借用するように Kubernetes ServiceAccount を構成すると、GKE は次の処理を行います。

  • クラスタの Google Cloud プロジェクトに対して固定の Workload Identity プールを次の形式で作成します。

    PROJECT_ID.svc.id.goog
    

    Workload Identity プールは、IAM が Kubernetes ServiceAccount 認証情報を理解し、信頼できるようにする命名規則を指定します。

  • GKE クラスタを Workload Identity プールの ID プロバイダとして登録します。

  • GKE メタデータ サーバーをデプロイします。このサーバーは、すべてのノードでワークロードからの認証情報リクエストをインターセプトします。

  • IAM が認識できる Kubernetes ServiceAccounts の ID を作成します。この ID の形式は次のとおりです。

    serviceAccount:PROJECT_ID.svc.id.goog[KUBERNETES_NAMESPACE/KUBERNETES_SERVICE_ACCOUNT]
    

    この ID には次のパラメータがあります。

    • PROJECT_ID: Google Cloud プロジェクト ID。
    • KUBERNETES_NAMESPACE: Kubernetes ServiceAccount の Namespace。
    • KUBERNETES_SERVICE_ACCOUNT: Kubernetes ServiceAccount の名前。

GKE 用 Workload Identity 連携を使用するようにワークロードを構成する

GKE 用 Workload Identity 連携を構成するには、次の操作を行います。

  1. IAM サービス アカウントを作成し、特定の Google Cloud APIs へのアクセス権を付与します。
  2. IAM ポリシーを使用して、IAM サービス アカウントを Kubernetes ServiceAccount にバインドします。
  3. Kubernetes ServiceAccount オブジェクトに、バインドされた IAM サービス アカウントの名前のアノテーションを付けます。
  4. Google Cloud APIs にアクセスする必要があるワークロードに Kubernetes ServiceAccount を割り当てます。

認証情報フロー

Google Cloud クライアント ライブラリを使用する場合など、ワークロードが Google Cloud API にアクセスするためのリクエストを送信すると、次の認証処理が行われます。

  1. アプリケーションのデフォルト認証情報(ADC)が、VM 上で実行される Compute Engine メタデータ サーバーに Google Cloud アクセス トークンをリクエストします。
  2. GKE メタデータ サーバーはトークン リクエストをインターセプトし、Kubernetes API サーバーにリクエスト元のワークロードを識別する Kubernetes ServiceAccount トークンを要求します。この認証情報は、クラスタ認証局(CA)によって署名された JSON Web Token(JWT)です。
  3. GKE メタデータ サーバーが、Security Token Service を使用して、Kubernetes ワークロードの ID を参照する有効期間の短い Google Cloud 連携アクセス トークンと JWT を交換します。
  4. リクエスト元のワークロード ServiceAccount に、特定の IAM サービス アカウントの権限借用がアノテーションされている場合、GKE メタデータ サーバーは対象のサービス アカウントの IAM アクセス トークンをリクエストします。
  5. GKE メタデータ サーバーが、IAM サービス アカウントのアクセス トークンをワークロードに提供します。

ワークロードは、権限借用した IAM サービス アカウントに認可されている Google Cloud APIs にアクセスできます。

ID の同一性

IAM が GKE 用 Workload Identity 連携で Kubernetes サービス アカウントを確認するために使用するメンバー名では、次の変数を使用します。

  • Kubernetes サービス アカウント名。
  • Kubernetes サービス アカウントの名前空間。
  • Google Cloud プロジェクト ID。

プロジェクトに Kubernetes サービス アカウントの名前と名前空間を持つクラスタが複数ある場合、すべてのアカウントは同じメンバー名に解決されます。この共通 ID を使用すると、個々のクラスタではなく、Workload Identity プールに Google Cloud リソースへのアクセス権を付与できます。

たとえば、次の図について考えてみましょう。クラスタ A、B、C は同じ Google Cloud プロジェクトに属しているため、同じ Workload Identity プールに属しています。クラスタ A とクラスタ B の両方の backend 名前空間内のアプリケーションは、Google Cloud リソースへのアクセス時に back IAM サービス アカウントとして認証できます。IAM では、呼び出しを行うクラスタを区別しません。

Workload Identity プール内の ID の同一性を示す図
GKE 用 Workload Identity 連携で Google Cloud APIs にアクセスする ID の同一性

また、この ID の同一性は、特定の Workload Identity プール内のすべてのクラスタを信頼できるようにする必要があることを意味します。たとえば、上記の例のクラスタ C が信頼できないチームによって所有されていた場合、クラスタ A とクラスタ B と同様に、backend 名前空間を作成し、back IAM サービス アカウントを使用して Google Cloud APIs にアクセスできます。

信頼できないアクセスを回避するには、クラスタを別々のプロジェクトに配置し、別々の Workload Identity プールを取得できるようにします。また、共通のメンバー名を回避するため、名前空間名が互いに異なるようにする必要があります。

GKE メタデータ サーバーについて

GKE 用 Workload Identity 連携が有効になっている GKE のすべてのノードは、メタデータを GKE メタデータ サーバーに保存します。GKE メタデータ サーバーは、Kubernetes ワークロードに必要な Compute Engine メタデータ サーバー エンドポイントのサブセットです。

GKE メタデータ サーバーは DaemonSet として実行されます。それぞれの Linux ノードで 1 つの Pod が使用されるか、クラスタ内の各 Windows ノードにネイティブ Windows サービスが実行されます。メタデータ サーバーは、http://metadata.google.internal169.254.169.254:80)への HTTP リクエストをインターセプトします。たとえば、GET /computeMetadata/v1/instance/service-accounts/default/token リクエストは、権限借用に Pod が構成されている IAM サービス アカウントのトークンを取得します。GKE メタデータ サーバーへのトラフィックは、Pod をホストする VM インスタンスから外に送信されません。

次の表に、GKE メタデータ サーバーで使用できる Compute Engine メタデータ サーバー エンドポイントのサブセットを示します。Compute Engine メタデータ サーバーで使用できるエンドポイントの一覧については、デフォルトの VM メタデータ値をご覧ください。

インスタンス メタデータ

インスタンス メタデータは、次のディレクトリに保存されます。

http://metadata.google.internal/computeMetadata/v1/instance/

エントリ 説明
hostname

ノードのホスト名。

id

ノードの一意の ID。

service-accounts/

ノードに関連付けられているサービス アカウントのディレクトリ。各サービス アカウントごとに、次の情報を利用できます。

  • aliases
  • email: サービス アカウントのメールアドレス。
  • identity: ノードに固有の JSON ウェブトークン(JWT)。リクエストには audience パラメータを含める必要があります。例: ?audience=http://www.example.com
  • scopes: サービス アカウントに割り当てられているアクセス スコープ。
  • token: ワークロードを認証するための OAuth 2.0 アクセス トークン。
zone

GKE ノードの Compute Engine ゾーン。

インスタンス属性

インスタンス属性は、次のディレクトリに保存されます。

http://metadata.google.internal/computeMetadata/v1/instance/attributes/

エントリ 説明
cluster-location

クラスタの Compute Engine ゾーンまたはリージョン。

cluster-name

GKE クラスタの名前。

cluster-uid

GKE クラスタの UID。

プロジェクトのメタデータ

クラスタ プロジェクトのメタデータは、次のディレクトリに保存されます。

http://metadata.google.internal/computeMetadata/v1/project/

エントリ 説明
project-id

Google Cloud プロジェクト ID。

numeric-project-id

Google Cloud プロジェクト番号。

GKE 用 Workload Identity 連携の制限事項

  • GKE が Google Cloud プロジェクト用に作成する Workload Identity プールの名前は変更できません。

  • GKE がノードプールで GKE メタデータ サーバーを有効にすると、Pod は Compute Engine メタデータ サーバーにアクセスできなくなります。GKE メタデータ サーバーは、ホスト ネットワークで実行されている Pod を除き、これらの Pod からメタデータ エンドポイントへのリクエストをインターセプトします。

  • GKE メタデータ サーバーが新しく作成された Pod でのリクエストの承認を開始するまでに数秒かかります。したがって、Pod の有効期間の最初の数秒以内に GKE 用 Workload Identity 連携を使用して認証を試みると、失敗する可能性があります。この問題は、呼び出しを再試行することで解決します。詳しくは、トラブルシューティングをご覧ください。

  • GKE の組み込みの Logging エージェントと Monitoring エージェントは、引き続きノードのサービス アカウントを使用します。

  • GKE 用 Workload Identity 連携を有効にしても Cloud Run for Anthos がリクエスト指標のリリースを継続するには手動による設定が必要になります。

  • GKE 用 Workload Identity 連携では、メモリの問題を回避するため、ノードごとに GKE メタデータ サーバーへの接続数の上限を 500 に設定しています。ノードがこの上限を超えると、タイムアウトが発生することがあります。

  • Windows Server ノードの GKE 用 Workload Identity 連携は、GKE バージョン 1.18.16-gke.1200、1.19.8-gke.1300、1.20.4-gke.1500 以降で使用できます。

  • GKE メタデータ サーバーは、クラスタ内の Kubernetes サービス アカウントの合計数に比例してメモリリソースを使用します。クラスタに 3,000 を超える Kubernetes サービス アカウントがある場合、kubelet はメタデータ サーバー Pod を終了することがあります。軽減策については、トラブルシューティングをご覧ください。

GKE 用 Workload Identity 連携に代わる方法

GKE から Google Cloud APIs にアクセスする場合、GKE 用 Workload Identity 連携の代わりに、次のいずれかの方法を使用できます。これらの方法では、セキュリティに関して一定の妥協が必要になるため、GKE 用 Workload Identity 連携を使用することをおすすめします。

  • ノードの Compute Engine のデフォルトのサービス アカウントを使用します。プロジェクト内の任意の IAM サービス アカウントとしてノードプールを実行できます。ノードプールの作成時にサービス アカウントを指定しなければ、GKE はプロジェクトに Compute Engine のデフォルトのサービス アカウントを使用します。デフォルトの Compute Engine サービス アカウントは、そのノードにデプロイされているすべてのワークロードで共有されます。その結果、権限が過剰にプロビジョニングされる可能性があります。これは、最小権限の原則に反し、マルチテナント クラスタでは不適切です。

  • サービス アカウント キーをエクスポートして Kubernetes Secret として保存します。

次のステップ