こんにちは、クラウド事業部の山路です。
今回は昨年11月にリリースされたEKS Pod Identityの紹介です。
EKS Pod Identityとは
EKS Pod Identityは、IAM Role for Service Account (IRSA) と同様、Podに対してAWS IAM権限を付与し、Pod内のコンテナがAWSリソースにアクセスする権限を付与する機能です。
IRSAと比較したとき、Pod Identityには以下のような特徴があります。
- AWSに閉じた権限管理: IRSAを利用するには、OIDC ID プロバイダーの作成が必要で、これはKubernetes クラスターの管理とは別のチームの責任になることもあります。一方でEKS Pod Identityの設定はすべてEKSで行われ、IAM権限の設定もすべてIAMで行われます。
- 1つのIAMロールを複数のEKSクラスターで共有できる: IRSAではEKSクラスターごとに個別のプリンシパルが必要となるので、クラスター専用のIAMロールが必要です。一方でEKS Pod Identityは単一の IAM プリンシパルを使用し、複数のクラスターでIAMロールを共用できます。
- スケーラビリティの向上: EKS Pod IdentityはEKS Pod Identity AgentというDaemonSetを利用します。これにより認証上の発行といった処理はNodeごとに1回で済むようになったようです。
なおEKS Pod Identityの仕組みは以下のように図示されています。
※AWS公式ブログより
検証
ここではPod Identityの利用方法を簡単にさらっていきます。
前提条件
Pod Identityを利用するにはいくつかの条件があります。
- EKS ver 1.24以上、かつ一定のPlatform version以上であること
- データプレーンはEC2 (Linux) を使っている
- EKS Add-onとして、IAM認証情報を利用する以下のアドオンではPod Identityを利用できません。
- Amazon VPC CNI plugin for Kubernetes
- AWS Load Balancer Controller
- CSI ストレージドライバー
- クラスター内の各Service Accountには、1つのIAM ロールを関連付けることができます。
- EKS Pod Identity Agentは
hostNetwork
を使用し、Node上のリンクローカルアドレス上の169.254.170.23
(IPv4アドレス) 、80
/2703
ポートを使用します。
IAMロールの作成
Pod中のコンテナが使用するIAMロールを用意します。今回はS3へのアクセス権限を付与するため、以下のファイルを使いました。
iam-for-pod-identity.yaml
AWSTemplateFormatVersion: '2010-09-09' Resources: IAMRoleForPodIdentityTest: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - pods.eks.amazonaws.com Action: - sts:AssumeRole - sts:TagSession Path: / Policies: - PolicyName: iam-policy-for-pod-identity-test PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: s3:ListAllMyBuckets Resource: '*' RoleName: iam-role-for-pod-identity-test
Pod Identity Agentのインストール
次にPod Identity AgentをEKSクラスターにインストールします。AgentのインストールはAWSマネジメントコンソールからも可能ですが、今回は以下のCloudFormationファイルを使いました。
addon.yaml
AWSTemplateFormatVersion: "2010-09-09" Resources: AddonForPodIdentity: Type: AWS::EKS::Addon Properties: AddonName: "eks-pod-identity-agent" AddonVersion: "v1.0.0-eksbuild.1" ClusterName: "eks-cluster"
Agentインストール後はEKS上でPodとして確認できます。
[cloudshell-user@ip-10-132-76-136 ~]$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system aws-node-4xg2n 2/2 Running 0 13m kube-system aws-node-sqr4t 2/2 Running 0 13m kube-system coredns-58c6c4f5db-75878 1/1 Running 0 17m kube-system coredns-58c6c4f5db-v7xpt 1/1 Running 0 17m kube-system eks-pod-identity-agent-5g9rq 1/1 Running 0 6m35s kube-system eks-pod-identity-agent-jkgfs 1/1 Running 0 6m35s kube-system kube-proxy-df7dg 1/1 Running 0 13m kube-system kube-proxy-zqxpq 1/1 Running 0 13m
Service Account / Pod Identity Agentとの連携
Pod Identity Agentをインストールしたので、Podへの権限付与に利用するService Accountの作成、及びPod Identity Associationを設定します。なお少し試したところ、この2つのリソースはどちらを先に作成しても良いようですが、前段で作成したIAMロールが存在しない場合はエラーとなりました。
Service Account / Pod Identity Associationはそれぞれ以下のファイルで作成しました。
serviceaccount.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: pod-identity-test namespace: default
podidentityassociation.yaml
AWSTemplateFormatVersion: "2010-09-09" Resources: PodIdentityAssociation: Type: AWS::EKS::PodIdentityAssociation Properties: ClusterName: "eks-cluster" Namespace: "default" RoleArn: "arn:aws:iam::<AWS Account ID>:role/iam-role-for-pod-identity-test" ServiceAccount: "pod-identity-test"
Podの作成
Pod Identityを利用する準備は整ったので、試しにAWS CLIイメージを使ってS3にアクセスできるかをチェックします。
以下のようにService Accountを指定してPodを作成すると、 aws s3 ls
コマンドを使ってS3の一覧を取得できることを確認できます。
[cloudshell-user@ip-10-132-76-136 ~]$ kubectl run -n default --rm -it pod-identity-test --image=public.ecr.aws/aws-cli/aws-cli:2.15.3 --overrides='{ "spec": { "serviceAccount": "pod-identity-test" } }' -- s3 ls If you don't see a command prompt, try pressing enter. 2023-03-26 01:36:30 alb-unit-test-handler-20230326 2023-10-14 06:37:18 athena-output-20231014 <割愛> 2023-04-26 06:41:16 test-202304261541
Service Accountを指定しない、あるいは s3:ListAllMyBuckets
以外の操作をするとエラーが発生することも確認できます。
[cloudshell-user@ip-10-132-76-136 ~]$ kubectl run -n default --rm -it pod-identity-test --image=public.ecr.aws/aws-cli/aws-cli:2.15.3 --overrides='{ "spec": { "serviceAccount": "pod-identity-test" } }' -- s3 ls test-202304261541 If you don't see a command prompt, try pressing enter. An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied Session ended, resume using 'kubectl attach pod-identity-test -c pod-identity-test -i -t' command when the pod is running
なお、Pod Identityで使用するService Accountを指定したPodの状態を見ると、以下のように変数の設定やトークンのマウントを確認できます。
kubectl describe pod
コマンドの実行結果
[cloudshell-user@ip-10-132-76-136 ~]$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-65947784f7-nwwhl 1/1 Running 0 3m55s [cloudshell-user@ip-10-132-76-136 ~]$ kubectl describe pod nginx-deployment-65947784f7-nwwhl Name: nginx-deployment-65947784f7-nwwhl Namespace: default Priority: 0 Service Account: pod-identity-test Node: ip-192-168-121-100.ap-northeast-1.compute.internal/192.168.121.100 Start Time: Wed, 03 Apr 2024 11:56:14 +0000 Labels: app=nginx pod-template-hash=65947784f7 Annotations: <none> Status: Running IP: 192.168.114.13 IPs: IP: 192.168.114.13 Controlled By: ReplicaSet/nginx-deployment-65947784f7 Containers: nginx: Container ID: containerd://72ec9c48f4e7ca4ea7e7cf2d0fbf971af7e183f991a535fe3591d2202611801d Image: nginx:latest Image ID: docker.io/library/nginx@sha256:6db391d1c0cfb30588ba0bf72ea999404f2764febf0f1f196acd5867ac7efa7e Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 03 Apr 2024 11:56:21 +0000 Ready: True Restart Count: 0 Environment: # Pod Identity Agentによって追加される AWS_STS_REGIONAL_ENDPOINTS: regional AWS_DEFAULT_REGION: ap-northeast-1 AWS_REGION: ap-northeast-1 AWS_CONTAINER_CREDENTIALS_FULL_URI: http://169.254.170.23/v1/credentials AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-b27c2 (ro) /var/run/secrets/pods.eks.amazonaws.com/serviceaccount from eks-pod-identity-token (ro) # Pod Identity Agentによって追加される Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: eks-pod-identity-token: # Pod Identity Agentによって追加される Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 86400 kube-api-access-b27c2: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m36s default-scheduler Successfully assigned default/nginx-deployment-65947784f7-nwwhl to ip-192-168-121-100.ap-northeast-1.compute.internal Normal Pulling 3m35s kubelet Pulling image "nginx:latest" Normal Pulled 3m29s kubelet Successfully pulled image "nginx:latest" in 6.588s (6.588s including waiting) Normal Created 3m29s kubelet Created container nginx Normal Started 3m29s kubelet Started container nginx [cloudshell-user@ip-10-132-76-136 ~]$
さいごに
今回はEKS Pod Identityの紹介でした。EKS Pod Identityはいくつかの条件があるものの、設定や管理のしやすさはIRSAよりも優れているため、条件を満たす場合は積極的に乗り換えを検討してもよさそうです。またeksctlはIRSAからPod Identityへの移行をコマンドで実行できるので、こういった機能を試すことも検討してみてはいかがでしょうか。
最後に、弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。