APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

IAM Roles for Service Accounts(IRSA)の仕組みを深堀りしてみた

はじめに

こんにちは!クラウド事業部の中根です。
半年ほど前から、Kubernetesを学びEKSを使うようになりました。
その中で特に苦戦したIAM Roles for Service Accounts(IRSA)の仕組みについて紹介します!

本記事について

本記事では、IAM Roles for Service Accounts(IRSA)の仕組みを解説します。
IRSAを使い始めたばかりの方、仕組みをよく理解せずに使っている方を想定読者としています。
IRSAの実装の各手順の裏で何が起きているのかを詳しく解説します。
実装方法については詳しく解説しないので、こちらをご覧ください。

IAM Roles for Service Accounts(IRSA)とは?

一言で言うと、Pod(サービスアカウント)にIAMアクセス許可を付与する機能です。

なぜ必要なのか?

前提として、KubernetesではPodにアクセス許可を与える時、サービスアカウントを介しています。

しかし、IAMロールをサービスアカウントに直接関連付ける機能がKubernetesにはありません。

この関連付けを行うために、EKS Pod IdentityまたはIRSAが必要になります。

EKS Pod Identityについて

IRSAと同様に、PodにIAMアクセス許可を付与する方法に、EKS Pod Identityがあります。
もともとIRSAが最初にあったのですが、別の方法としてEKS Pod Identityが昨年登場しました。
基本的にはEKS Pod Identityを使用し、EKS Pod Identityが使用できない場面ではIRSAを使うことが推奨されています。
こちらを参照。
EKS Pod Identityについても仕組みを解説しているので、ぜひご覧ください!

techblog.ap-com.co.jp

なぜ仕組みを知る必要があるのか

一言で言うと、EKSクラスタの構築をスムーズにするためです。
IRSAは、Podのアクセス制御を行う上で、非常に重要な仕組みです。
基本的にはEKS Pod Identityの使用が推奨されますが、どうしてもIRSAを使わないといけない場面もあります。
仕組みを知らないまま構築すると、設定したけどうまく動いてくれない、といった場面によく出会うことになると思います。
特に、IaCなどのドキュメントと異なる手順で設定する場面で出会うことでしょう。
私は、このトラブルシューティングに結構時間を使わされてきました。
振り返った時に、先に仕組みを知っておけば、もっと早く簡単に解決できたな、と後悔しています。

仕組み解説

全体像

大まかな流れを図にしました。
①~⑥の詳細は後述します。

登場人物

図の登場人物について、補足します。

  • EKS Pod Identity Webhookサーバー
    EKSマネージドで作成される、Mutating Webhookです。
    Mutating Webhookは、簡単に言うと、「Kubernetesのリソースを作成・変更した時に、その設定を変更する機能」です。
    EKS Pod Identity Webhookサーバーの場合は、「Podを作る時に、AWSの認証情報を取得するためにPodの設定変更」をします。
    コントロールプレーン側にいるので普段は見えませんが、EKS Pod IdentityやIRSAを利用する上で欠かせない存在です。

  • SDK
    プログラミングで AWSサービスを利用するためのツールです。
    上図の場合だと、Pod(アプリケーション)で次のようなコードが実行された、というイメージです。

      cloudwatch = boto3.client('cloudwatch')
    
      # メトリクスデータをCloudWatchに送信
      response = cloudwatch.put_metric_data(
          Namespace='MyApp/Metrics', 
          MetricData=[
              {
                  'MetricName': 'PageViewCount',  
                  'Dimensions': [
                      {
                          'Name': 'PageType',
                          'Value': 'HomePage'
                      },
                  ],
                  'Timestamp': datetime.utcnow(), 
                  'Value': 1.0, 
                  'Unit': 'Count' 
              },
          ]
      )
    
  • IAM OIDCプロバイダー
    信頼できる第三者として、トークンを発行、検証するものです。
    EKSクラスタのサービスアカウントとIAMの間で、トークンを介して信頼性を確立し、サービスアカウントが特定のIAMロールを引き受けられるようにします。

仕組みの詳細

IRSAでAWSサービスにアクセスするまでの流れを説明します。

①IAM OIDCプロバイダーの作成

OIDCプロバイダーを作成し、IAMにプロバイダーを登録します。
EKSクラスタが作成したものを使うこともできますし、外部のOIDCプロバイダーを関連付けることもできます。
マネジメントコンソール、eksctlなど作成手順によってやるべきことが異なります。
例えば、TerraformのEKSモジュールを使った場合は、デフォルトでプロバイダーの作成とIAMへの登録までが自動で行われるので、何もしなくてよいです。
詳しい作成方法はこちらを参考にしてください。
この手順を完了することで、クラスタ、OIDCプロバイダー、IAMの関係性が以下のようになります。
(イメージ図であり、技術的に正しいものではない点に注意)

②IAMロールの作成

Podに与えたい権限を持つIAMロールを作成します。
IAMロールの信頼ポリシーのConditionで、サービスアカウント名やOIDCプロバイダのホスト名などの指定を必ずしましょう。
Conditionを指定しないと、どのサービスアカウント(Pod)でもそのIAMロールを使えるようになってしまうので、IRSAを使う意義が失われてしまいます。
参考ドキュメント

③サービスアカウントにIAMロールのARNを追加

Podが使用するサービスアカウントを作成します。
このとき、サービスアカウントのeks.amazonaws.com/role-arnアノテーションに、IAMロールのARNを指定する必要があります。
指定しないと、サービスアカウントが使いたいIAMロールがわからないので、アノテーションを使って指定しています。
ちなみに、EKS Pod Identityの場合は、Pod Identityの関連付けでサービスアカウントとIAMロールの対応がわかるので、アノテーションは不要です。
詳しい手順はこちらを参考にして下さい。

④Pod作成(kubectl apply)

Podを作成します。
ここでは、kubectl applyを実行した時の動きについて解説します。

  1. APIサーバーは、Pod作成のリクエストを受け取ります。
  2. Podを実際に作成する前に、MutatingWebhookConfigurationに従って、EKS Pod Identity Webhookサーバーに対してリクエストが送られます。
    こちらは、MutatingWebhookConfigurationの定義です。
    ここから、Podが作成されるとPod Identity Webhookサーバーの/mutateエンドポイントにリクエストが送られることが読み取れます。
  3. EKS Pod Identity Webhookサーバーは、Podに環境変数を追加します。
    いくつかあるのですが特筆すべき2つについて紹介します。
    AWS_IAM_ROLE_ARN は、③で設定したIAMロールのARNです。
    EKS Pod Identity Webhookサーバーに対するリクエストの中に、サービスアカウントの情報もふくまれており、eks.amazonaws.com/role-arnアノテーションの値をこの環境変数の値にセットします。
    AWS_WEB_IDENTITY_TOKEN_FILE は、認証情報取得の際に使うトークンの格納場所です。
  4. 変更が行われたPodが作成されます。
    この時点で、IRSAによる認証情報取得の準備が整った状態になっています。

⑤一時的な認証情報取得

Podが起動し、やがてAWSサービス(例だとCloudWatch)にアクセスするコードが実行されることになります。
ここでは、コードが実行された時の動きについて解説します。

  1. 環境変数AWS_IAM_ROLE_ARN に指定されたIAMロールのARNと、環境変数AWS_WEB_IDENTITY_TOKEN_FILE から取得したトークンと共にAssumeRoleWithWebIdentity APIを実行します。
    なお、コードの内容によっては環境変数が使用されません。
    ここでは、コードで明示的に指定しておらず、環境変数が使われるものとします。
    SDKの認証設定の優先順位についてはこちらを参照してください。

  2. AssumeRoleWithWebIdentity APIによって、トークンを検証し、指定されたIAMロールを使用するための一時的な認証情報(アクセスキー、シークレットキー、セッショントークン)を取得することができます。
    具体的には以下のような事が行われていると考えられます。

    • トークンの発行者がIAMに登録されているOIDCプロバイダか確認
    • 署名を検証
    • トークンの有効期限が切れていないか
    • 信頼ポリシーの検証

    参考:AssumeRoleWithWebIdentity APIのリファレンス

⑥アクセス

取得した認証情報を使って、AWSサービスにアクセスすることができるようになります!

終わりに

今回はIAM Roles for Service Accounts(IRSA)の仕組みについて解説しました!
仕組みを知っておくと障害切り分けが捗り、結果的にEKSクラスタの構築がスムーズになります!

関連記事

techblog.ap-com.co.jp

お知らせ

APCはAWS Advanced Tier Services(アドバンストティアサービスパートナー)認定を受けております。

その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。
www.ap-com.co.jp

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp