Lambda를 사용하여 EKS의 서비스 계정에 대한 OIDC 및 IAM 역할 자동화

Terraform 또는 CloudFormatio로 EKS 클러스터를 프로비저닝할 때 OIDCIAM roles 생성을 자동화할 수 있지만 Rancher로 EKS 클러스터를 생성할 때 OIDC 및 IAM 역할 생성을 자동화하려면 어떻게 해야 합니까?

crossplane을 사용하여 새 EKS 클러스터에서 AWS 리소스를 생성하려는 경우 크로스플레인이 클러스터에 액세스하는 방법은 무엇입니까? 이제 우리는 달걀 문제에 직면해 있습니다.

이 기사에서는 EKS 클러스터가 생성된 후 프로세스를 자동화하는 방법을 보여드리겠습니다.

Kubernetes에서 서비스 계정을 사용하여 S3, SQS, SNS 등의 AWS 리소스에 액세스하려면 OIDC 및 IAM 역할이 필요합니다.

AWS는 서비스 계정을 사용하는 것보다 서비스 계정을 사용하는 것이 좋습니다.
Pod 내부의 정적 ACCESS KEY 및 SECRET KEY.



아키텍처 다이어그램에서 새 EKS 클러스터가 생성되면 이벤트 브리지로 이벤트를 보낸 다음 이벤트 이름이 CreateNodegroup 또는 DeleteCluster인 경우에만 람다를 호출하는 규칙을 추가했습니다.
클러스터가 생성된 후 값에 관심이 있기 때문에 이벤트 이름이 CreateCluster가 아닌 이유를 묻습니다. 클러스터 생성에는 약 8분이 걸립니다.

단계:

1- Lambda 서비스로 이동 -> 함수 생성 -> 함수 이름에 "eks-iam"추가 -> 처음부터 작성 -> Runtime Python 3.8 선택 -> 기본 Lambda 권한으로 새 역할 생성 -> 함수 생성

2- IAM 정책 eks-iam-policy를 만들고 아래 정책을 추가합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:UntagRole",
                "iam:TagRole",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:CreateOpenIDConnectProvider",
                "iam:DetachRolePolicy",
                "iam:ListAttachedRolePolicies",
                "eks:DescribeCluster",
                "iam:UntagOpenIDConnectProvider",
                "eks:ListClusters",
                "iam:DeleteOpenIDConnectProvider",
                "iam:TagOpenIDConnectProvider"
            ],
            "Resource": "*"
        }
    ]
}


3- 정책을 람다 실행 역할에 연결하고 람다 eks-iam 기능 -> 구성 -> 권한 -> 실행 역할 -> 역할 이름 eks-iam-role-XXXX 클릭 -> 정책 eks-iam-policy 연결로 이동합니다.

4- 아래 코드를 eks-iam lambda 함수에 추가합니다.

import json
import boto3

# in which namespace that used by the service account
namespace = 'default'

# iam policies
policies = ['arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess']

iam = boto3.client('iam')

def create_role(roleName,policy):
    response = iam.create_role(
        RoleName=roleName,
        AssumeRolePolicyDocument=json.dumps(policy),
        Description='Lambda invoked by Rancher event to Create this Role',
        MaxSessionDuration=3600,
        Tags=[
            {
                'Key': 'Created-By',
                'Value': 'Lambda'
            },

        ]
    )

    return response

def lambda_handler(event, context):

    if event['detail']['eventName'] == "CreateNodegroup":
        clusterName = event['detail']['responseElements']['nodegroup']['clusterName']
        eks = boto3.client('eks')
        eksResponse = eks.describe_cluster(name=clusterName)
        oidc = eksResponse['cluster']['identity']['oidc']['issuer']

        # create oidc provider
        oidcResponse = iam.create_open_id_connect_provider(Url=oidc,
        ClientIDList=['sts.amazonaws.com',],
        ThumbprintList=['9e99a48a9960b14926bb7f3b02e22da2b0ab7280',],
        Tags=[{ 'Key': 'Created-By', 'Value': 'Lambda' }, ])

        arn = oidcResponse['OpenIDConnectProviderArn']
        policy =  { "Version": "2012-10-17","Statement": [ {"Sid": "", "Effect": "Allow", "Principal": { "Federated": arn}, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { arn.split('oidc-provider/')[1] +":sub": "system:serviceaccount:" + namespace + ":" + clusterName }}}]}

        # create iam role
        createResponse = create_role (clusterName, policy)

        print(createResponse)

        # attach policies to the role
        for i in range(len(policies)):
            iam.attach_role_policy(
                RoleName=clusterName,
                PolicyArn= policies[i]
                )

        return oidcResponse

    elif event['detail']['eventName'] == "DeleteCluster":
        clusterName =  event['detail']['responseElements']['cluster']['name']
        oidc = event['detail']['responseElements']['cluster']['identity']['oidc']['issuer']
        accountId = event['detail']['userIdentity']['accountId']
        arn = "arn:aws:iam::" + accountId + ":oidc-provider/" + oidc.split('https://')[1]

        # remove oidc provider
        oidcResponse = iam.delete_open_id_connect_provider(
            OpenIDConnectProviderArn=arn
            )

        # get all policies attached to the role
        policyResponse = iam.list_attached_role_policies(
            RoleName=clusterName
            )

        # detach all policies from the role
        for i in range(len(policyResponse['AttachedPolicies'])):
            iam.detach_role_policy(
                RoleName=clusterName, PolicyArn=policyResponse['AttachedPolicies'][i]['PolicyArn']
                )

        # remove the iam role
        roleResponse = iam.delete_role(
            RoleName=clusterName
            )

        return oidcResponse



5- EventBridge -> 규칙 -> 규칙 만들기 -> 이벤트 패턴이 있는 규칙 -> 이벤트 패턴으로 이동하여 사용자 지정 패턴(JSON 편집기)을 선택하고 다음을 추가합니다.

{
  "source": ["aws.eks"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["eks.amazonaws.com"],
    "eventName": ["CreateNodegroup", "DeleteCluster"]
  }
}


대상 선택 -> AWS 서비스 -> 대상 선택 -> Lambda 함수 -> 함수 -> eks-iam

6- EKS 클러스터에서 서비스 계정을 생성합니다. 이제 EKS-CLUSTER-NAME만 변경하기 때문에 IAM 역할의 arn을 알 수 있습니다.

힌트: EKS 클러스터에 고유한 이름이 있다고 가정했습니다.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: list-s3
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::AWS-ACCOUNT-NUMBER:role/EKS-CLUSTER-NAME



7- 아래 예와 같이 배포를 만들고 서비스 계정 이름을 정의합니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aws-cli
  namespace: default
spec:
  selector:
    matchLabels:
      app: aws-cli
  replicas: 1
  template:
    metadata:
      labels:
        app: aws-cli
    spec:
      serviceAccountName: list-s3
      containers:
      - name: aws-cli
        image: amazon/aws-cli
        command: [ "/bin/bash", "-c", "--" ]  
        args: [ "while true; do sleep 30; done;" ]



이제 다음을 통해 포드에 액세스하고 테스트할 수 있습니다.

aws s3 ls


결국 각 EKS 클러스터에 연결된 기본 정책을 가질 수 있으며 크로스플레인과 같은 도구를 사용하여 특정 IAM 정책 및 역할을 생성할 수 있습니다.

출처:
https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html

좋은 웹페이지 즐겨찾기