AWS: EKS Pod Identities – заміна IRSA? Спрощуємо менеджмент IAM доступів

Автор |  15/12/2023

Ще з дуже цікавих новинок останнього re:Invent – це EKS Pod Identities: нова можливість керувати доступами подів до ресурсів AWS.

The current state: IAM Roles for Service Accounts

До цього ми використовували модель IAM Roles for Service Accounts, IRSA, де для того, щоб якомусь поду дати доступ до, наприклад, S3, ми створювали IAM Role з відповідною IAM Policy, налаштовували її Trust Policy – щоб дозволити виконувати AssumeRole тільки з відповідвідного кластеру, потім створювали Kubernetes ServiceAccount, в annotations якого вказували ARN цієї ролі.

За такою схемою ми мали декілька “error prone” моментів:

  • найбільш розповсюджена проблема, з якою і я стикався прям ну дуже багато раз – помилки в Trust Policy, де треба було вказувати OIDC кластеру
  • помилки в самому ServiceAccount, де можна було помилитись в ARN ролі

Див. AWS: EKS, OpenID Connect та ServiceAccounts.

The f(ea)uture state: EKS Pod Identities

Проте тепер EKS Pod Identities дозволяє нам один раз створити IAM Role, ніяк її не обмежувати конкретним кластером, і підключати цю роль до подів (знову-таки – через ServiceAccount) прямо з AWS CLI, AWS Console чи через AWS API (Terraform, CDK, etc).

Як це виглядає:

  • в EKS додаємо новий контроллер – Amazon EKS Pod Identity Agent add-on
  • створюємо IAM Role, в Trust Policy якої тепер використовуємо Principal: pods.eks.amazonaws.com
  • і з AWS CLI, AWS Console чи через AWS API підключаємо цю роль напряму до потрібного ServiceAccount

Го тестити!

Створення IAM Role

Переходимо в IAM, створюємо роль.

В Trusted entity type вибираємо EKS і новий тип – EKS – Pod Identity:

В Permissions візьмемо вже існуючу політику на S3ReadOnly:

Задаємо ім’я ролі, і як раз тут і бачимо нову Trust Policy:

І давайте порівняємо її з Trust Policy для IRSA ролі:

Набагато простіше, а значить – менше варіантів для помилок, і взагалі простіше менеджити. До того ж, ми більше не зав’язані на Cluster OIDC Provider.

До речі, з EKS Pod Identities ми можемо використовувати і role session tags.

Окей, йдемо далі.

Amazon EKS Pod Identity Agent add-on

Переходимо до нашого кластеру, встановлюємо новий компонент – Amazon EKS Pod Identity Agent add-on:

Чекаємо хвилину – готово:

І поди цього контролера:

$ kk -n kube-system get pod | grep pod
eks-pod-identity-agent-d7448                    1/1     Running   0               91s
eks-pod-identity-agent-m46px                    1/1     Running   0               91s
eks-pod-identity-agent-nd2xn                    1/1     Running   0               91s

Підключення IAM Role до ServiceAccount

Переходимо в Access, і клікаємо Create Pod Identity Association:

Вибираємо роль, яку створили вище.

Далі задаємо ім’я неймспейсу – або вибираємо зі списку існуючих, або вказуємо нове.

Аналогічно з ім’ям ServiceAccount – можна задати вже створенний SA, можно задати нове ім’я:

Створення Pod та ServiceAccount

Описуємо маніфест:

apiVersion: v1
kind: Namespace
metadata:
  name: ops-iam-test-ns
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ops-iam-test-sa
  namespace: ops-iam-test-ns
---
apiVersion: v1
kind: Pod
metadata:
  name: ops-iam-test-pod
  namespace: ops-iam-test-ns
spec:
  containers:
    - name: aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  serviceAccountName: ops-iam-test-sa

Деплоїмо:

$ kubectl apply -f iam-sa.yaml    
namespace/ops-iam-test-ns created
serviceaccount/ops-iam-test-sa created
pod/ops-iam-test-pod created

І пробуємо доступ:

$ kk -n ops-iam-test-ns exec -ti ops-iam-test-pod -- bash
bash-4.2# aws s3 ls
2023-02-01 11:29:34 amplify-staging-112927-deployment
2023-02-02 15:40:56 amplify-dev-174045-deployment
...

Але якщо ми спробуємо іншу операцію, на яку ми не підключали політику, наприклад – EKS, то отримаємо 403:

bash-4.2# aws eks list-clusters

An error occurred (AccessDeniedException) when calling the ListClusters operation: User: arn:aws:sts::492***148:assumed-role/EKS-Pod-Identities-test-TO-DEL/eks-atlas-eks--ops-iam-te-cc662c4d-6c87-44b0-99ab-58c1dd6aa60f is not authorized to perform: eks:ListClusters on resource: arn:aws:eks:us-east-1:492***148:cluster/*

Проблеми?

Наразі я бачу одну потенційну не проблему, але питання, яке варто мати на увазі: якщо раніьше ми налаштовували доступ на рівні сервісу, то з EKS Pod Identities це робиться на рівні управління кластером.

Тобо: в мене є сервіс, Backend API. В нього є власний репозиторій, в якому є каталог terrafrom, в якому створюються необхідні IAM-ролі.

Далі, є каталог helm, в якому маємо маніфест з ServiceAccount, в якому в анотаціях через змінні передається ARN цієї IAM ролі.

І на цьому все – мені (точніше – CI/CD пайплайну, який виконує деплой) потрібен доступ тільки до IAM, потрібен доступ в EKS на створення Ingress, Deployment та ServiceAccount.

Але тепер треба буде думати як давати доступ ще й до EKS на рівні AWS, бо треба буде виконувати додаткову операцію в AWS API на Create Pod Identity Assosiaction.

До речі, в Terraform вже новий ресурс для цього – aws_eks_pod_identity_association.

Проте виглядає дійсно класно, і може дуже спростити життя по менеджменту EKS та IAM.

EKS Pod Identity restrictions

Варто звернути увагу на документацію, бо в EKS Pod Identity restrictions говориться, що EKS Pod Identities доступна тількина Amazon Linux:

EKS Pod Identities are available on the following: