Identity and Access Management - Amazon EKS

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Identity and Access Management

Identity and Access Management (IAM) は、認証と認可の 2 つの重要な機能を実行する AWS のサービスです。認証にはアイデンティティの検証が含まれますが、認可は AWS リソースが実行できるアクションを管理します。AWS 内では、リソースは EC2 などの別の AWS サービスでも、IAM ユーザーロールなどの AWS プリンシパルでもかまいません。リソースが実行できるアクションを管理するルールは、IAM ポリシーとして表されます。

EKS クラスターへのアクセスの制御

Kubernetes プロジェクトは、ベアラートークン、X.509 証明書、OIDC など、kube-apiserver サービスへのリクエストを認証するためのさまざまな戦略をサポートしています。EKS は現在、ウェブフックトークン認証サービスアカウントトークン、および 2021 年 2 月 21 日現在の OIDC 認証をネイティブにサポートしています。

ウェブフック認証戦略は、ベアラートークンを検証するウェブフックを呼び出します。EKS では、これらのベアラートークンは、kubectlコマンドの実行時に AWS CLI または aws-iam-authenticator クライアントによって生成されます。コマンドを実行すると、トークンは kube-apiserver に渡され、認証ウェブフックに転送されます。リクエストの形式が適切である場合、ウェブフックはトークンの本文に埋め込まれた署名付き URL を呼び出します。この URL はリクエストの署名を検証し、ユーザーのアカウント、Arn、UserId などのユーザーに関する情報を kube-apiserver に返します。

認証トークンを手動で生成するには、ターミナルウィンドウで次のコマンドを入力します。

aws eks get-token --cluster-name <cluster_name>

プログラムでトークンを取得することもできます。Go で書かれた例を次に示します。

package main import ( "fmt" "log" "sigs.k8s.io/aws-iam-authenticator/pkg/token" ) func main() { g, _ := token.NewGenerator(false, false) tk, err := g.Get("<cluster_name>") if err != nil { log.Fatal(err) } fmt.Println(tk) }

出力は次のようになります。

{ "kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": { "expirationTimestamp": "2020-02-19T16:08:27Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" } }

各トークンは で始まり、base64 でエンコードされた文字列k8s-aws-v1.が続きます。文字列はデコードされると、次のようなものになります。

https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393

トークンは、Amazon 認証情報と署名を含む署名付き URL で構成されます。詳細については、https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html を参照してください。

トークンの有効期間 (TTL) は 15 分です。その後、新しいトークンを生成する必要があります。これはkubectl、 などのクライアントを使用すると自動的に処理されますが、Kubernetes ダッシュボードを使用している場合は、トークンの有効期限が切れるたびに新しいトークンを生成し、再認証する必要があります。

ユーザーの ID が AWS IAM サービスによって認証されると、kube-apiserver はkube-system名前空間の aws-auth ConfigMap を読み取り、ユーザーに関連付ける RBAC グループを決定します。ConfigMap aws-auth は、IAM ユーザーとロール、Kubernetes RBAC グループなど、IAM プリンシパル間の静的マッピングを作成するために使用されます。RBAC グループは、Kubernetes RoleBindings または ClusterRoleBindings で参照できます。これらは、Kubernetes リソース (オブジェクト) のコレクションに対して実行できる一連のアクション (動詞) を定義するという点で IAM ロールに似ています。

クラスターアクセスマネージャー

Amazon EKS クラスターへの AWS IAM プリンシパルのアクセスを管理するために推奨される方法である Cluster Access Manager は、AWS API の機能であり、EKS v1.23 以降のクラスター (新規または既存) のオプトイン機能です。これにより、AWS IAM と Kubernetes RBACs 間の ID マッピングが簡素化され、AWS と Kubernetes APIsなり、アクセス管理のために aws-auth ConfigMap を編集し、運用上のオーバーヘッドを減らし、設定ミスに対処するのに役立ちます。このツールを使用すると、クラスター管理者は、クラスターの作成に使用される AWS IAM プリンシパルに自動的に付与されたcluster-adminアクセス許可を取り消したり絞り込んだりすることもできます。

この API は、次の 2 つの概念に基づいています。

  • アクセスエントリ: Amazon EKS クラスターへの認証が許可されている AWS IAM プリンシパル (ユーザーまたはロール) に直接リンクされたクラスター ID。

  • アクセスポリシー: Amazon EKS クラスターでアクションを実行するためのアクセスエントリの認可を提供する Amazon EKS 固有のポリシーです。

起動時に、Amazon EKS は事前定義された および AWS 管理ポリシーのみをサポートします。アクセスポリシーは IAM エンティティではなく、Amazon EKS によって定義および管理されます。

Cluster Access Manager では、API サーバーリクエストに関する Kubernetes AuthZ の決定に対する許可と合格 (拒否ではない) をサポートするアクセスポリシーとアップストリーム RBAC を組み合わせることができます。拒否の決定は、アップストリーム RBAC オーソライザーと Amazon EKS オーソライザーの両方がリクエスト評価の結果を判断できない場合に発生します。

この機能を使用すると、Amazon EKS は 3 つの認証モードをサポートしています。

  1. CONFIG_MAP configMap aws-auth を排他的に使用し続けるには。

  2. API_AND_CONFIG_MAP は、EKS アクセスエントリ APIsと aws-auth configMap の両方から認証された IAM プリンシパルをソースとし、アクセスエントリを優先します。アクセスエントリへの既存のアクセスaws-auth許可の移行に最適です。

  3. API は、EKS アクセスエントリ APIs。これは新しい推奨アプローチです。

開始するために、クラスター管理者は Amazon EKS クラスターを作成または更新し、優先認証を API_AND_CONFIG_MAPまたは APIメソッドに設定し、アクセスエントリを定義して、目的の AWS IAM プリンシパルへのアクセスを許可できます。

$ aws eks create-cluster \ --name <CLUSTER_NAME> \ --role-arn <CLUSTER_ROLE_ARN> \ --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \ --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false

上記のコマンドは、クラスター作成者の管理者アクセス許可なしで既に Amazon EKS クラスターを作成する例です。

update-cluster-config コマンドを使用して Amazon EKS クラスター設定を更新して API authenticationMode を有効にできます。 を使用して既存のクラスターで有効にするには、まず に更新API_AND_CONFIG_MAPしてから に更新CONFIG_MAPする必要がありますAPIこれらのオペレーションを元に戻すことはできません。つまり、 を から APIAPI_AND_CONFIG_MAPまたは に切り替えることもCONFIG_MAP、 から API_AND_CONFIG_MAPに切り替えることもできませんCONFIG_MAP

$ aws eks update-cluster-config \ --name <CLUSTER_NAME> \ --access-config authenticationMode=API

API は、クラスターへのアクセスを追加および取り消すコマンドをサポートし、指定されたクラスターの既存のアクセスポリシーとアクセスエントリを検証します。デフォルトポリシーは、次のように Kubernetes RBACs と一致するように作成されます。

EKS アクセスポリシー Kubernetes RBAC

AmazonEKSClusterAdminPolicy

クラスター管理者

AmazonEKSAdminPolicy

admin

AmazonEKSEditPolicy

edit (編集)

AmazonEKSViewPolicy

表示

$ aws eks list-access-policies { "accessPolicies": [ { "name": "AmazonEKSAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" }, { "name": "AmazonEKSClusterAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" }, { "name": "AmazonEKSEditPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" }, { "name": "AmazonEKSViewPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" } ] } $ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] }

クラスター作成者の管理者権限なしでクラスターを作成すると、アクセスエントリは使用できません。これはデフォルトで作成される唯一のエントリです。

aws-auth ConfigMap (廃止)

Kubernetes と AWS 認証を統合する方法の 1 つは、kube-system名前空間にある aws-auth ConfigMap 経由です。AWS IAM アイデンティティ (ユーザー、グループ、ロール) 認証を Kubernetes ロールベースのアクセスコントロール (RBAC) 認可にマッピングします。ConfigMap aws-auth は、プロビジョニングフェーズ中に Amazon EKS クラスターに自動的に作成されます。最初はノードがクラスターに参加できるように作成されましたが、前述のように、この ConfigMap を使用して IAM プリンシパルに RBACs アクセスを追加することもできます。

クラスターの ConfigMap aws-auth を確認するには、次のコマンドを使用できます。

kubectl -n kube-system get configmap aws-auth -o yaml

これは、ConfigMap aws-auth のデフォルト設定のサンプルです。

apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes - system:node-proxier rolearn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/kube-system-<SELF_GENERATED_UUID> username: system:node:{{SessionName}} kind: ConfigMap metadata: creationTimestamp: "2023-10-22T18:19:30Z" name: aws-auth namespace: kube-system

この ConfigMap のメインセッションは、基本的に 3 つのパラメータで構成される mapRolesブロックdataの にあります。

  • groups: IAM ロールをマッピングする Kubernetes グループ。これは、デフォルトグループでも、 または で指定されたカスタムグループclusterrolebindingでもかまいませんrolebinding。上記の例では、システムグループのみが宣言されています。

  • rolearn: 次の形式 を使用して、AWS IAM ロールの ARN を Kubernetes グループ/グループ追加にマッピングしますarn:<PARTITION>:iam::<AWS_ACCOUNT_ID>:role/role-name

  • username: AWS IAM ロールにマッピングする Kubernetes 内のユーザー名。これは任意のカスタム名にすることができます。

また、AWS IAM ユーザーのアクセス許可をマッピングし、ConfigMap の dataで の新しい設定ブロックを定義してmapUsers、ユーザーarn aws-authrolearn パラメータを置き換えることもできますが、ベストプラクティスとしてmapRoles、代わりに ユーザーに常にお勧めします。

アクセス許可を管理するには、ConfigMap aws-auth を編集して Amazon EKS クラスターへのアクセスを追加または削除します。aws-auth ConfigMap を手動で編集することは可能ですが、これは非常にセンチブな設定でありeksctl、不正確な設定は Amazon EKS クラスターの外部をロックする可能性があるため、 などのツールを使用することをお勧めします。詳細については、「」のサブセクションを参照してください。ツールを使用して、以下の aws-auth ConfigMap を変更します

クラスターアクセスに関する推奨事項

EKS クラスターエンドポイントをプライベートにする

デフォルトでは、EKS クラスターをプロビジョニングすると、API クラスターエンドポイントはパブリックに設定されます。つまり、インターネットからアクセスできます。インターネットからアクセス可能であっても、エンドポイントは引き続き安全と見なされます。これは、すべての API リクエストを IAM で認証し、Kubernetes RBAC で承認する必要があるためです。つまり、企業のセキュリティポリシーで、インターネットからの API へのアクセスを制限することが義務付けられている場合、またはクラスター VPC の外部にトラフィックをルーティングできない場合は、次のことができます。

  • EKS クラスターエンドポイントをプライベートに設定します。このトピックの詳細については、「クラスターエンドポイントアクセスの変更」を参照してください。

  • クラスターエンドポイントをパブリックのままにして、クラスターエンドポイントと通信できる CIDR ブロックを指定します。ブロックは、実質的にクラスターエンドポイントへのアクセスが許可されているパブリック IP アドレスのホワイトリストに登録されたセットです。

  • ホワイトリストに登録された CIDR ブロックのセットを使用してパブリックアクセスを設定し、プライベートエンドポイントアクセスを有効に設定します。これにより、コントロールプレーンのプロビジョニング時にクラスター VPC にプロビジョニングされるクロスアカウント ENIs を介して kubelets (ワーカー) と Kubernetes API 間のすべてのネットワークトラフィックを強制しながら、特定の範囲のパブリック IPs からのパブリックアクセスが可能になります。

認証にサービスアカウントトークンを使用しない

サービスアカウントトークンは、存続期間の長い静的認証情報です。侵害、紛失、盗難された場合、攻撃者はサービスアカウントが削除されるまで、そのトークンに関連付けられたすべてのアクションを実行できる可能性があります。CI/CD パイプラインアプリケーションなど、クラスターの外部から Kubernetes API を消費する必要があるアプリケーションには例外を付与する必要がある場合があります。このようなアプリケーションが EC2 インスタンスなどの AWS インフラストラクチャで実行されている場合は、インスタンスプロファイルを使用して Kubernetes RBAC ロールにマッピングすることを検討してください。

AWS リソースへの最小特権アクセスを採用する

IAM ユーザーは、Kubernetes API にアクセスするために AWS リソースに権限を割り当てる必要はありません。EKS クラスターへのアクセス権を IAM ユーザーに付与する必要がある場合は、特定の Kubernetes RBAC aws-auth グループにマッピングするエントリをそのユーザーの ConfigMap に作成します。

クラスター作成者プリンシパルから cluster-admin アクセス許可を削除する

デフォルトでは、Amazon EKS クラスターは、クラスター作成者プリンシパルにバインドされた永続的なcluster-adminアクセス許可で作成されます。Cluster Access Manager API では、 API_AND_CONFIG_MAP または API認証モードを使用する場合--access-config bootstrapClusterCreatorAdminPermissionsfalse、このアクセス許可なしでクラスターを作成できます。このアクセスを取り消すことは、クラスター設定への不要な変更を避けるためのベストプラクティスと考えられています。このアクセスを取り消すプロセスは、クラスターへの他のアクセスを取り消す同じプロセスに従います。

API を使用すると、IAM プリンシパルをアクセスポリシーからのみ関連付け解除できます。この場合、 ですAmazonEKSClusterAdminPolicy

$ aws eks list-associated-access-policies \ --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN> $ aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN. \ --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy

または、 アクセスcluster-admin許可に関連付けられたアクセスエントリを完全に削除します。

$ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] } $ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN>

このアクセスは、クラスターにアクセスできないインシデント、緊急、またはブレークグラスのシナリオ中に必要に応じて再度許可できます。

クラスターがCONFIG_MAP認証方法でまだ設定されている場合、追加のすべてのユーザーに ConfigMap aws-auth を介してクラスターへのアクセスを許可する必要があります。ConfigMap aws-auth を設定した後、クラスターを作成したエンティティに割り当てられたロールを削除して再作成できるのは、インシデント、緊急、またはブレークグラスシナリオが発生した場合、または ConfigMap aws-auth が破損していてクラスターにアクセスできない場合のみです。これは、本番稼働用クラスターで特に役立ちます。

複数のユーザーがクラスターへの同一のアクセスを必要とする場合の IAM ロールの使用

個々の IAM ユーザーごとにエントリを作成するのではなく、それらのユーザーが IAM ロールを引き受け、そのロールを Kubernetes RBAC グループにマッピングできるようにします。これは、特にアクセスを必要とするユーザーの数が増えるにつれて、保守が容易になります。

重要

ConfigMap によってマッピングされた IAM エンティティを使用して EKS aws-auth クラスターにアクセスする場合、記述されたユーザー名は Kubernetes 監査ログのユーザーフィールドに記録されます。IAM ロールを使用している場合、そのロールを引き受ける実際のユーザーは記録されず、監査もできません。

認証方法として configMap aws-auth を引き続き使用する場合、IAM ロールに K8s RBAC アクセス許可を割り当てるときは、ユーザー名に \{{SessionName}} を含める必要があります。これにより、監査ログにセッション名が記録されるため、実際のユーザーがこのロールを引き受けるユーザーを CloudTrail ログとともに追跡できます。

- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole username: testRole:{{SessionName}} groups: - system:masters

RoleBindings と ClusterRoleBindings の作成時に最小特権アクセスを使用する

AWS リソースへのアクセス許可の付与に関する前のポイントと同様に、RoleBindings と ClusterRoleBindings には、特定の関数の実行に必要な一連のアクセス許可のみを含める必要があります。絶対に必要でない限り、ロールと ClusterRoles ["*"]で を使用しないでください。割り当てるアクセス許可が不明な場合は、audit2rbac などのツールを使用して、Kubernetes 監査ログで観測された API コールに基づいてロールとバインドを自動的に生成することを検討してください。

自動プロセスを使用してクラスターを作成する

前のステップで説明したように、Amazon EKS クラスターを作成するときに、 API_AND_CONFIG_MAPまたは API認証モードを使用せず、クラスター作成者にアクセスcluster-admin許可を委任することをオプトアウトしない場合、クラスターを作成するフェデレーティッドユーザーなどの IAM エンティティユーザーまたはロールには、クラスターの RBAC 設定でアクセスsystem:masters許可が自動的に付与されます。このアクセス許可を削除するベストプラクティスであっても、ここで説明するように、CONFIG_MAP認証方法を使用して ConfigMap aws-auth に依存する場合、このアクセスを取り消すことはできません。したがって、専用の IAM ロールに関連付けられたインフラストラクチャ自動化パイプラインを使用してクラスターを作成し、他のユーザーやエンティティが引き受けるアクセス許可なしで、このロールのアクセス許可、ポリシー、パイプラインをトリガーするアクセス権を持つユーザーを定期的に監査することをお勧めします。また、このロールは、クラスターでルーチンアクションを実行するために使用すべきではなく、たとえば SCM コード変更を介してパイプラインによってトリガーされるクラスターレベルのアクションにのみ使用してください。

専用 IAM ロールを使用してクラスターを作成する

Amazon EKS クラスターを作成すると、クラスターを作成するフェデレーティッドユーザーなどの IAM エンティティユーザーまたはロールに、クラスターの RBAC 設定のsystem:mastersアクセス許可が自動的に付与されます。このアクセスは削除できず、ConfigMap aws-auth を通じて管理されません。したがって、専用の IAM ロールを使用してクラスターを作成し、このロールを引き受けることができるユーザーを定期的に監査することをお勧めします。このロールは、クラスターでルーチンアクションを実行するために使用しないでください。代わりに、この目的のために ConfigMap aws-auth を介してクラスターへのアクセスを追加のユーザーに許可する必要があります。ConfigMap aws-auth を設定したら、ロールを保護し、クラスターにアクセスできないシナリオの一時的な昇格特権モード/ブレークグラスでのみ使用する必要があります。これは、直接ユーザーアクセスが設定されていないクラスターで特に便利です。

クラスターへのアクセスを定期的に監査する

アクセスを必要とするユーザーは、時間の経過とともに変化する可能性があります。ConfigMap aws-auth を定期的に監査して、アクセス権が付与されたユーザーと割り当てられた権限を確認する計画を立てます。kubectl-who-canrbac-lookup などのオープンソースツールを使用して、特定のサービスアカウント、ユーザー、またはグループにバインドされたロールを調べることもできます。監査に関するセクションに進むと、このトピックをさらに詳しく説明します。その他のアイデアは、この記事の NCC グループから入手できます。

configMap aws-auth に依存する場合は、ツールを使用して変更を行います。

正しくフォーマットされていない aws-auth ConfigMap を使用すると、クラスターにアクセスできなくなる可能性があります。ConfigMap を変更する必要がある場合は、 ツールを使用します。

eksctl eksctlCLI には、aws-auth ConfigMap に ID マッピングを追加するためのコマンドが含まれています。

CLI ヘルプの表示:

$ eksctl create iamidentitymapping --help ...

Amazon EKS クラスターにマッピングされた ID を確認します。

$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION ARN USERNAME GROUPS ACCOUNT arn:aws:iam::788355785855:role/kube-system-<SELF_GENERATED_UUID> system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier

IAM ロールをクラスター管理者にする:

$ eksctl create iamidentitymapping --cluster <CLUSTER_NAME> --region=<region> --arn arn:aws:iam::123456:role/testing --group system:masters --username admin ...

詳細については、eksctlドキュメントを参照してください。

keikoproj による aws-auth

aws-auth の keikoproj には、cli と go ライブラリの両方が含まれています。

CLI ヘルプをダウンロードして表示する:

$ go get github.com/keikoproj/aws-auth ... $ aws-auth help ...

または、kubectl 用の krew プラグインマネージャーaws-authを使用して をインストールします。

$ kubectl krew install aws-auth ... $ kubectl aws-auth ...

go ライブラリなどの詳細については、GitHub の aws-auth ドキュメントを参照してください。

AWS IAM Authenticator CLI

aws-iam-authenticator プロジェクトには、ConfigMap を更新するための CLI が含まれています。

GitHub でリリースをダウンロードします。

クラスターのアクセス許可を IAM ロールに追加します。

$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config ...

認証とアクセス管理の代替アプローチ

EKS クラスターへのアクセスを必要とするユーザーを認証するには IAM が推奨されますが、認証プロキシと Kubernetes 偽装を使用して GitHub などの OIDC ID プロバイダーを使用できます。このような 2 つのソリューションの投稿は、AWS オープンソースブログで公開されています。

重要

EKS は、プロキシを使用せずに OIDC 認証をネイティブにサポートします。詳細については、起動ブログ「Amazon EKS の OIDC ID プロバイダー認証の紹介」を参照してください。さまざまな認証方法用のコネクタを備えた一般的なオープンソース OIDC プロバイダーである Dex で EKS を設定する方法の例については、「Dex & dex-k8s-authenticator を使用した Amazon EKS への認証」を参照してください。ブログで説明されているように、OIDC プロバイダーによって認証されたユーザーのユーザー名/グループが Kubernetes 監査ログに表示されます。

AWS SSO を使用して、AWS を Azure AD などの外部 ID プロバイダーとフェデレーションすることもできます。これを使用する場合、AWS CLI v2.0 には、SSO セッションを現在の CLI セッションに簡単に関連付けて IAM ロールを引き受けることができる名前付きプロファイルを作成するオプションが含まれています。ユーザーの Kubernetes RBAC グループを決定するために IAM ロールが使用されkubectlるため、 を実行する前にロールを引き受ける必要があることに注意してください。

EKS ポッドの ID と認証情報

Kubernetes クラスター内で実行される特定のアプリケーションでは、適切に機能するために Kubernetes API を呼び出すアクセス許可が必要です。たとえば、AWS Load Balancer Controller はサービスのエンドポイントを一覧表示できる必要があります。また、コントローラーは AWS APIs を呼び出して ALB をプロビジョニングおよび設定できる必要があります。このセクションでは、Pod に権限を割り当てるためのベストプラクティスについて説明します。

Kubernetes サービスアカウント

サービスアカウントは、ポッドに Kubernetes RBAC ロールを割り当てることができる特殊なタイプのオブジェクトです。デフォルトのサービスアカウントは、クラスター内の名前空間ごとに自動的に作成されます。特定のサービスアカウントを参照せずにポッドを名前空間にデプロイすると、その名前空間のデフォルトのサービスアカウントがポッドに自動的に割り当てられ、シークレット、つまりそのサービスアカウントのサービスアカウント (JWT) トークンが のボリュームとしてポッドにマウントされます/var/run/secrets/kubernetes.io/serviceaccount。そのディレクトリのサービスアカウントトークンをデコードすると、次のメタデータが表示されます。

{ "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "default", "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", "sub": "system:serviceaccount:default:default" }

デフォルトのサービスアカウントには、Kubernetes API に対する次のアクセス許可があります。

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2020-01-30T18:13:25Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "43" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery uid: 350d2ab8-438c-11ea-9438-063a49b60fba rules: - nonResourceURLs: - /api - /api/* - /apis - /apis/* - /healthz - /openapi - /openapi/* - /version - /version/ verbs: - get

このロールは、認証されていないユーザーと認証されたユーザーが API 情報を読み取ることを承認し、パブリックにアクセス可能であると安全と見なされます。

Pod 内で実行されているアプリケーションが Kubernetes APIs を呼び出す場合、それらの APIs を呼び出すアクセス許可を明示的に付与するサービスアカウントを Pod に割り当てる必要があります。ユーザーアクセスのガイドラインと同様に、サービスアカウントにバインドされたロールまたは ClusterRole は、アプリケーションが機能するために必要な API リソースとメソッドに制限する必要があります。デフォルト以外のサービスアカウントを使用するには、Pod の spec.serviceAccountNameフィールドを、使用するサービスアカウントの名前に設定します。サービスアカウントの作成の詳細については、https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions を参照してください。

注記

Kubernetes 1.24 以前は、Kubernetes はサービスアカウントごとにシークレットを自動的に作成していました。このシークレットは /var/run/secrets/kubernetes.io/serviceaccount でポッドにマウントされ、ポッドによって Kubernetes API サーバーへの認証に使用されます。Kubernetes 1.24 では、サービスアカウントトークンはポッドの実行時に動的に生成され、デフォルトでは 1 時間のみ有効です。サービスアカウントのシークレットは作成されません。Jenkins など、Kubernetes API に対して認証する必要があるクラスターの外部で実行されるアプリケーションがある場合は、 のようなサービスアカウントを参照する注釈kubernetes.io/service-account-tokenとともに、 タイプのシークレットを作成する必要がありますmetadata.annotations.kubernetes.io/service-account.name: <SERVICE_ACCOUNT_NAME>。この方法で作成されたシークレットは期限切れになりません。

サービスアカウントの IAM ロール (IRSA)

IRSA は、Kubernetes サービスアカウントに IAM ロールを割り当てることができる機能です。これは、サービスアカウントトークンボリューム射影と呼ばれる Kubernetes 機能を活用することで機能します。ポッドが IAM ロールを参照するサービスアカウントで設定されている場合、Kubernetes API サーバーは起動時にクラスターのパブリック OIDC 検出エンドポイントを呼び出します。エンドポイントは、Kubernetes によって発行された OIDC トークンと、ボリュームとしてマウントされた結果のトークンを暗号的に署名します。この署名付きトークンにより、ポッドは AWS APIs に関連付けられた IAM ロールを呼び出すことができます。AWS API が呼び出されると、AWS SDKssts:AssumeRoleWithWebIdentity。トークンの署名を検証すると、IAM は Kubernetes が発行したトークンを一時的な AWS ロール認証情報と交換します。

IRSA を使用する場合は、AWS STS への不要な呼び出しを避けるために、AWS SDK セッションを再利用することが重要です。

IRSA の (JWT) トークンをデコードすると、次のような出力が生成されます。

{ "aud": [ "sts.amazonaws.com" ], "exp": 1582306514, "iat": 1582220114, "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "kubernetes.io": { "namespace": "default", "pod": { "name": "alpine-57b5664646-rf966", "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" }, "serviceaccount": { "name": "s3-read-only", "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" } }, "nbf": 1582220114, "sub": "system:serviceaccount:default:s3-read-only" }

この特定のトークンは、IAM ロールを引き受けることで、ポッドに S3 へのビューのみの権限を付与します。アプリケーションが S3 からの読み取りを試みると、トークンは次のような一時的な IAM 認証情報のセットと交換されます。

{ "AssumedRoleUser": { "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" }, "Audience": "sts.amazonaws.com", "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oesl1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZeuE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0Hbi/PWAtlI8YJcDX69cM30JAHDdQHltm/4scFptW1hlvMaPWReCAaCrsHrATyka7ttw5YlUyvZ8EPogj6fwHlxmrXM9h1BqdikomyJU00gm1FJelfP1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkWsCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZGCkyDLIa8MBn9KPXeJd/yjTk5IifIwO/mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVCM+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } }

EKS コントロールプレーンの一部として実行される変更ウェブフックは、AWS ロール ARN とウェブ ID トークンファイルへのパスを環境変数として Pod に挿入します。これらの値を手動で指定することもできます。

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

kubelet は、合計 TTL の 80% より古い場合、または 24 時間後に、射影されたトークンを自動的にローテーションします。AWS SDKs は、ローテーション時にトークンを再ロードする責任があります。IRSA の詳細については、https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html を参照してください。

EKS Pod Identity

EKS Pod Identity は re:Invent 2023 で起動された機能で、AWS アカウント内のクラスターごとに Open Id Connect (OIDC) ID プロバイダー (IDP) を設定することなく、kubernetes サービスアカウントに IAM ロールを割り当てることができます。EKS Pod Identity を使用するには、対象となるすべてのワーカーノードで DaemonSet ポッドとして実行される エージェントをデプロイする必要があります。このエージェントは EKS アドオンとして利用でき、EKS Pod Identity 機能を使用するための前提条件です。この機能を使用するには、アプリケーションがサポートされているバージョンの AWS SDK を使用する必要があります。

EKS Pod Identity がポッド用に設定されている場合、EKS はポッド ID トークンを にマウントして更新します/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token。このトークンは、AWS SDK が EKS Pod Identity Agent と通信するために使用します。EKS Pod Identity Agent は、ポッド ID トークンとエージェントの IAM ロールを使用して、AssumeRoleForPodIdentity API を呼び出してポッドの一時的な認証情報を作成します。ポッドに配信されるポッド ID トークンは、EKS クラスターから発行され、暗号化によって署名された JWT であり、EKS Pod ID で使用するための適切な JWT クレームがあります。

EKS Pod Identity の詳細については、このブログを参照してください。

EKS Pod ID を使用するには、アプリケーションコードを変更する必要はありません。サポートされている AWS SDK バージョンでは、認証情報プロバイダーチェーンを使用して、EKS Pod Identity で使用できる認証情報が自動的に検出されます。IRSA と同様に、EKS ポッド ID はポッド内の変数を設定して、AWS 認証情報の検索方法を指示します。

EKS Pod ID の IAM ロールの使用

  • EKS Pod Identity は、EKS クラスターと同じ AWS アカウントに属する IAM ロールのみを直接引き受けることができます。別の AWS アカウントの IAM ロールにアクセスするには、SDK 設定またはアプリケーションのコードでプロファイルを設定して、そのロールを引き受ける必要があります。 https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html

  • EKS Pod Identity がサービスアカウントに設定されている場合、Pod Identity Association を設定するユーザーまたはプロセスには、そのロールのiam:PassRoleエンタイトルメントが必要です。

  • 各サービスアカウントには、EKS Pod ID を介して関連付けられる IAM ロールが 1 つだけありますが、同じ IAM ロールを複数のサービスアカウントに関連付けることができます。

  • EKS Pod Identity で使用される IAM ロールは、pods.eks.amazonaws.comサービスプリンシパルがそれらを引き受け、セッションタグを設定できるようにする必要があります。以下は、EKS Pod ID に IAM ロールの使用を許可するロール信頼ポリシーの例です。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ], "Condition": { "StringEquals": { "aws:SourceOrgId": "${aws:ResourceOrgId}" } } } ] }

AWS ではaws:SourceOrgId、 のような条件キーを使用して、サービス間の混乱した代理問題から保護することをお勧めします。上記のロール信頼ポリシーの例では、 ResourceOrgIdは、AWS アカウントが属する AWS Organizations の AWS Organizations Organization ID と等しい変数です。EKS は、EKS Pod ID でロールを引き受けるときに、 とaws:SourceOrgId等しい の値を渡します。

ABAC および EKS ポッド ID

EKS Pod Identity が IAM ロールを引き受けると、次のセッションタグが設定されます。

EKS ポッドアイデンティティセッションタグ

kubernetes-namespace

EKS Pod ID に関連付けられたポッドが実行される名前空間。

kubernetes-service-account

EKS Pod ID に関連付けられた kubernetes サービスアカウントの名前

eks-cluster-arn

EKS クラスターの ARN。例: arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}。クラスター ARN は一意ですが、クラスターが削除され、同じ AWS アカウント内で同じ名前の同じリージョンで再作成されると、同じ ARN になります。

eks-cluster-name

EKS クラスターの名前。EKS クラスター名は、AWS アカウント内、および他の AWS アカウントの EKS クラスター内で同じにできることに注意してください。

kubernetes-pod-name

EKS のポッドの名前。

kubernetes-pod-uid

EKS のポッドの UID。

これらのセッションタグを使用すると、属性ベースのアクセスコントロール (ABAC) を使用して、特定の kubernetes サービスアカウントにのみ AWS リソースへのアクセスを許可できます。その場合、kubernetes サービスアカウントは名前空間内でのみ一意であり、kubernetes 名前空間は EKS クラスター内でのみ一意であることを理解することが重要です。これらのセッションタグは、 などのaws:PrincipalTag/<tag-key>グローバル条件キーを使用して AWS ポリシーでアクセスできます。 aws:PrincipalTag/eks-cluster-arn

例えば、IAM またはリソースポリシーを使用してアカウント内の AWS リソースにアクセスするためのアクセスを特定のサービスアカウントのみに付与する場合は、 eks-cluster-arn および kubernetes-namespace タグと をチェックして、目的のクラスターのサービスアカウントのみがそのリソースにアクセスできるkubernetes-service-accountことを確認する必要があります。他のクラスターは kubernetes-service-accountsと を同じにすることができますkubernetes-namespaces

この S3 バケットポリシーの例では、kubernetes-service-account、、 kubernetes-namespace eks-cluster-arn が EKS クラスターが AWS アカウント でホストされている想定値を満たしている場合にのみ、アタッチされている S3 バケット内のオブジェクトへのアクセスを許可します111122223333

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::ExampleBucket/*" ], "Condition": { "StringEquals": { "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" } } } ] }

IRSA と比較した EKS Pod ID

EKS ポッドに一時的な AWS 認証情報を配信するには、EKS ポッド ID と IRSA の両方をお勧めします。IRSA の特定のユースケースがない限り、EKS を使用するときは EKS Pod ID を使用することをお勧めします。この表は、2 つの機能を比較するのに役立ちます。

# EKS Pod Identity IRSA

AWS アカウントに OIDC IDP を作成するアクセス許可が必要ですか?

いいえ

はい

クラスターごとに一意の IDP 設定が必要です

いいえ

はい

ABAC で使用する関連セッションタグを設定します

はい

いいえ

iam:PassRole チェックが必要ですか?

はい

いいえ

AWS アカウントの AWS STS Quota を使用しますか?

いいえ

はい

他の AWS アカウントにアクセスできる

ロールの連鎖による間接的な

sts:AssumeRoleWithWebIdentity で直接

AWS SDKs との互換性

はい

はい

ノードに Pod Identity Agent デーモンセットが必要ですか?

はい

いいえ

EKS ポッドの推奨事項のアイデンティティと認証情報

IRSA を使用するように aws-node デーモンセットを更新する

現在、aws-node デーモンセットは、EC2 インスタンスに割り当てられたロールを使用してポッドに IPs を割り当てるように設定されています。このロールには、AmazonEKS_CNI_Policy や EC2ContainerRegistryReadOnly など、複数の AWS 管理ポリシーが含まれており、ノードで実行されているすべてのポッドが ENIs、IP アドレスの割り当て/割り当て解除、または ECR からのイメージのプルを効果的に許可します。これはクラスターにリスクをもたらすため、IRSA を使用するように aws-node デーモンセットを更新することをお勧めします。これを行うためのスクリプトは、このガイドの リポジトリにあります。

aws-node デーモンセットは、バージョン v1.15.5 以降の EKS Pod ID をサポートしています。

ワーカーノードに割り当てられたインスタンスプロファイルへのアクセスを制限する

IRSA または EKS Pod ID を使用すると、最初に IRSA または EKS Pod ID を使用するようにポッドの認証情報チェーンが更新されますが、ポッドはワーカーノードに割り当てられたインスタンスプロファイルの権限を継承できます。これらのアクセス許可を必要としないポッドの場合、インスタンスメタデータへのアクセスをブロックして、アプリケーションに必要なアクセス許可のみを持ち、ノードを持たないようにすることができます。

警告

インスタンスメタデータへのアクセスをブロックすると、IRSA または EKS Pod ID を使用しないポッドがワーカーノードに割り当てられたロールを継承できなくなります。

以下の例のように、インスタンスに IMDSv2 のみの使用を要求し、ホップ数を 1 に更新することで、インスタンスメタデータへのアクセスをブロックできます。これらの設定をノードグループの起動テンプレートに含めることもできます。インスタンスメタデータを無効にしないでください。これにより、ノード終了ハンドラーなどのコンポーネントや、インスタンスメタデータに依存する他のモノが正しく動作しなくなります。

$ aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1 ...

Terraform を使用して Managed Node Groups で使用する起動テンプレートを作成する場合は、メタデータブロックを追加して、次のコードスニペットに示すようにホップ数を設定します。

tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" …​ metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } …​

ノードで iptables を操作することで、EC2 メタデータへのポッドのアクセスをブロックすることもできます。この方法の詳細については、「インスタンスメタデータサービスへのアクセスの制限」を参照してください。

IRSA または EKS Pod ID をサポートしていない古いバージョンの AWS SDK を使用しているアプリケーションがある場合は、SDK バージョンを更新する必要があります。

IRSA ロールの IAM ロール信頼ポリシーをサービスアカウント名、名前空間、クラスターにスコープする

信頼ポリシーの範囲は、名前空間または名前空間内の特定のサービスアカウントに限定できます。IRSA を使用する場合は、サービスアカウント名を含めて、ロールの信頼ポリシーをできるだけ明確にすることをお勧めします。これにより、同じ名前空間内の他のポッドがロールを引き受けるのを効果的に防ぐことができます。これを使用してサービスアカウント/IAM ロールを作成すると、CLI eksctlは自動的にこれを行います。詳細については、https://eksctl.io/usage/iamserviceaccounts/ を参照してください。

IAM を直接使用すると、条件を使用して:subクレームが想定する名前空間とサービスアカウントであることを確認する条件がロールの信頼ポリシーに追加されます。例えば、「system:serviceaccount:default:s3-read-only」というサブクレームを持つ IRSA トークンがある前は、これはdefault名前空間で、サービスアカウントは ですs3-read-only。クラスターの特定の名前空間内のサービスアカウントのみがそのロールを引き受けられるようにするには、次のような条件を使用します。

"Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" } }

アプリケーションごとに 1 つの IAM ロールを使用する

IRSA と EKS Pod Identity の両方を使用する場合、各アプリケーションに独自の IAM ロールを付与するのがベストプラクティスです。これにより、別のアプリケーションに影響を与えることなく 1 つのアプリケーションを変更できるため、分離が改善され、必要なアクセス許可のみをアプリケーションに付与することで、最小特権のプリンシパルを適用できます。

EKS Pod Identity で ABAC を使用する場合、複数のサービスアカウントで共通の IAM ロールを使用し、それらのセッション属性を使用してアクセス制御を行うことができます。これは、ABAC ではより少ない IAM ロールで運用できるため、大規模に運用する場合に特に便利です。

アプリケーションが IMDS にアクセスする必要がある場合は、IMDSv2 を使用し、EC2 インスタンスのホップ制限を 2 に引き上げます。

IMDSv2 では、PUT リクエストを使用してセッショントークンを取得する必要があります。最初の PUT リクエストには、セッショントークンの TTL を含める必要があります。AWS SDKs の新しいバージョンでは、これとトークンの更新が自動的に処理されます。また、IP 転送を防ぐために、EC2 インスタンスのデフォルトのホップ制限が意図的に 1 に設定されていることに注意してください。その結果、EC2 インスタンスで実行されるセッショントークンをリクエストするポッドは、最終的にタイムアウトし、IMDSv1 データフローの使用にフォールバックする可能性があります。EKS は、v1 と v2 の両方を有効にし、eksctl によってプロビジョニングされたノードまたは公式の CloudFormation テンプレートを使用してホップ制限を 2 に変更することで、IMDSv2 のサポートを追加します。 CloudFormation

サービスアカウントトークンの自動マウントを無効にする

アプリケーションが Kubernetes API を呼び出す必要がない場合は、アプリケーションの PodSpec falseautomountServiceAccountToken 属性を に設定するか、各名前空間のデフォルトのサービスアカウントにパッチを適用して、ポッドに自動的にマウントされなくなります。例:

kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'

アプリケーションごとに専用サービスアカウントを使用する

各アプリケーションには、独自の専用サービスアカウントが必要です。これは、Kubernetes API のサービスアカウントと IRSA および EKS Pod Identity に適用されます。

重要

IRSA の使用時にインプレースクラスターアップグレードを実行する代わりに、クラスターのアップグレードにブルー/グリーンアプローチを採用する場合は、新しいクラスターの OIDC エンドポイントを使用して、各 IRSA IAM ロールの信頼ポリシーを更新する必要があります。ブルー/グリーンクラスターのアップグレードでは、古いクラスターとともに新しいバージョンの Kubernetes を実行するクラスターを作成し、ロードバランサーまたはサービスメッシュを使用して、古いクラスターで実行されているサービスから新しいクラスターにトラフィックをシームレスに移行します。EKS Pod Identity で Blue/Green クラスターのアップグレードを使用する場合は、新しいクラスター内の IAM ロールとサービスアカウントの間にポッド ID の関連付けを作成します。sourceArn 条件がある場合は、IAM ロールの信頼ポリシーを更新します。

ルート以外のユーザーとしてアプリケーションを実行する

デフォルトでは、コンテナは root として実行されます。これにより、ウェブ ID トークンファイルを読み取ることができますが、コンテナをルートとして実行することはベストプラクティスとは見なされません。別の方法として、 spec.securityContext.runAsUser 属性を PodSpec に追加することを検討してください。の値は任意の値runAsUserです。

次の例では、Pod 内のすべてのプロセスは、 runAsUserフィールドで指定されたユーザー ID で実行されます。

apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ]

コンテナを非ルートユーザーとして実行すると、トークンにはデフォルトで 0600 [ルート] アクセス許可が割り当てられるため、コンテナが IRSA サービスアカウントトークンを読み取ることができなくなります。コンテナの securityContext を更新して fsgroup=65534 [Nobody] を含めると、コンテナはトークンを読み取ることができます。

spec: securityContext: fsGroup: 65534

Kubernetes 1.19 以降では、この変更は不要になり、アプリケーションは Nobody グループに追加せずに IRSA サービスアカウントトークンを読み取ることができます。

アプリケーションへの最小特権アクセスを付与する

Action Hero は、アプリケーションと一緒に実行して、アプリケーションが正しく機能するために必要な AWS API コールと対応する IAM アクセス許可を識別できるユーティリティです。これは、アプリケーションに割り当てられた IAM ロールの範囲を徐々に制限するのに役立つという点で、IAM Access Advisor に似ています。詳細については、AWS リソースへの最小特権アクセスの付与に関するドキュメントを参照してください。

IRSA および Pod ID で使用される IAM ロールに対するアクセス許可の境界を設定することを検討してください。アクセス許可の境界を使用して、IRSA または Pod ID で使用されるロールがアクセス許可の最大レベルを超えないようにすることができます。アクセス許可の境界ポリシーの例を使用してアクセス許可の境界を開始する方法の例については、この github リポジトリを参照してください。

EKS クラスターへの不要な匿名アクセスを確認して取り消す

理想的には、すべての API アクションで匿名アクセスを無効にする必要があります。匿名アクセスは、Kubernetes 組み込みユーザーシステムの RoleBinding または ClusterRoleBinding:anonymous を作成することによって付与されます。rbac-lookup ツールを使用して、system:anonymous ユーザーがクラスターに対して持っているアクセス許可を特定できます。

./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' system:anonymous cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer

system:public-info-viewer 以外のロールまたは ClusterRole は、system:anonymous user または system:unauthenticated グループにバインドしないでください。

特定の APIs で匿名アクセスを有効にするには、いくつかの正当な理由が考えられます。クラスターの場合、匿名ユーザーがこれらの特定の APIs のみにアクセスでき、認証なしでこれらの APIs を公開しても、クラスターが脆弱になることはありません。

Kubernetes/EKS バージョン 1.14 以前は、system:unauthenticated グループはデフォルトで system:discovery および system:basic-user ClusterRoles に関連付けられていました。クラスターをバージョン 1.14 以降に更新した場合でも、クラスターの更新によってこれらのアクセス許可が取り消されないため、これらのアクセス許可はクラスターで引き続き有効になる可能性があることに注意してください。system:public-info-viewer を除く「system:unauthenticated」を持つ ClusterRoles を確認するには、次のコマンドを実行します (jq util が必要です)。

kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name'

また、「system:unauthenticated」は、以下を使用して「system:public-info-viewer」を除くすべてのロールから削除できます。

kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f -

または、kubectl describe と kubectl edit を使用して手動でチェックおよび削除することもできます。system:unauthenticated グループにクラスターに対する system:discovery アクセス許可があるかどうかを確認するには、次のコマンドを実行します。

kubectl describe clusterrolebindings system:discovery Name: system:discovery Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:discovery Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated

system:unauthenticated グループにクラスターに対する system:basic-user アクセス許可があるかどうかを確認するには、次のコマンドを実行します。

kubectl describe clusterrolebindings system:basic-user Name: system:basic-user Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:basic-user Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated

system:unauthenticated グループがクラスターの system:discovery および/または system:basic-user ClusterRoles にバインドされている場合は、system:unauthenticated グループからこれらのロールの関連付けを解除する必要があります。次のコマンドを使用して、system:discovery ClusterRoleBinding を編集します。

kubectl edit clusterrolebindings system:discovery

上記のコマンドは、以下に示すように、エディタで system:discovery ClusterRoleBinding の現在の定義を開きます。

# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2021-06-17T20:50:49Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "24502985" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery uid: b7936268-5043-431a-a0e1-171a423abeb6 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:discovery subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:authenticated - apiGroup: rbac.authorization.k8s.io kind: Group name: system:unauthenticated

上記のエディタ画面の「件名」セクションから system:unauthenticated グループのエントリを削除します。

system:basic-user ClusterRoleBinding に対して同じ手順を繰り返します。

IRSA で AWS SDK セッションを再利用する

IRSA を使用する場合、AWS SDK を使用して記述されたアプリケーションは、ポッドに配信されたトークンを使用して を呼び出しsts:AssumeRoleWithWebIdentity、一時的な AWS 認証情報を生成します。これは、コンピューティングサービスが一時的な AWS 認証情報を Lambda 関数などの AWS コンピューティングリソースに直接配信する他の AWS コンピューティングサービスとは異なります。つまり、AWS SDK セッションが初期化されるたびに、 の AWS STS への呼び出しAssumeRoleWithWebIdentityが行われます。アプリケーションが急速にスケールし、多くの AWS SDK セッションを初期化する場合、コードが を何度も呼び出すため、AWS STS からのスロットリングが発生する可能性がありますAssumeRoleWithWebIdentity

このシナリオを回避するには、 への不要な呼び出しが行われAssumeRoleWithWebIdentityないように、アプリケーション内で AWS SDK セッションを再利用することをお勧めします。

次のコード例では、boto3 Python SDK を使用してセッションが作成され、同じセッションを使用してクライアントを作成し、Amazon S3 と Amazon SQS の両方とやり取りします。 AssumeRoleWithWebIdentityは 1 回だけ呼び出され、AWS SDK は有効期限が切れmy_sessionると の認証情報を自動的に更新します。

import boto3 = Create your own session my_session = boto3.session.Session() = Now we can create low-level clients from our session sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') s3response = s3.list_buckets() sqsresponse = sqs.list_queues() #print the response from the S3 and SQS APIs print("`s3 response:`") print(s3response) print("`—`") print("`sqs response:`") print(sqsresponse) ```

EC2 などの別の AWS コンピューティングサービスから IRSA を使用する EKS にアプリケーションを移行する場合、これは特に重要な詳細です。AWS SDK セッションを初期化する他のコンピューティングサービスでは、指示がない限り、AWS STS は呼び出されません。

代替アプローチ

IRSA および EKS Pod Identity はポッドに AWS ID を割り当てるための推奨方法ですが、アプリケーションに最新バージョンの AWS SDKs を含める必要があります。現在 IRSA をサポートしている SDKs の完全なリストについては、https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html を参照してください。EKS Pod ID については、https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html を参照してください。互換性のある SDK ですぐに更新できないアプリケーションがある場合は、kube2iamkiam など、Kubernetes ポッドに IAM ロールを割り当てるためのコミュニティ構築のソリューションがいくつかあります。AWS はこれらのソリューションの使用を推奨、容認、サポートしていませんが、IRSA や EKS Pod ID と同様の結果を得るためにコミュニティ全体で頻繁に使用されています。

これらの aws 提供以外のソリューションのいずれかを使用する必要がある場合は、デューデリジェンスを行い、そのために生じるセキュリティ上の影響を理解していることを確認してください。

ツールとリソース