スキップしてコンテンツを表示

Amazon EKS における、OIDC プロバイダーと IRSA に関する問題のトラブルシューティング方法を教えてください。

所要時間4分
0

使用するポッドにおいて、Amazon Elastic Kubernetes Service (Amazon EKS) の AWS アカウントトークンでは、AWS Identity and Access Management (IAM) ロールのアクセス許可を使用できません。

解決策

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

クラスターに既存の IAM OIDC プロバイダーが存在するかどうかを確認する

OpenID Connect (OIDC) プロバイダーが存在しない場合、次のようなエラーが発生します。

「WebIdentityErr: failed to retrieve credentials\ncaused by: InvalidIdentityToken: No OpenIDConnect provider found in your account for https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\tstatus code: 400 (アカウントには適切な OpenIDConnect プロバイダーが存在しません)」

既存の IAM OIDC プロバイダーが存在するかどうかを確認するには、次の手順を実行します。

  1. クラスターの OIDC プロバイダー URL を確認するには、次の AWS CLI コマンド describe-cluster を実行します。

    aws eks describe-cluster --name cluster_name --query "cluster.identity.oidc.issuer" --output text

    注: cluster-name を実際のクラスター名に置き換えてください。
    出力例:

    https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
  2. アカウント内の IAM OIDC プロバイダーを一覧表示するには、次の list-open-id-connect-providers コマンドを実行します。

    aws iam list-open-id-connect-providers | grep EXAMPLED539D4633E53DE1B716D3041E

    注: EXAMPLED539D4633E53DE1B716D3041E を、上記のコマンドから取得した OIDC プロバイダーの URL に置き換えてください。
    コマンドが出力を返す場合は、クラスターには既存のプロバイダーが存在します。コマンドが出力を返さない場合は、IAM OIDC プロバイダーを作成する必要があります。出力例:

    "Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"

IAM ロールに必要なアクセス許可が含まれており、IAM ポリシーがアタッチされているかどうかを確認する

次の手順を実行します。

  1. IAM コンソールを開きます。
  2. ナビゲーションペインで [ロール] を選択します。
  3. Kubernetes サービスアカウントに関連付けられているロールを選択します。
  4. [アクセス許可] タブを選択します。次に、ロールにアタッチされているポリシーを参照し、構成に必要なアクセス許可が含まれていることを確認してください。
  5. [信頼関係] タブを選択します。次に、IAM ポリシーの形式が次の JSON ポリシーの形式と一致していることを確認します。
    {  "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME",
              "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"
            }
          }
        }
      ]
    }
    次の get-role コマンドを実行しても信頼関係を確認できます。
    aws iam get-role --role-name EKS-IRSA
    注: EKS-IRSA をサービスアカウント IAM ロール (IRSA) のロール名に置き換えてください。
    出力例:
    {  "Role": {
        "Path": "/",
        "RoleName": "EKS-IRSA",
        "RoleId": "AROAQ55NEXAMPLELOEISVX",
        "Arn": "arn:aws:iam::ACCOUNT_ID:role/EKS-IRSA",
        "CreateDate": "2021-04-22T06:39:21+00:00",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
              },
              "Action": "sts:AssumeRoleWithWebIdentity",
              "Condition": {
                "StringEquals": {
                  "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com",
                  "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME"
                }
              }
            }
          ]
        },
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
          "LastUsedDate": "2021-04-22T07:01:15+00:00",
          "Region": "AWS_REGION"
        }
      }
    }
    出力された JSON において、AssumeRolePolicyDocument セクションを参照して信頼関係ポリシーを確認してください。
  6. (オプション) ロールの信頼関係を更新し、正しい AWS リージョン、Kubernetes サービスアカウント名、または Kubernetes 名前空間を指定します。

サービスアカウントが作成済みかどうかを確認する

サービスアカウントが存在するかどうかを確認するには、次のコマンドを実行します。

kubectl get sa -n YOUR_NAMESPACE

**注:**YOUR_NAMESPACE は、Kubernetes の名前空間に置き換えてください。

出力例:

NAME      SECRETS   AGEdefault   1         28d
irsa      1         66m

出力には、目的のサービスアカウントが表示される必要があります。サービスアカウントが存在しない場合は、Kubernetes のウェブサイトで「ポッドでサービスアカウントを構成する」を参照してください。

サービスアカウントに正しい IAM ロールアノテーションが存在することを確認する

サービスアカウントに正しい IAM ロールアノテーションがあることを確認するには、次のコマンドを実行します。

kubectl describe sa irsa -n YOUR_NAMESPACE

**注:**irsa はご自身の Kubernetes サービスアカウント名に、YOUR_NAMESPACE は Kubernetes 名前空間に置き換えてください。

出力例:

Name:                irsa
Namespace:           default
Labels:              none
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
Image pull secrets:  none
Mountable secrets:   irsa-token-v5rtc
Tokens:              irsa-token-v5rtc
Events:              none

Annotation を参照し、正しい IAM ロールが表示されていることを確認してください。そうでない場合は、次のコマンドを実行してサービスアカウントを編集してください。

kubectl edit sa -n NAMESPACE

注: namespace を実際の名前空間に置き換えてください。

次に、Annotations の値を正しい IAM ロールで更新します。

ポッドで serviceAccountName が正しく指定されていることを確認する

serviceAccountName を確認するには、次のコマンドを実行します。

kubectl get pod POD_NAME  -o yaml -n YOUR_NAMESPACE| grep -i serviceAccountName:

注: 実際のものでそれぞれ、POD_NAME を Kubernetes Pod に、YOUR_NAMESPACE を名前空間に置き換えてください。

出力例:

serviceAccountName: irsa

出力の値に誤ったサービスアカウント名が表示される場合は、デプロイマニフェストを編集し、正しい名前を指定してください。その後、デプロイマニフェストを再デプロイします。

環境変数とアクセス許可を確認する

ポッドの環境変数を確認するには、次のコマンドを実行します。

kubectl -n YOUR_NAMESPACE exec -it POD_NAME -- env | grep AWS

出力例:

AWS_REGION=ap-southeast-2
AWS_ROLE_ARN=arn:aws:iam::111122223333:role/EKS-IRSA
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
AWS_DEFAULT_REGION=ap-southeast-2

出力には、目的のサービスアカウントが表示される必要があります。サービスアカウントが存在しない場合は、Kubernetes のウェブサイトで「ポッドでサービスアカウントを構成する」を参照してください。

アプリケーションはサポートされている AWS SDK を使用していることを確認する

AWS SDK のバージョンは、その AWS SDK の必須バージョン以上である必要があります。

ポッドを再作成する

IRSA を適用する前にポッドを作成した場合は、次のコマンドを実行してポッドを再作成してください。

kubectl rollout restart deploy nginx

出力例:

deployment.apps/nginx restarted

daemonset または statefulset のデプロイでは、次のコマンドを実行します。

kubectl rollout restart deploy DEPLOYMENT_NAME

ポッドを 1 つだけ作成した場合は、そのポッドを削除してから再作成する必要があります。次の手順を実行します。

  1. ポッドを削除するには、次のコマンドを実行します。
    kubectl delete pod POD_NAME
    注: POD_NAME を実際のポッド名に置き換えてください。
  2. ポッドを再作成するには、次のコマンドを実行します。
    kubectl apply -f SPEC_FILE
    **注:**SPEC\ _FILE は、Kubernetes マニフェストのファイルパスとファイル名に置き換えてください。

オーディエンスが正しいことを確認する

OIDC プロバイダーを間違ったオーディエンスで作成すると、次のエラーが表示されます。

「Error - An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Incorrect token audience (トークンのオーディエンスに誤りがあります)」

クラスターの IAM ID プロバイダーを確認するには、次の get-open-id-connect-provider コマンドを実行します。

aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E

注: 実際のものでそれぞれ、ACCOUNT_ID をアカウント ID に、AWS_REGION をリージョンに、EXAMPLED539D4633E53DE1B716D3041E を OIDC プロバイダーの URL に置き換えてください。

出力例:

{  "Url": "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E",
  "ClientIDList": [
    "sts.amazonaws.com"
  ],
  "ThumbprintList": [
    "9e99a48a9960b14926bb7f3b02e22da2b0ab7280"
  ],
  "CreateDate": "2021-01-21T04:29:09.788000+00:00",
  "Tags": []
}

出力では、ClientIDListsts.amazonaws.com である必要があります。そうでない場合は、ID プロバイダーをロールに追加し、[オーディエンス]sts.amazonaws.com を入力してください。

正しいサムプリントが設定されていることを確認する

IAM OIDC で設定したサムプリントが正しくない場合は、次のエラーが発生します。

「failed to retrieve credentials caused by: InvalidIdentityToken: OpenIDConnect provider's HTTPS certificate doesn't match configured thumbprint (OIDC プロバイダーの HTTPS 証明書は、設定されたサムプリントと一致しません)」

正しいサムプリントを自動的に設定するには、eksctl または Amazon EKS コンソールを使用して IAM ID プロバイダーを作成します。サムプリントを取得する他の方法については、「OpenID Connect ID プロバイダーのサムプリントを取得する」を参照してください。

(AWS China リージョンのみ) AWS_DEFAULT_REGION 環境変数を確認する

IRSA を適用したポッドまたはデーモンセットを AWS China リージョンのクラスターにデプロイするには、ポッドの仕様で AWS_DEFAULT_REGION を設定する必要があります。AWS_DEFAULT_REGION 環境変数を設定しない場合、ポッドまたはデーモンセットに対し、次のエラーが発生する場合があります。

「An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid (リクエストに含まれるセキュリティトークンが無効です)」

ポッドまたはデーモンセットの仕様に AWS_DEFAULT_REGION 環境変数を追加するには、次の例を参考にデプロイマニフェストを作成してください。

apiVersion: apps/v1kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      labels:
        app: my-app
    spec:
      serviceAccountName: my-app
      containers:
      - name: my-app
        image: my-app:latest
        env:
        - name: AWS_DEFAULT_REGION
          value: "AWS_REGION"
...

または、次のコマンドを実行して環境変数を設定してください。

kubectl set env deployment deployment_name AWS_DEFAULT_REGION=example_region -n NAMESPACE"

注: deployment_name を実際のデプロイ名に、example_region を AWS China リージョンに、NAMESPACE を実際の名前空間に置き換えてください。

コメントはありません