サービスアカウントのために AWS Identity and Access Management (IAM) ロールを使用しようとしています。しかし、私の Amazon Elastic Kubernetes Service (Amazon EKS) ポッドは、割り当てられた IAM ロールを引き受けません。認証エラーが表示されます。あるいは、ポッドが、ポッドに割り当てられた IAM ロールの代わりに、Amazon EKS ノードに割り当てられたデフォルトの IAM ロールを使用しようとします。
簡単な説明
サービスアカウントの IAM ロール機能を使用して問題を解決するには、以下を試してください。
- Amazon EKS クラスター用の IAM OpenID Connect (OIDC) アイデンティティプロバイダーがあることを確認する
- IAM ロールポリシーと信頼ポリシー設定を検証する
- サービスアカウントが存在しており、IAM ロールの ARN のために適切にフォーマットされたアノテーションがあることを確認する
- テストポッドを使用して、サービスアカウントが機能していることを確認する
注: AWS Command Line Interface (AWS CLI) コマンドの実行中にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください。
解決方法
Amazon EKS クラスター用の IAM OIDC アイデンティティプロバイダーがあることを確認する
まだ作成していない場合は、クラスター用の IAM OIDC プロバイダーを作成します。サービスアカウントのために IAM ロールを使用するには、クラスター用の OIDC アイデンティティプロバイダーが必要です。
次に、OIDC アイデンティティプロバイダーが正しく設定されていることを確認します。
1. IAM コンソールを開いて、ナビゲーションペインから [Identity providers] (アイデンティティプロバイダー) を選択します。
2. [Provider] (プロバイダー) 列で、OIDC プロバイダーの URL を確認して書き留めます。
3. 別のタブまたはウィンドウで Amazon EKS コンソールを開いて、ナビゲーションペインから [クラスター] を選択します。
4. クラスターを選択して、[Configuration] (設定) タブを選択します。
5. [Details] (詳細) セクションで、[OpenID Connect provider URL] (OpenID Connect プロバイダー URL) プロパティの値を書き留めます。
6. Amazon EKS コンソールからの OIDC プロバイダー URL (ステップ 5) が IAM コンソールの OIDC プロバイダー URL (ステップ 2) と一致することを確認します。
Amazon EKS クラスターの OIDC プロバイダー URL が IAM コンソールの OIDC プロバイダー URL のいずれとも一致しない場合は、新しい IAM OIDC プロバイダーを作成する必要があります。
IAM ロールポリシーと信頼ポリシー設定を検証する
IAM ロールには、そのロールに割り当てられていることが想定されている完全な許可がない可能性があります。また、AWS マネジメントコンソールまたは AWS CLI を使用して IAM ロールを作成した場合は、IAM ロールの信頼関係ポリシーにも構文エラーがある可能性があります。
IAM ロールポリシーを検証し、信頼ポリシーの構文エラーをチェックするには、次の手順を実行します。
1. IAM コンソールを開きます。
2. ナビゲーションペインで、[Roles] (ロール) を選択し、自分のロールを選択します。
3. ロールのページで [Permissions] (許可) タブを選択し、必要なすべての許可がロールに割り当てられていることを確認します。
4. [Trust Relationships] (信頼関係) タブを選択して、[Edit trust relationship] (信頼関係を編集する) を選択します。
5. 信頼関係のポリシードキュメントで、ポリシーの形式が次の JSON ポリシーの形式と一致することを確認します。
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::your-account-id:oidc-provider/oidc.eks.your-region-code.amazonaws.com/id/EXAMPLE_OIDC_IDENTIFIER"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.your-region-code.amazonaws.com/id/EXAMPLE_OIDC_IDENTIFIER:sub": "system:serviceaccount:your-namespace:your-service-account"
}
}
}
]
}
前述の JSON ポリシーで、Federated プロパティ行と StringEquals プロパティ行の形式を確認します。Federated 行で、AWS リージョンコード (your-region-code)、アカウント ID (your-account-id)、および一意の OIDC 識別子 (EXAMPLE_OIDC_IDENTIFIER) が正しくフォーマットされていることを確認します。StringEquals 行で、リージョンコード (your-region-code)、OIDC の一意の識別子 (EXAMPLE_OIDC_IDENTIFIER)、Kubernetes 名前空間 (your-namespace)、および Kubernetes サービスアカウント名 (your-namespace) が正しくフォーマットされていることを確認します。
6. ポリシードキュメントを編集してフォーマットエラーを修正する場合は、[Update Trust Policy] (信頼ポリシーの更新) を選択します。
サービスアカウントが存在しており、IAM ロールの ARN のために適切にフォーマットされたアノテーションがあることを確認する
1. Kubernetes サービスアカウントが存在することを確認します。
$ kubectl get serviceaccount YOUR_ACCOUNT_NAME -n YOUR_NAMESPACE -o yaml
注: YOUR_ACCOUNT_NAME を自分のアカウント名に置き換えます。YOUR_NAMESPACE を自分の名前空間に置き換えます。
前述のコマンドでサービスアカウント名が返されない場合は、(Kubernetes ウェブサイトから) サービスアカウントを作成します。
2. サービスアカウントの名前が想定どおりの名前であること、および role-arn アノテーションが正しくフォーマットされていることを確認します。例:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::012345678912:role/my-example-iam-role
name: my-example-serviceaccount
namespace: my-test-namespace
テストポッドを使用して、サービスアカウントが機能していることを確認する
テストポッドを実行して、サービスアカウントが正しく機能しているかどうかを確認できます。その後、ポッドが環境変数を正しくマウントでき、指定された IAM ロールを引き受けることができるかどうかを確認します。
注: サービスアカウントの IAM ロール機能が正常に動作している場合でも、アプリケーションの認証情報に関連する問題が発生する可能性があります。ポッドに正しい環境変数がある場合も、この問題が発生する可能性があります。この問題を回避するには、検証のために AWS CLI コンテナイメージを使用します。
1. awscli-pod.yaml という名前のローカル YAML ファイルを作成します。例:
apiVersion: v1
kind: Pod
metadata:
name: awscli
labels:
app: awscli
spec:
serviceAccountName: YOUR_SERVICE_ACCOUNT
containers:
- image: amazon/aws-cli
command:
- "sleep"
- "604800"
imagePullPolicy: IfNotPresent
name: awscli
restartPolicy: Always
注: YOUR_SERVICE_ACCOUNT を自分の Kubernetes サービスアカウント名に置き換えます。
2. (YAML ファイルから) テストポッドを名前空間に作成します。
$ kubectl apply -f ./awscli-pod.yaml -n YOUR_NAMESPACE
注: YOUR_NAMESPACE を自分の名前空間に置き換えます。
3. awscli ポッドに正しい環境変数があることを確認します。
$ kubectl exec -n YOUR_NAMESPACE awscli env | grep AWS
出力:
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
4. テストポッドが正しい IAM ロールを使用していることを確認します。
$ kubectl exec -it awscli -n YOUR_NAMESPACE -- aws sts get-caller-identity
出力:
{
"UserId": "REDACTEDY471234567890:botocore-session-1632772568",
"Account": "012345678912",
"Arn": "arn:aws:sts::012345678912:assumed-role/your-iam-role/botocore-session-1632772568"
}
ステップ 4 のコマンドからの出力で受け取る IAM ロール名 (your-iam-role) を含む Arn 値を書き留めます。
5. IAM ロールを確認した後、awscli ポッドを削除します。
$ kubectl delete -f ./awscli-pod.yaml -n YOUR_NAMESPACE
awscli ポッドに正しい IAM ロールが表示されていれば、サービスアカウントの IAM ロール機能は正常に動作しています。
前述の手順は、IAM トークンがポッドに正しくマウントされていることを確認します。それでもアプリケーションがトークンファイルを正しく使用できない場合は、アプリケーションまたは SDK レベルで問題がある可能性があります。この問題は、アプリケーションが AWS 認証情報を取り込む方法に関連している可能性があります。詳細については、Using the Default Credential Provider Chain および Credentials (Boto3 ウェブサイトから) を参照してください。