コラム
こんにちはクラウド推進チームの宮國です。
久々とはなりますが、今回はEKSを理解する(第2回)という事で、IRSA(IAM Roles for Service Accounts)の仕組みと使い方について書いてみたいと思います。
IRSA(IAM Roles for Service Accounts)とは
IRSAはKubernetesにおけるサービスアカウントリソースにIAMロールを紐づける機能を指します。
サービスアカウントはKubernetes内の認証、認可に関連するリソースで、Pod内のコンテナから各リソースへのアクセスを制御するために用いられます。
なぜ必要か
このIRSAという機能が登場するまでは、Pod単位でIAMロールを割り当てる標準的な手順はなく、EC2インスタンスにIAMロールを割り当てることでAWSリソースに対する権限を付与していました。
しかし、ノードレベルでIAMロールを割り当ててしまうと、そのノードで動作する全てのpodに同様の権限を付与してしまうことになるので、各Podが本来アクセスすべきでないリソースにアクセスできてしまうリスクが伴います。
そこでkube2iamやkiamといったOSSを利用してPodに対してIAMロールを適用させていましたが、AWS公式のソリューションである分、今後はIRSAが主流になると考えられます。
EKSでIRSAを利用するには、
・OpenID Connect Provider Endpointを作成して有効なIdpとしてIAMに登録する
・サービスアカウントに対して、アノテーションとしてIAMロールのARNを付与する
といった2つの前提条件が必要ですが、eksctlコマンドを使うことで簡単に実現できます。それでは実際にやってみます。
検証用クラスタ作成
まずは事前準備としてeksctlを用いてクラスタを作成します。
今回クラスタ構築はCloud9から行います。eksworkshopを参考にkubectlやeksctlコマンドをインストールします。
https://www.eksworkshop.com/020_prerequisites/workspace/
※このワークショップは、各種インストールコマンドがkubernetesのバージョンアップに追従しているので重宝しています。
クラスタを作成する際はeksctl create clusterコマンドを利用します。オプションでもノードの情報は渡せますが、今回は基本的にyaml化して適用します。
eksctl create cluster -f eks-cluster.yaml
eks-cluster.yaml
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: irsa-test region: us-west-2 version: "1.17" managedNodeGroups: - name: nodegroup instanceType: t3.medium minSize: 3 maxSize: 3 desiredCapacity: 3 privateNetworking: true iam: attachPolicyARNs: - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore preBootstrapCommands: - | #!/bin/bash sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm sudo systemctl enable amazon-ssm-agent sudo systemctl start amazon-ssm-agent
preBootstrapCommandsで、ワーカーノードに対してSSMのSession managerで入れるようなユーザデータを設定しています。
ノード毎に1台動かすようなエージェントはKubernetesの思想に則るならば本来的にはDaemonsetで導入すべきですが、コンテナイメージ化が難しいエージェントのインストールはこのように対応します。
また、Session managerで入れるような権限をEC2に付与するためにattachPolicyARNsでAmazonSSMManagedInstanceCoreを指定しています。
クラスタの作成には数十分ほどかかります。
eksctlの裏で動いているのはCloudFormationなので、エラーが発生して削除も再作成もうまくいかない場合はAWSのマネジメントコンソールのCloudFormationから該当のスタックを削除します。
Test Jobの作成
クラスタが作成されたらテスト用のJobを作成します。
今回は以下のようなJobを用意しました。
testjob.yaml
apiVersion: batch/v1 kind: Job metadata: name: s3-listonly spec: template: spec: containers: - name: s3-listonly image: amazon/aws-cli command: ["aws", "s3" , "ls"] restartPolicy: Never backoffLimit: 0
公式AWS CLI v2のDockerイメージを利用して、S3のバケット一覧を取得する簡単なジョブです。
試しに今の状態でapplyしてみると、
kubectl apply -f testjob.yaml
ワーカーノードにもpodにもS3に対する権限を付与していないため、
kubectl get pod
NAME READY STATUS RESTARTS AGE s3-listonly-nff2g 0/1 Error 0 21m
AccessDeniedというエラーが表示されます。
kubectl logs s3-listonly-nff2g
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
IRSAの導入
それではいよいよIRSAの導入です。
以下のコマンドを打つことで、OpenID Connect Provider Endpointを作成して有効なIdpとしてIAMに登録することができます。
eksctl utils associate-iam-oidc-provider \ --name irsa-test \ --approve
[ℹ] eksctl version 0.26.0 [ℹ] using region us-west-2 [ℹ] will create IAM Open ID Connect provider for cluster "irsa-test" in "us-west-2" [✔] created IAM Open ID Connect provider for cluster "irsa-test" in "us-west-2"
IAMのIDプロバイダーを確認すると作成されていることを確認できます。
次に、サービスアカウントとIAMロールを紐づけるために、サービスアカウントのアノテーションとしてIAMロールのARNを付与する必要がありますが、
eksctlコマンドでは以下のように、IAMロール(とアタッチするポリシー)とサービスアカウントのペアを簡単に作成できます。
もしクラスター内にすでに作成されているサービスアカウントがある場合(IAMロールなし)、`–override-existing-serviceaccounts`を使用することで上書き可能です。
eksctl create iamserviceaccount \ --cluster irsa-test \ --name s3-reader-sa \ --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ --approve
IAMロールが作成されていることが確認できます。
また、Kubernetes上ではサービスアカウントが作成されていることが確認できます。
kubectl get sa
NAME SECRETS AGE default 1 95m s3-reader-sa 1 3m27s
そしてサービスアカウントのアノテーションにIAMロールのARNが追加されていることが確認できます。
kubectl describe sa s3-reader-sa | grep eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<accountid>:role/eksctl-irsa-test-addon-iamserviceaccount-Role1-XXXXXXXX
※コマンドのオプションで渡すとどうしても冗長です。以下のようにyaml化して適用する事も可能です。
irsa.yaml
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: irsa-test region: us-west-2 iam: withOIDC: true serviceAccounts: - metadata: name: s3-reader-sa attachPolicyARNs: - "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
eksctl utils associate-iam-oidc-provider -f irsa.yaml --approve
eksctl create iamserviceaccount -f irsa.yaml --approve
IRSAが適用できたら、先ほどErrorになっていたjobを削除し、
kubectl delete -f testjob.yaml
spec.template.spec.serviceAccountNameに先ほど作成したサービスアカウントの名前を指定します。
apiVersion: batch/v1 kind: Job metadata: name: s3-listonly spec: template: spec: serviceAccountName: s3-reader-sa containers: - name: s3-listonly image: amazon/aws-cli command: ["aws", "s3" , "ls"] restartPolicy: Never backoffLimit: 0
kubectl apply -f testjob.yaml
すると、Jobが成功していることが確認できます。
kubectl get job
NAME COMPLETIONS DURATION AGE s3-listonly 1/1 5s 16s
kubectl get pod
NAME READY STATUS RESTARTS AGE s3-listonly-mfb2r 0/1 Completed 0 30s
kubectl logs s3-listonly-mfb2r
バケットの一覧が表示されます。
ノードからS3へのアクセス確認
SSMのSession Managerでノードに入って同じコマンドを打ったとしても、AccessDeniedとなることが確認できます。
sudo su - aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
このようにeksctlを通してIRSAを利用することで、サービスアカウントに対してIAMロールを紐づけるのが容易に実装することができました。
次回はこのIRSAを用いたCluster AutoScalerを試せたらと思います。
-
PICK UP
ピックアップ
-
ピックアップコンテンツがありません
-
RANKING
人気の記事
-
-
1
AWSのその構成、一緒に見直してみませんか vol…
AWSのその構成、一緒に見直してみませんか vol.1
2023/01/15
-
2
望雲彼方に ~クラウド移行その2(インフラエンジニ…
望雲彼方に ~クラウド移行その2(インフラエンジニア編)~
2020/06/12
-
3
Infrastructure as Codeを理解…
Infrastructure as Codeを理解する(第2回)AWS Clou…
2020/11/27
-
4
EKSを理解する(第2回)IRSAを用いたPod単…
EKSを理解する(第2回)IRSAを用いたPod単位のIAMロール割り当て
2020/09/08
-
5
Azureのコスト情報をTeamsで通知する方法
Azureのコスト情報をTeamsで通知する方法
2023/06/14
-
-
ARCHIVE
アーカイブ
-
- July 2024 (1)
- January 2024 (1)
- December 2023 (2)
- June 2023 (2)
- May 2023 (1)
- April 2023 (1)
- March 2023 (2)
- February 2023 (2)
- January 2023 (1)
- December 2022 (2)
- October 2022 (2)
- September 2022 (2)