Маємо Grafana Loki для логів, до подів якої треба підключити AWS IAM Role з AWS IAM Policy, котра дає доступ до AWS S3 бакету, в якому будуть зберігатися чанки та індекси (про сетап самої Loki з AWS S3 трохи пізніше окремим постом).
IAM ролі для Kubernetes подів працють тим самим чином, як ми це робимо, коли підключаємо IAM-ролі до ЕС2-інстансів – процес всередині пода виконує запит до AWS API, а AWS SDK чи AWS CLI, за допомогою якого робиться запит, виконує запит AssumeRole, якому передається сама IAM Role (див. AWS: ротация ключей IAM пользователей, EC2 IAM Roles и Jenkins).
Щоб перевірити, як воно взагалі буде працювати в Кубері – створимо тестову IAM Role, ServiceAccount з аннотацією цієї ролі, та запустимо под з цим ServiceAccount.
Забігаючи наперед – в самій Локі це все одно працює через якусь альтернативну реальність, тобто навіть коли їй підключаєш вже протестований ServiceAccount – вона валиться з помилками. Треба буде копати.
Документація – IAM roles for service accounts.
Зміст
Перевірка IAM OIDC identity provider
EKS кластер розгорнутий за допомогою Terraform модуля aws_eks_cluster
, і OpenID Connect (OIDC) provider вже має бути налаштований.
Заходимо на сторінку кластера, знаходимо OpenID Connect provider URL:
Або з консолі:
[simterm]
$ aws --profile development --region us-west-2 eks describe-cluster --name dev_data_services --query "cluster.identity.oidc.issuer" --output text https://oidc.eks.us-west-2.amazonaws.com/id/537***A10
[/simterm]
Копіюємо URL без https://
, та перевіряємо в IAM > Identity providers:
Окей, тут все є.
Створення Kubernetes ServiceAccount з AWS IAM role
Для початку, створимо IAM policy, яка дає права на AWS S3 bucket, потім IAM Role з TrustedPolicy, яка дозволяє виконувати AssumeRole, використовуючи OIDC identity provider (IDP) кластеру.
AWS IAM policy
Створюємо тестову політику:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::development-dev-loki-object-store", "arn:aws:s3:::development-dev-loki-object-store/*" ] } ] }
Додаємо її в AWS IAM:
[simterm]
$ aws --profile development iam create-policy --policy-name test-iam-sa-pod-policy --policy-document file://test-iam-sa-pod-policy.json
[/simterm]
Переходимо до ролі.
AWS IAM role та TrustedPolicy
Знаходимо ARN нашого Identity Provier:
URL OIDC identity provider вже знаходили раніше:
[simterm]
$ aws --profile development --region us-west-2 eks describe-cluster --name dev_data_services --query "cluster.identity.oidc.issuer" --output text https://oidc.eks.us-west-2.amazonaws.com/id/537***A10
[/simterm]
Створення IAM Role з AWS CLI
Створюємо файл з TustedPolicy, в Principal
якої вказуємо ARN IDP, а в Condition – URL OIDC кластеру, якому дозволяємо виконувати запит до sts.amazonaws.com:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::638***021:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/537***A10" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/537***A10:aud": "sts.amazonaws.com" } } } ] }
Створюємо роль, якій передаємо цю TrustedPolicy:
[simterm]
$ aws --profile development iam create-role --role-name test-iam-sa-pod-role --assume-role-policy-document file://test-iam-sa-role-trusted-policy.json
[/simterm]
Підключаємо їй IAM Policy з правами на S3, яку створили раніше:
[simterm]
$ aws --profile development iam attach-role-policy --role-name test-iam-sa-pod-role --policy-arn=arn:aws:iam::638***021:policy/test-iam-sa-pod-policy
[/simterm]
Створення IAM Role з AWS Console
Або робимо теж саме через адмінку Амазона – вибираємо тип Web identity, Identity Provider кластеру та Audience:
Додаємо IAM Policy для S3:
Зберігаємо:
Копіюємо ARN ролі:
Створення Kubernetes ServiceAccount
Створюємо маніфест ServiceAccount-у, в анотації якого вказуємо ARN ролі, яку створили:
--- apiVersion: v1 kind: ServiceAccount metadata: name: test-iam-sa-pod-service-account annotations: eks.amazonaws.com/role-arn: arn:aws:iam::638***021:role/test-iam-sa-pod-role
І переходимо до пода.
Запуск Kubernetes Pod з ServiceAccount
Додаємо опис поду, якому через serviceAccountName
підключаємо ServiceAccount, тож повністю маніфест буде виглядати так:
apiVersion: v1 kind: ServiceAccount metadata: name: test-iam-sa-pod-service-account annotations: eks.amazonaws.com/role-arn: arn:aws:iam::638***021:role/test-iam-sa-pod-role --- apiVersion: v1 kind: Pod metadata: name: test-iam-sa-pod labels: app: test-iam-sa-app spec: containers: - name: test-iam-sa image: amazon/aws-cli command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 30; done;" ] serviceAccountName: test-iam-sa-pod-service-account
В поді використовємо docker-образ з AWS CLI, якому передаємо sleep
, щоб він працював після запуску.
Деплоїмо ServiceAccount та Pod:
[simterm]
$ kk apply -f test-iam-sa-pod.yaml serviceaccount/test-iam-sa-pod-service-account created pod/test-iam-sa-pod created
[/simterm]
Заходимо в нього:
[simterm]
$ kk exec -ti test-iam-sa-pod -- bash
[/simterm]
І перевіряємо доступ до корзини:
[simterm]
bash-4.2# aws s3 ls development-dev-loki-object-store PRE test/
[/simterm]
Готово.