
この記事は GRIPHONE Advent Calendar 2021 16日目の記事です。
SREの徳田です。(2回目)
前回TokenRequestProjectionを使ったAWSへの認証をやったわけですが、同じ機能を使ってGCPのWorkload Identity Federationをやってみよう、という試みです。
TL;DR
- Workload Identity Pool & Providerを設定
- Podを作成
- TokenRequestProjectionを使ってOIDC ID Tokenを作成
- 認証情報構成ファイルをConfigMapなどで作成してマウント
- 環境変数で認証情報構成ファイルを指定
背景
GKEを使ってWorkload Identityやるならこっちの方法でいいじゃん!という話なのですが、hostNetworkを有効にしたPodではWorkload Identityを使うことができません。
ということでTokenRequestで発行されるOIDC ID Tokenを使ったWorkload Identity Federationで認証をしてみようとなった次第です。
Workload Identity Federationの設定
それではまずWorkload Identity Poolを作成します。
次にOIDC向けのWorkload Identity Providerを作成します。
--issuer-url
:クラスタのIssuerのURL。こちらの記事も見てみてください--allowed-audiences
:許可するAudience。--attribute-mapping
:属性マップ。複数ある場合はカンマで区切る
--attribute-mapping
では google.subject=assertion.sub
となっていますが、google.subject
はGCP上でのユーザーの一意の識別子で、 assertion.sub
はID Tokenの sub
クレームであり、これらをマップするように指定しています。
ついでにTokenRequestによって発行されるID Tokenの sub
クレームは以下のようになっております。
属性のマッピングについて詳しく知りたい方は以下からどうぞ
https://cloud.google.com/iam/docs/workload-identity-federation#mapping
GCPのServiceAccountの設定
Workload Identityを使って成り代わる先のServiceAccountを作成しましょう。
次にWorkload Identity Poolから先程作成したServiceAccountに成り代われるように権限を設定します。
--member
の指定は以下のようなフォーマットになっており、今回は sub
クレームが system:serviceaccount:default:default
となっているユーザーを許可するようにしています。要はdefaultネームスペースのdefaultサービスアカウントに権限を渡しています。
memberの指定方法についてはこちらを参考にしていただければと思います。
https://cloud.google.com/iam/docs/workload-identity-federation#impersonation
そして最後に作成したサービスアカウントに適当に権限を付けておきましょう。今回はviewer権限を付与します。
KubernetesのManifestの設定
それではいよいよPodを作ります。
google-cloud-sdkでは認証情報を構成ファイルとして渡してあげる必要があります。その構成ファイルを作成しておきます。
--service-account
:成り代わるサービスアカウントを指定--output-file
:構成ファイルの出力先--credential-source-file
:ID Tokenのパス--credential-source-type
:ファイルのタイプ。text
/json
を指定。今回は直接ID Tokenがおいてあるのでtext
を指定
すると作業フォルダに config.json
というファイルで以下のような内容のものができます。
この作成ファイルを使ってConfigMapとPodを作成します。
要点としては
- 構成ファイルを入れたConfigMapのマウント先と
GOOGLE_APPLICATION_CREDENTIALS
のパスを合わせる - TokenRequestで作成したTokenを含むProjected Volumeのマウント先と構成ファイルで指定したID Tokenのパスを合わせる
- audienceにWorkload Identity Providerを作成した際に
--allowed-audience
で指定した値と同じものを指定
また、今回はgcloudコマンドを使うため gcloud auth login
コマンドを実行していますが、クライアントライブラリを活用したツールなどでは環境変数からクレデンシャルを読み込んでくれます。
それでは上記のManifestを適用してログを確認してみます。
ログの通り、サービスアカウントに成り代わってクラスタの情報を取得することができました!!
さいごに
TokenRequestProjectionとWorkload Identity Federationを使ってGCPのサービスアカウントに成り代わってGCPを操作することができました。
hostNetwork
を有効にしているとノードプールのインスタンスに権限を渡すか、サービスアカントを作成して権限を付与し、JSONのSecretを渡して上げる必要がありましたが、TokenRequestProjectionとWorkload Identity Federationを組み合わせることで、外からクレデンシャルを渡すことなく認証処理を動かすことができました。
このケースに当たることはなかなか無いとは思いますが、もしこの手段が活用できるケースが有った場合は参考にしていただければ幸いです。
それでは!