EKS上でシステムを動かす上で、AWS上のサービスと一切連携しないということは、まず無いでしょう。
当然ですが、Kubernetesの世界ではPodに対して、AWS IAMを直接設定する機能はありません。
Podと権限をひもづけする Service Account
に対して、
なんらかの仕組みを用いて、 Service Account
と IAMロール
を結びつけてあげる必要があります。
これまでは IAM Roles for Service Account (IRSA) がそのための機能として提供されてきました。
そして、Re:Invent 2023で新しい仕組みとして Pod Identity が導入されました。
https://aws.amazon.com/about-aws/whats-new/2023/11/amazon-eks-pod-identity/
今回は、なぜPod Identityが新しく導入されたのか、実際の使い方や使いどころについて考察します。
IRSAとPod Identityの利用方法
まずは、それぞれ利用するためにどのように設定するのかを紹介します。
いろいろな手段がありますが、今回はマネージメントコンソール(+kubectlコマンド)で設定したいと思います。 マネコンの場合、一部冗長な作業も増えますので、aws cliを使う方がシンプルかと思います。
IRSAの利用方法
基本的な手順はドキュメントにあるので、詳細な内容は公式のドキュメントを参照してください。
https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html
EKSクラスタを作成したら、IAMの
IDプロバイダ
に追加します。IAMロールを作成する。マネコンから作成するときは、 「信頼されたエンティティタイプ」には、「ウェブアイデンティティ」を選択し、先ほど追加したOIDCのIDプロバイダを選択します。
必要なIAMポリシーをアタッチしたら、一度、IAMロールを作成を完了します。
作成後、再度作成したIAMロールの「信頼ポリシー」を編集し、subjectを追加します。
追加する行は、
"<IDプロバイダ>:sub": "system:serviceaccount:<Namespace名>:<ServiceAccount名>"
とします。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::012345678901:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/3AA037B32A34BC710A0AC2F76BD1CE05" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.us-east-1.amazonaws.com/id/3AA037B32A34BC710A0AC2F76BD1CE05:aud": "sts.amazonaws.com", "oidc.eks.us-east-1.amazonaws.com/id/3AA037B32A34BC710A0AC2F76BD1CE05:sub": "system:serviceaccount:default:s3-full" } } } ] }
この例では、
Condition
をStringEquals
としているので、完全一致である必要がありますが、StringLike
を使ってワイルドカードを使うこともできます。また、このとき作成したIAMロールのARNをメモしておきます。
Kubernetesの世界に入ります。以下のコマンドを実行して、先ほどIAMロールを作成するときに指定したのと同じ名前のServiceAccountを作成し、IAMロールとひもづけられるようにARNをアノテーションに追加します。
$ kubectl create serviceaccount s3-full $ kubectl annotate sa s3-full eks.amazonaws.com/role-arn=<メモっておいたARN>
最後にPodに作成したServiceAccountを利用するように設定すれば完成です。
apiVersion: v1 kind: Pod metadata: name: pod-1 spec: containers: - image: amazonlinux name: amazonlinux command: ["sh", "-c", "sleep 3600"] serviceAccountName: s3-full
Pod Identityの利用方法
こちらも、基本的な手順はドキュメントにあります。
https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html
Pod Identityのアドオンを追加します。今はEKSクラスタ作成時にアドオン追加にデフォルトでチェックが入っているようです。
もちろん、あとから追加することも可能です。
ワーカーノードのロールのポリシーに
"eks-auth:AssumeRoleForPodIdentity"
のアクションを加えます。 AWS管理ポリシーであるAmazonEKSWorkerNodePolicy
を利用している場合には、特別な対処は不要です。管理ポリシーの履歴を見てみると、2023/11/27に当該アクションが追加されていました。Pod Identityの機能が発表されてから、すぐに追加されたようです。
$ aws iam get-policy-version --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy --version-id v3 { "PolicyVersion": { "Document": { "Version": "2012-10-17", "Statement": [ { "Sid": "WorkerNodePermissions", "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:DescribeInstanceTypes", "ec2:DescribeRouteTables", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVolumes", "ec2:DescribeVolumesModifications", "ec2:DescribeVpcs", "eks:DescribeCluster", "eks-auth:AssumeRoleForPodIdentity" ], "Resource": "*" } ] }, "VersionId": "v3", "IsDefaultVersion": true, "CreateDate": "2023-11-27T00:06:13+00:00" } }
ServiceAccountとひもづけたいIAMロールを作成する。 ドキュメントにはいろいろと書いてありますが、マネコンから操作する場合はAWSのサービスのユースケースに
EKS - Pod Identity
というのが、すでに用意されているのでこれを選んで必要な権限のポリシーをアタッチするだけです。マネコンのEKSの設定から 「アクセス」タブの「Pod Identityの関連付け」から関連付けを作成します。
- 先ほど作成したIAMロール
- ServiceAccountの存在するNamespace
- ServiceAccount名
を指定します。
先ほど指定したServiceAccountを実際に作ります。IRSAと違ってAnnotationの付与は不要です。
$ kubectl create serviceaccount s3-full
PodにServiceAccountを割り当てれば完了です(yamlのサンプルはIRSAと同じです)
Pod Identityの使いどころ
実際にそれぞれを改めて設定してみて、基本的に後述する注意点を除けば、Pod Identityを使ったほうがよいと感じました。
IRSAの場合、クラスタやServiceAccountの情報をIAMロールの設定の中に記載する必要があります。 ある程度の規模のシステムの場合、権限分掌がされてて、IAMを設定できる人とEKSを設定できる人は異なると思います。 その場合、EKSで開発している人は頻繁にIAMを設定できる人に設定変更をしてもらわないといけません。 プロジェクトによってはIAMの設定はヒアリングシートを提出して5営業日後に反映される、なんてケースもあるのではないでしょうか?
クラスタごとにというのも厄介で、クラスタのバージョンアップをする際、もちろんインプレースでバージョンアップするプロジェクトも多いと思いますが、安全のため新しいバージョンのクラスタを用意して、クラスタごとB/Gで切り換えるという手段をとるプロジェクトもあるでしょう。
この場合、IAMの設定もクラスタ固有情報が含まれているため、 新しいクラスタのOIDCプロバイダURLを参照するように一式切り替えないといけません。 頻繁にアップデートが必要なKubernetesの運用において、これは大きな負荷ですし、何より事故のもとです。
それに対して、Pod Identityであれば、IAM側にはEKSの情報は基本的には含まれないため、 作成されたIAMロールを使いまわせるのであればEKSに閉じて完結させることができます。
これだけ見ると、強い権限のIAMロールが意図しないところで好き勝手に使い回されるリスクがあるのではないか、と心配になりますが、安心してください。
EKS Pod Identityはクラスタ名やServiceAccount名などの属性タグを認証時に付与するため、 それを用いてフィルタリングすることができます。
例えば、以下のようなIAMポリシーにすることで s3-full
という名前のServiceAccountにだけ権限を付与し、
それ以外の名前のServiceAccountについては、例えPod Identity側でひもづけを追加したとしても権限は付与しないといった制御をすることができます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/kubernetes-service-account": "s3-full"
}
}
}
]
}
これを活用することで、一般的に利用されるような権限はあらかじめIAMロールを用意しておき自由に使ってもらう。 特殊な権限が必要な場合には、クラスタ、Namespace、ServiceAccountを絞って権限を与えるといった、 ある程度自由を与えつつ、ガバナンスが必要なところはしめる、という制御が可能です。
利用できるタグの詳細は以下のドキュメントを参照してください。
https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html
Pod Identityの注意点
残念ながら、Pod Identityは Fargateには対応していないようです。 また、以前活用した Mountpoint for Amazon S3 CSI driverなどアドオンは対応していないものがあるようです。
これらは引き続きIRSAを利用するとして、使えるところはPod Identityに置き換えていくのがよいと思います。
まとめ
今回は、Re:Invent2023で導入された Pod Identityについて使い方や既存のIRSAとの違いについて紹介しました。
使ってみて、これまでのつらかったところが一気によくなった機能アップデートだと思いますので、是非使ってみてはいかがでしょうか。
Share