GKE 用 Workload Identity 連携は、Google Kubernetes Engine(GKE)で実行されているワークロードが安全かつ管理しやすい方法で Google Cloud サービスにアクセスできるようにするために推奨される方法です。
GKE 用 Workload Identity 連携は、Google Cloud 内外の環境で実行されるワークロードに ID を提供する、IAM Workload Identity 連携を介して利用できます。IAM Workload Identity 連携を使用すると、AWS、Azure、セルフマネージド Kubernetes などで実行されているワークロードから、サポートされている Google Cloud API を安全に認証できます。GKE では、Google Cloud が Workload Identity プールとプロバイダを管理するため、外部 ID プロバイダは必要ありません。
- 他の環境の Workload Identity 連携については、Workload Identity 連携をご覧ください。
- GKE 用 Workload Identity 連携を有効にして使用するには、GKE ワークロードから Google Cloud API にアクセスするをご覧ください。
- フリート内のクラスタに Workload Identity 連携のサポートを提供するには、フリート Workload Identity を使用します。
用語
このページでは、Kubernetes サービス アカウントと Identity and Access Management(IAM)サービス アカウントを区別しています。
- Kubernetes サービス アカウント
- GKE Pod で実行されるプロセスの ID を提供する Kubernetes リソース。
- IAM サービス アカウント
- アプリケーションが Google Cloud API への承認された呼び出しを実行できるようにする Google Cloud リソース。
GKE 用 Workload Identity 連携とは
GKE で実行されるアプリケーションで、Compute Engine API、BigQuery Storage API、ML API などの Google Cloud API へのアクセスが必要になる場合があります。
GKE 用 Workload Identity 連携では、IAM ポリシーを使用して、GKE クラスタ内の Kubernetes ワークロードに特定の Google Cloud API へのアクセス権を付与できます。手動構成や、サービス アカウント キー ファイルのような安全性の低い方法は必要ありません。GKE 用 Workload Identity 連携を使用すると、クラスタ内のアプリケーションごとに詳細に設定した個別の ID と認可を割り当てることができます。
GKE 用 Workload Identity 連携はメタデータ隠蔽機能に代わるものです。メタデータ隠蔽機能によって保護される機密メタデータは、GKE 用 Workload Identity 連携によっても保護されます。
GKE 用 Workload Identity 連携の仕組み
クラスタで GKE 用 Workload Identity 連携を有効にすると、GKE は次の処理を行います。
クラスタの Google Cloud プロジェクトに対して固定の Workload Identity プールを次の形式で作成します。
PROJECT_ID.svc.id.goog
Workload Identity プールは、IAM が Kubernetes 認証情報を理解し、信頼できるようにする命名規則を指定します。プロジェクト内のすべてのクラスタを削除しても、この Workload Identity プールは削除されません。
GKE クラスタを Workload Identity プールの ID プロバイダとして登録します。
GKE メタデータ サーバーをデプロイします。このサーバーは、すべてのノードでワークロードからの認証情報リクエストをインターセプトします。
Google Cloud リソースに IAM 許可ポリシーを作成する
GKE 用 Workload Identity 連携を使用してアクセス権を付与するには、アプリケーションの ID に対応するプリンシパルに特定の Google Cloud リソースに対するアクセス権を付与する IAM 許可ポリシーを作成します。たとえば、database-reader
Kubernetes ServiceAccount を使用するすべての Pod に、Cloud Storage バケットの読み取り権限を付与できます。
許可ポリシーをサポートするリソースの一覧については、許可ポリシーを受け入れるリソースタイプをご覧ください。
IAM ポリシーで条件を使用する
また、許可ポリシーで条件を設定することで、アクセスの範囲を制限することもできます。条件は、許可ポリシーを適用するタイミングを指定する拡張可能な方法です。たとえば、条件を使用して特定の Google Cloud リソースのワークロードに一時的にアクセス権を付与すると、そのアクセスを手動で管理する必要がなくなります。
条件は、Secret Manager シークレットや Cloud Storage バケットなどの特定のリソースではなく、プロジェクト、フォルダ、組織レベルで許可ポリシーを設定する場合に便利です。
許可ポリシーに条件を追加するには、次のリソースを使用します。
- 条件付きロール バインディングを管理する: 条件付きロール バインディングを追加、変更、削除します。
- 一時的なアクセスを構成する: 条件を使用して、許可ポリシーで Google Cloud リソースに対する一時的なアクセス権を設定します。
- タグと条件付きアクセス: 条件を使用して、リソースに特定のタグが付いている場合にのみ許可ポリシーを適用します。
次の式の例は、条件を使用する一般的なシナリオを想定しています。式で使用できる属性のリストについては、IAM Conditions の属性リファレンスをご覧ください。
条件式の例 | ||
---|---|---|
指定した時刻になるまでアクセスを許可する | request.time < timestamp('
|
|
リクエストに含まれているリソースに、指定されたタグが付いている場合にアクセスを許可する | resource.matchTag(' 次のように置き換えます。
|
IAM ポリシーで Kubernetes リソースを参照する
IAM ポリシーでは、IAM のプリンシパル ID を使用してリソースを選択することで、Kubernetes リソースを参照します。この ID の構文は次のとおりです。
PREFIX://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/example-project.svc.id.goog/SELECTOR
この例では、次のフィールドについて考えてみましょう。
PREFIX
: 選択したリソースに応じてprincipal
またはprincipalSet
にする必要があります。principal
は、単一の ServiceAccount などの特定のリソースを対象とします。principalSet
は、特定のクラスタ内のすべての Pod など、指定されたリソースに属する複数のリソースを対象とします。SELECTOR
: プリンシパル タイプを選択する文字列。たとえば、kubernetes.serviceaccount.uid/SERVICEACCOUNT_UID
は UID で ServiceAccount を選択します。
次の表に、GKE でサポートされているプリンシパル タイプを示します。
プリンシパル ID のタイプ | 構文 |
---|---|
特定の Kubernetes ServiceAccount を使用するすべての Pod | 名前で ServiceAccount を選択します。
principal://iam.googleapis.com/projects/ 次のように置き換えます。
UID で ServiceAccount を選択します。 principal://iam.googleapis.com/projects/ 次のように置き換えます。
|
サービス アカウントやクラスタに関係なく、Namespace 内のすべての Pod | principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/namespace/NAMESPACE 次のように置き換えます。
|
特定のクラスタ内のすべての Pod | principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/kubernetes.cluster/https://container.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME 次のように置き換えます。
|
認証情報フロー
Google Cloud クライアント ライブラリを使用する場合など、ワークロードが Google Cloud API にアクセスするためのリクエストを送信すると、次の認証処理が行われます。
- アプリケーションのデフォルト認証情報(ADC)が、VM 上で実行される Compute Engine メタデータ サーバーに Google Cloud アクセス トークンをリクエストします。
- GKE メタデータ サーバーはトークン リクエストをインターセプトし、Kubernetes API サーバーにリクエスト元のワークロードを識別する Kubernetes ServiceAccount トークンを要求します。この認証情報は、API サーバーによって署名された JSON Web Token(JWT)です。
- GKE メタデータ サーバーが、Security Token Service を使用して、Kubernetes ワークロードの ID を参照する有効期間の短い Google Cloud 連携アクセス トークンと JWT を交換します。
Security Token Service から返される連携アクセス トークンには、ID 連携: プロダクトと制限事項で説明されているように、一部の Google Cloud サービスへのアクセス時に制限が適用される場合があります。選択した Google Cloud サービスに制限が適用される場合は、必要に応じてサービス アカウントの権限借用を構成できます。この方法では、Workload がターゲット サービスへのアクセスに使用できる IAM サービス アカウントのアクセス トークンが生成されます。詳細については、代替方法: Kubernetes ServiceAccount を IAM にリンクするをご覧ください。
これにより、ワークロードは、ワークロードの IAM プリンシパル ID でアクセスできるすべての Google Cloud API にアクセスできるようになります。
ID の同一性
プリンシパル ID のメタデータが、同じ Google Cloud プロジェクトに属しているために Workload Identity プールを共有する複数のクラスタのワークロードで同じ場合、IAM はこれらのワークロードを同じものとして識別します。たとえば、2 つのクラスタに同じ Namespace があり、IAM でその Namespace へのアクセス権を付与すると、両方のクラスタのその Namespace のワークロードがそのアクセス権を取得します。条件付き IAM ポリシーを使用すると、このアクセスを特定のクラスタに制限できます。
たとえば、次の図について考えてみましょう。クラスタ A とクラスタ B は同じ Workload Identity プールに属しています。Google Cloud は、クラスタ A とクラスタ B の両方の backend
Namespace で back-ksa
ServiceAccount を使用するアプリケーションを同じ ID として識別します。IAM では、呼び出しを行うクラスタを区別しません。
また、この ID の同一性は、特定の Workload Identity プール内のすべてのクラスタを信頼できるようにする必要があることを意味します。たとえば、上記の例の新しいクラスタ(クラスタ C)が信頼できないチームによって所有されていた場合、クラスタ A とクラスタ B と同様に、backend
Namespace を作成し、back-ksa
ServiceAccount を使用して Google Cloud APIs にアクセスできます。
信頼できないアクセスを回避するには、クラスタを別々のプロジェクトに配置し、別々の Workload Identity プールを取得できるようにします。また、共通のプリンシパル ID を回避するため、Namespace 名が互いに異なるようにする必要があります。
GKE メタデータ サーバーについて
GKE 用 Workload Identity 連携が有効になっている GKE のすべてのノードは、メタデータを GKE メタデータ サーバーに保存します。GKE メタデータ サーバーは、Kubernetes ワークロードに必要な Compute Engine メタデータ サーバー エンドポイントのサブセットです。
GKE メタデータ サーバーは DaemonSet として実行されます。それぞれの Linux ノードで 1 つの Pod が使用されるか、クラスタ内の各 Windows ノードにネイティブ Windows サービスが実行されます。メタデータ サーバーは、http://metadata.google.internal
(169.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/ |
ノードに関連付けられているサービス アカウントのディレクトリ。各サービス アカウントごとに、次の情報を利用できます。
|
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 プロジェクト番号。 |
Workload Identity Federation for GKE の制限事項
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 連携を有効にしても、リクエスト指標のリリースを継続するには Knative serving の手動設定が必要になります。
GKE 用 Workload Identity 連携では、メモリの問題を回避するため、ノードごとに GKE メタデータ サーバーへの接続数の上限を 200 に設定しています。ノードがこの上限を超えると、タイムアウトが発生することがあります。
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 API にアクセスする場合、GKE 用 Workload Identity 連携の代わりに、次のいずれかの方法を使用できます。これらの方法では、セキュリティに関して一定の妥協が必要になるため、GKE 用 Workload Identity 連携を使用することをおすすめします。
ノードの Compute Engine のデフォルトのサービス アカウントを使用します。プロジェクト内の任意の IAM サービス アカウントとしてノードプールを実行できます。ノードプールの作成時にサービス アカウントを指定しないと、GKE はプロジェクトに Compute Engine のデフォルトのサービス アカウントを使用します。デフォルトの Compute Engine サービス アカウントは、そのノードにデプロイされているすべてのワークロードで共有されます。その結果、権限が過剰にプロビジョニングされる可能性があります。これは、最小権限の原則に反し、マルチテナント クラスタでは不適切です。
サービス アカウント キーをエクスポートして Kubernetes Secret として保存し、Volume として Pod にマウントします。