본문 바로가기
Amazon AWS/EKS

IAM 역할을 수임하도록 Kubernetes 서비스 계정 구성 후 Pod에 권한 적용

by 홍띠 2023. 4. 29.

EKS에 헬름차트로 구성한 Fluentd에서 AWS 데이터를 보낼 때 cloudwatch에 대한 권한이 필요하다.
이때, pod가 클라우드워치 수행 권한이 있는 IAM 역할을 위임하도록 serviceaccount를 구성하여 해당 파드에서 Cloudwatch로 로그를 보낼 수 있도록 한다.

💡Prerequisites:
- EKS 클러스터
- IAM OpenID Connect(OIDC) 공급자
확인: aws eks describe-cluster --name <cluster-name> --query "cluster.identity.oidc.issuer" --output text
- AWS CLI 버전 2.9.20 이상
- kubectl 설치
- kubectl config 파일 (~/.kube/config)


1. IAM 정책 생성


    $ cat >log-policy.json <<EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "logs:*"
                ],
                "Effect": "Allow",
                "Resource": "*"
            }
        ]
    }
    EOF
    
    $ aws iam create-policy --policy-name eks-log-policy --policy-document file://log-policy.json

2. IAM 역할 생성

  •     환경변수 설정

    

oidc_provider=$(aws eks describe-cluster --name <cluster name> --region <region> --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
  • 신뢰정책 파일 생성 정의

account-id에 aws 계정 id를 입력한다.
namespace는 서비스계정이 배포되는 네임스페이스를 입력한다.
serviceaccount name에는 뒤에서 생성할 서비스계정 이름을 미리 정의해서 넣는다.

cat >log-trust-relationship.json <<EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::<account-id>:oidc-provider/$oidc_provider"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "$oidc_provider:aud": "sts.amazonaws.com",
              "$oidc_provider:sub": "system:serviceaccount:<namespace>:<serviceaccount name>"
            }
          }
        }
      ]
    }
EOF
  • 역할 생성
aws iam create-role --role-name eks-log-role --assume-role-policy-document file://log-trust-relationship.json
  • 역할에 정책 연결
aws iam attach-role-policy --role-name eks-log-role --policy-arn=arn:aws:iam::<account-id>:policy/eks-log-policy

3. Service account 생성

서비스 계정을 생성하고 적용하는것은 헬름차트를 사용하는지에 따라 방법이 달라진다.
이번 예시에서는 헬름차트를 사용하는것으로 진행한다.

  • values.yml에 아래 코드를 추가 혹은 업데이트

role-arn에 위에서 생성한 role의 arn을 입력한다.

serviceAccount:
  create: true
  annotations:
    eks.amazonaws.com/role-arn: "arn:aws:iam::<account-id>:role/eks-log-role"
  name: "eks-log-service-account"
  • Helm chart upgrade
helm upgrade <release name> /chart/dir/

4. 결과확인

Helm upgrade 후 deployment.yml 와serviceaccount.yml가 아래와 같이 구성되어 있으면 된다!

  • deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: log-fluentd
  namespace: 
  labels:
    helm.sh/chart: fluentd-0.3.9
    app.kubernetes.io/name: fluentd
    app.kubernetes.io/instance: log
    app.kubernetes.io/version: "v1.14.6"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: fluentd
      app.kubernetes.io/instance: log
  template:
    metadata:
      annotations:
      labels:
        app.kubernetes.io/name: fluentd
        app.kubernetes.io/instance: log
    spec:
      serviceAccountName: eks-log-service-account
      securityContext:
        {}
      containers:
        - name: fluentd
        …생략
  • serviceaccount.yml
# Source: fluentd/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: eks-log-service-account
  labels:
    helm.sh/chart: fluentd-0.3.9
    app.kubernetes.io/name: fluentd
    app.kubernetes.io/instance: log
    app.kubernetes.io/version: "v1.14.6"
    app.kubernetes.io/managed-by: Helm
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/eks-log-role


참고: https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/associate-service-account-role.html