技術概要 - Amazon EKS

技術概要

2014 年に、OpenID Connect (OIDC) を使用したフェデレーティッドアイデンティティのサポート AWS Identity and Access Management が追加されました。この機能により、サポートされている ID プロバイダーで AWS API コールを認証し、有効な OIDC JSON ウェブトークン (JWT) を受け取ることができます。このトークンを AWS STS AssumeRoleWithWebIdentity の API オペレーションに渡し、一時的な IAM ロールの認証情報を受け取ることができます。これらの認証情報を使用して、Amazon S3 や DynamoDB などの任意の AWS のサービスとやり取りできます。

Kubernetes は、独自の内部 ID システムとして長い間、サービスアカウントを使用してきました。ポッドは、Kubernetes API サーバーのみが検証できる自動マウントトークン(OIDC JWT ではない)を使用して Kubernetes API サーバーで認証できます。これらのレガシーサービスアカウントトークンは期限切れにならず、署名キーの更新は難しいプロセスです。Kubernetes バージョン 1.12 では、サービスアカウント ID を含む OIDC JSON ウェブトークンである新しい ProjectedServiceAccountToken 機能のサポートが追加され、設定可能な対象者がサポートされます。

Amazon EKS は、ProjectedServiceAccountToken JSON ウェブトークンの署名キーを含むクラスターごとにパブリック OIDC 検出エンドポイントをホストするようになり、IAM などの外部システムで、Kubernetes によって発行された OIDC トークンを検証して受け入れることができるようになりました。

IAM ロールの設定

IAM では、クラスターの OIDC プロバイダー、サービスアカウントの名前空間、および (オプションで) サービスアカウント名に限定された信頼関係を持つ IAM ロールを作成し、サービスアカウントに関連付ける IAM ポリシーをアタッチします。以下の StringEquals および StringLike 条件に複数のエントリを追加して、ロールで複数のサービスアカウントまたは名前空間を使用できます。

  • ロールを特定のサービスアカウントに絞り出すには:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/OIDC_PROVIDER" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "OIDC_PROVIDER:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME" } } } ] }
  • ロールを名前空間全体にスコープするには(名前空間を境界として使用するため):

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/OIDC_PROVIDER" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "OIDC_PROVIDER:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:*" } } } ] }

サービスアカウント設定

Kubernetes を使用するユーザーは、eks.amazonaws.com/role-arn のアノテーションをサービスアカウントに追加することで、クラスター内のサービスアカウントに関連付ける IAM ロールを定義します。

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME

ポッドの設定

クラスターの Amazon EKS Pod Identity Webhook は、このアノテーションを持つサービスアカウントに関連付けられているポッドを監視し、それらに以下の環境変数を適用します。

AWS_ROLE_ARN=arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
注記

クラスターでは、環境変数とトークンファイルのマウントを設定するために、mutating なウェブフックを使用する必要はありません。これらの環境変数を手動で追加するようにポッドを設定できます。

SDK のサポートされているバージョンAWSは、最初に認証情報チェーンプロバイダーでこれらの環境変数を探します。ロールの認証情報は、この条件を満たすポッドに使用されます。

注記

ポッドがサービスアカウントに関連付けられた IAM ロールの AWS 認証情報を使用する場合、AWS CLI またはそのポッドのコンテナ内の他の SDK は、そのロールによって提供される認証情報を使用します。この場合もポッドには、(そのアクセスを制限しない限り) Amazon EKS ノードの IAM ロール に提供された認証情報へのアクセスが許可されます。詳細については、「ワーカーノードに割り当てられたインスタンスプロファイルへのアクセスを制限する」を参照してください。

デフォルトでは、root として実行されるコンテナにのみ、Web ID トークンファイルを読み取るための適切なファイルシステムアクセス許可があります。コンテナを root として実行するか、マニフェスト内のコンテナに以下のセキュリティコンテキストを渡すことで、これらのアクセス許可を付与できます。fsGroup ID は任意であり、いずれかの有効なグループ ID を選択できます。ポッドにセキュリティコンテキストを設定することの意味の詳細については、Kubernetes ドキュメントの「Configure a Security Context for a Pod or Container」を参照してください。

注記

1.19 以降のクラスターでは、このセキュリティコンテキストの指定は必須ではありません。

apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: metadata: labels: app: my-app spec: serviceAccountName: my-app containers: - name: my-app image: my-app:latest securityContext: fsGroup: 1337 ...

kubelet が、ポッドに代わってリクエストを送信し、トークンを格納します。デフォルトで kubelet は、トークンが合計 TTL の 80% を超えている場合、またはトークンが 24 時間を超えている場合、そのトークンをリフレッシュします。ポッド仕様の設定により、デフォルトのサービスアカウントを除くすべてのアカウントの有効期限を変更できます。詳細については、Kubernetes ドキュメントの「Service Account Token Volume Projection (サービスアカウントトークンボリュームのプロジェクション)」を参照してください。

クロスアカウントの IAM アクセス許可

別のアカウントのクラスターから ID プロバイダーを作成するか、連鎖した AssumeRole オペレーションを使用することで、クロスアカウントの IAM アクセス許可を設定できます。次の例では、アカウント A は、サービスアカウントの IAM ロールをサポートする Amazon EKS クラスターを所有しています。そのクラスターで実行されているポッドは、アカウント B の IAM アクセス許可を引き受ける必要があります。

例 : 別のアカウントのクラスターから ID プロバイダーを作成する

この例では、アカウント A はアカウント B にクラスターからの OIDC 発行者 URL を提供します。アカウント B は、アカウント A のクラスターからの OIDC 発行者 URL を使用して、クラスターの IAM OIDC プロバイダーを作成するには および サービスアカウントの IAM ロールとポリシーの作成 の手順に従います。次に、クラスター管理者は、アカウント A のクラスターのサービスアカウントに注釈を付けて、アカウント B のロールを使用します。

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_B_ID:role/IAM_ROLE_NAME

例 : 連鎖された AssumeRole オペレーションを使用する

この例では、アカウント B は、アカウント A のクラスターのポッドに付与するためのアクセス許可を持つ、IAM ポリシーを作成しています。アカウント B は、以下に示すように、アカウント A (111111111111) への AssumeRole アクセスを許可できる信頼関係を持つ IAM ロールにそのポリシーをアタッチします。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }

アカウント A は、次に示すように、クラスターの OIDC 発行者 URL で作成された ID プロバイダーから認証情報を取得する信頼ポリシーを持つロールを作成します。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111111111111:oidc-provider/oidc.eks.region-code.amazonaws.com/id/EXAMPLEC061A78C479E31025A21AC4CDE191335D05820BE5CE" }, "Action": "sts:AssumeRoleWithWebIdentity" } ] }

アカウント A は、アカウント B が作成したロールを引き受けるための以下のアクセス許可を持つポリシーをそのロールにアタッチします。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::222222222222:role/account-b-role" } ] }

アカウント B のロールを引き受けるポッドのアプリケーションコードは、account_b_roleaccount_a_role の 2 つのプロファイルを使用します。account_b_role プロファイルでは、ソースとして account_a_role プロファイルを使用します。AWS CLI の場合、~/.aws/config ファイルは次の例のようになります。

[profile account_b_role] source_profile = account_a_role role_arn=arn:aws:iam::222222222222:role/account-b-role [profile account_a_role] web_identity_token_file = /var/run/secrets/eks.amazonaws.com/serviceaccount/token role_arn=arn:aws:iam::111111111111:role/account-a-role

他の AWS SDK の連鎖されたプロファイルを指定するには、そのドキュメントを参照してください。