翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
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 は現在、ウェブフックトークン認証
ウェブフック認証戦略は、ベアラートークンを検証するウェブフックを呼び出します。EKS では、これらのベアラートークンは、kubectl
コマンドの実行時に AWS CLI または aws-iam-authenticator
認証トークンを手動で生成するには、ターミナルウィンドウで次のコマンドを入力します。
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 つの認証モードをサポートしています。
-
CONFIG_MAP
configMapaws-auth
を排他的に使用し続けるには。 -
API_AND_CONFIG_MAP
は、EKS アクセスエントリ APIsとaws-auth
configMap の両方から認証された IAM プリンシパルをソースとし、アクセスエントリを優先します。アクセスエントリへの既存のアクセスaws-auth
許可の移行に最適です。 -
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
。これらのオペレーションを元に戻すことはできません。つまり、 を から API
API_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-auth
の rolearn パラメータを置き換えることもできますが、ベストプラクティスとして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 bootstrapClusterCreatorAdminPermissions
false
、このアクセス許可なしでクラスターを作成できます。このアクセスを取り消すことは、クラスター設定への不要な変更を避けるためのベストプラクティスと考えられています。このアクセスを取り消すプロセスは、クラスターへの他のアクセスを取り消す同じプロセスに従います。
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
自動プロセスを使用してクラスターを作成する
前のステップで説明したように、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-can
configMap aws-auth
に依存する場合は、ツールを使用して変更を行います。
正しくフォーマットされていない aws-auth ConfigMap を使用すると、クラスターにアクセスできなくなる可能性があります。ConfigMap を変更する必要がある場合は、 ツールを使用します。
eksctl eksctl
CLI には、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
プロジェクトには、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 偽装
重要
EKS は、プロキシを使用せずに OIDC 認証をネイティブにサポートします。詳細については、起動ブログ「Amazon EKS の OIDC ID プロバイダー認証の紹介
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
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 ロールを割り当てることができる機能です。これは、サービスアカウントトークンボリューム射影sts: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。例: |
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 false
で automountServiceAccountToken
属性を に設定するか、各名前空間のデフォルトのサービスアカウントにパッチを適用して、ポッドに自動的にマウントされなくなります。例:
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
IRSA および Pod ID で使用される IAM ロールに対するアクセス許可の境界を設定することを検討してください。アクセス許可の境界を使用して、IRSA または Pod ID で使用されるロールがアクセス許可の最大レベルを超えないようにすることができます。アクセス許可の境界ポリシーの例を使用してアクセス許可の境界を開始する方法の例については、この github リポジトリ
EKS クラスターへの不要な匿名アクセスを確認して取り消す
理想的には、すべての API アクションで匿名アクセスを無効にする必要があります。匿名アクセスは、Kubernetes 組み込みユーザーシステムの RoleBinding または ClusterRoleBinding:anonymous を作成することによって付与されます。rbac-lookup
./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 ですぐに更新できないアプリケーションがある場合は、kube2iam
これらの aws 提供以外のソリューションのいずれかを使用する必要がある場合は、デューデリジェンスを行い、そのために生じるセキュリティ上の影響を理解していることを確認してください。