AWS 기술 블로그

간소화된 Amazon EKS 액세스 관리 제어 톺아보기

본 블로그 포스트는 Sheetal Joshi, Rodrigo Bersa, Mike Stefaniak 님의 영문 블로그를 원문으로 한글 번역된 블로그 입니다. 

소개

초기 Amazon Elastic Kubernetes Service (Amazon EKS) 출시 이후 클러스터에서 인증할 수 있는 개체로 AWS Identity and Access Management (AWS IAM) 보안 주체(principals)를 지원해 왔습니다. 이는 관리자가 별도의 자격 증명 공급자(Identity Provider)를 유지해야 하는 부담을 없애기 위한 조치입니다. 또한 AWS IAM을 사용하면 AWS 고객은 AWS IAM에 대한 지식과 경험을 활용할 수 있고 관리자는 AWS CloudTrail 감사 로깅 및 멀티 팩터 인증(MFA)과 같은 기능을 사용할 수 있습니다.

지금까지 관리자는 Amazon EKS API를 사용하여 클러스터를 생성한 후 Kubernetes API로 전환하여 AWS IAM 보안 주체의 매핑과 Kubernetes 권한을 관리했습니다. 이러한 수동 및 다단계 프로세스로 인해 사용자에게 Amazon EKS 클러스터에 대한 액세스 권한을 부여하는 방식이 복잡해졌습니다. 관리자가 클러스터를 생성할 때 사용한 보안 주체로부터 클러스터 관리자 [루트와 유사한(root-like)] 권한을 취소할 수 없었고, 액세스를 관리하기 위해 다른 API (AWS 및 Kubernetes) 를 호출해야 했기 때문에 구성이 잘못될 가능성도 커졌습니다.

기능 개요

Amazon EKS 팀은 향상된 클러스터 액세스 관리 제어를 통해 클러스터 인증 (AuthN) 및 권한 부여 (AuthZ) 사용자 경험을 개선했습니다. 이 게시물이 게시된 날부터 클러스터 관리자는 이제 AWS IAM 보안 주체에게 Amazon EKS API를 통해 Amazon EKS 클러스터 및 Kubernetes 객체의 지원되는 모든 버전 (v1.23 이상) 에 대한 액세스 권한을 직접 부여할 수 있습니다. 이 새로운 기능은 액세스 항목(access entries)과 액세스 정책(access policy)이라는 두 가지 새로운 개념을 기반으로 합니다. 액세스 항목은 AWS IAM 사용자 또는 역할에 직접 연결되어 Amazon EKS 클러스터를 인증하는 데 사용됩니다. Amazon EKS 액세스 정책은 특정 클러스터 작업을 수행할 수 있는 액세스 항목을 승인합니다.

Cluster access management API

새로운 Cluster access management API는 관리자가 친숙한 인프라스트럭처 코드(IaC) 도구인 AWS CloudFormation, Terraform 또는 AWS Cloud Development Kit (CDK)를 사용하여 클러스터 생성 시 액세스 관리 구성을 정의할 수 있게 합니다.

개선된 액세스 관리 제어 기능을 통해 관리자는 클러스터를 생성하는 데 사용된 AWS IAM 보안 주체에 자동으로 부여된 권한을 완전히 제거하거나 세분화할 수 있습니다. 구성이 잘못 되었을 경우 호출자에게 필요한 권한이 있다면 Amazon EKS API를 호출하여 클러스터 액세스를 쉽게 복원할 수 있습니다. 이러한 새로운 제어 기능의 목적은 사용자와 애플리케이션이 클러스터와 클러스터 내 객체에 액세스할 수 있도록 부여하는 데 따른 오버헤드를 줄이는 것입니다.

Note: AWS IAM 역할을 Amazon EKS 클러스터 생성 보안 주체로 사용할 것을 항상 권장합니다. 역할은 사용자와 권한을 분리하는 간접 계층을 제공합니다. 사용자를 역할에서 제거할 수 있으며, 클러스터 생성자 역할에 권한을 제공하는 AWS IAM 정책을 조정할 필요가 없습니다.

Kubernetes authorizers

액세스 정책은 Kubernetes 권한을 액세스 항목에 할당하는 Amazon EKS 전용 정책입니다. 출시 시점에 Amazon EKS는 사전 정의된 정책과 AWS 관리 정책만 지원합니다. 액세스 정책은 AWS IAM 엔티티가 아니며, Amazon EKS에서 정의하고 관리합니다.

Kubernetes에서 다양한 AuthZ 서비스(authorizer)가 체인으로 연결되어 인바운드 API 서버 요청에 대한 AuthZ 결정을 내립니다. 이를 통해 사용자 지정 AuthZ 서비스를 Kubernetes API 서버와 함께 사용할 수 있습니다. 새로운 기능을 통해 업스트림 RBAC (Role-Based Access Control)를 액세스 정책과 함께 사용할 수 있습니다. 업스트림 RBAC 와 Amazon EKS Authorizer 모두 AuthZ 결정에 대해 allow 및 pass(but not deny)를 지원합니다. Kubernetes 사용자 이름 또는 그룹으로 액세스 항목를 생성할 때, 업스트림 RBAC가 평가한 후 허용 결과가 나오면 즉시 AuthZ 결정을 반환합니다. RBAC 권한 부여자가 결과를 판단할 수 없다면 결정을 Amazon EKS Authorizer에게 전달합니다. 두 권한 부여자 모두 결과를 판단할 수 없는 경우에는 거부 결정(deny decision)이 내려집니다.

Walkthrough

시작하기

액세스 항목 API를 사용한 클러스터 액세스 관리는 Amazon EKS v1.23 이상부터 새로 생성 된 클러스터에 대해 옵트인(opt-in) 기능입니다. 기본적으로 Amazon EKS는 새 클러스터를 생성할 때 최신 Amazon EKS 플랫폼 버전을 사용합니다. Amazon EKS는 자동으로 모든 기존 클러스터를 해당 Kubernetes 마이너 버전에 대한 최신 Amazon EKS 플랫폼 버전으로 업그레이드합니다. 기존 클러스터에서 플랫폼 버전 자동 업그레이드가 적용되면 새로운 클러스터 액세스 관리 제어를 사용할 수 있습니다. 또는 이 기능을 활용하기 위해 다음 지원되는 Kubernetes 마이너 버전으로 클러스터를 업데이트할 수 있습니다.

이 기능을 사용하려면 클러스터 관리자가 원하는 AWS IAM 보안 주체로 Amazon EKS 액세스 항목을 생성해야 합니다. 관리자를 위한 AWS IAM 권한을 구성하려면 액세스 항목에 대한 IAM 정책 제어를 참조하십시오. 이러한 액세스 항목이 생성되면 관리자는 액세스 정책을 할당하여 해당 액세스 항목에 대한 액세스 권한을 부여할 수 있습니다. Amazon EKS 액세스 정책에는 Kubernetes 리소스에 대한 관리(administration), 편집(editing) 또는 읽기 전용(read-only) 액세스와 같은 일반적인 사용 사례를 지원하는 권한 세트가 포함되어 있습니다.

다음 명령어 및 출력은 클러스터 액세스 관리를 위해 지원되는 액세스 정책의 최신 목록을 제공합니다.

# List all access policies
$ aws eks list-access-policies
{
    "accessPolicies": [
        {
            "name": "AmazonEKSAdminPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy"
        },
        {
            "name": "AmazonEKSClusterAdminPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
        },
        {
            "name": "AmazonEKSEditPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy"
        },
        {
            "name": "AmazonEKSViewPolicy",
            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
        }
    ]
}

다음 Amazon EKS 액세스 정책은 Kubernetes 설명서에 게시된 user-facing roles 을 기반으로 합니다:

  • AmazonEKSClusterAdminPolicy – cluster-admin
  • AmazonEKSAdminPolicy – admin
  • AmazonEKSEditPolicy – edit
  • AmazonEKSViewPolicy – view

클러스터 액세스 관리 제어를 사용하면 적절한 권한을 가진 AWS IAM 보안 주체만이 다른 AWS IAM 보안 주체에게 Amazon EKS 클러스터에 액세스할 수 있는 권한을 부여할 수 있습니다. 액세스 항목을 생성하고 액세스 정책을 해당 액세스 항목과 연결하여 권한을 부여합니다. Amazon EKS 액세스 정책에 의해 AWS IAM 보안 주체에 부여된 액세스는 AWS IAM 보안 주체와 관련된 AWS IAM 정책에 정의된 권한과는 별개라는 점에 유의하십시오.

간단히 말해서 클러스터 액세스 관리 권한 부여자는 AWS IAM 보안 주체와 적용된 Amazon EKS 액세스 항목 정책만 사용합니다. 다음 다이어그램은 워크플로를 보여줍니다.

다음 섹션에서는 새로운 Amazon EKS 클러스터 액세스 관리 API를 통해 현재 가능한 몇 가지 사용 사례를 살펴보겠습니다.

Access Management API를 사용하도록 클러스터를 만들거나 업데이트

이 기능이 도입됨에 따라 Amazon EKS는 세 가지 인증 모드(authenticationMode)로 CONFIG_MAP, API_AND_CONFIG_MAP 및 API를 지원합니다. API 또는 API_AND_CONFIG_MAP 인증 모드를 사용하여 클러스터가 액세스 항목 API를 사용하도록 설정할 수 있습니다. CONFIG_MAP 인증 모드를 사용하여 aws-auth configMap을 계속 사용할 수도 있습니다. API_AND_CONFIG_MAP 모드가 활성화되면 클러스터는 Amazon EKS 액세스 항목 API와 aws-auth configMap 모두에서 인증된 AWS IAM 보안 주체를 가져오되, 액세스 항목 API에 우선 순위가 부여됩니다.

aws eks create-cluster \
  --name <CLUSTER_NAME> \
  --role-arn <CLUSTER_ROLE_ARN> \
  --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \
  --access-config authenticationMode=API

이제 Amazon EKS 클러스터 액세스 관리는 AWS IAM 보안 주체의 Amazon EKS 클러스터 액세스를 관리하는 데 선호되는 방식입니다. 액세스 관리를 더 쉽고 안전하게 만들면서도, 클러스터 운영이나 현재 구성을 방해하지 않고도 액세스 할 수 있습니다. 이 접근 방식을 통해 필요에 맞는 클러스터 액세스 관리를 탐색하고, 가장 적절한 시기에 클러스터 액세스 관리로 마이그레이션 할 수 있습니다.

Amazon EKS는 기존 클러스터를 API_AND_CONFIG_MAP 인증 모드로 사용하도록 업데이트하고, aws-auth configMap에서 사용된 동일한 ID 및/또는 그룹을 지정하여 동등한 액세스 항목을 생성할 것을 제안합니다. API_AND_CONFIG_MAP이 활성화되면 클러스터는 Amazon EKS 액세스 항목 API와 aws-auth configMap 모두에서 인증된 AWS IAM 보안 주체를 가져오되, 액세스 항목 API에 우선순위를 부여합니다. 인증 모드를 API_AND_CONFIG_MAP로 설정하면 인증 시 액세스 항목이 ConfigMap 및 관련 사용자 이름(username)과 그룹에 앞서 평가됩니다. 보안 주체에 대한 액세스 항목이 생성되지 않은 경우 ConfigMap에서 보안 주체와 관련 사용자 이름 및 그룹의 존재 여부를 검사합니다.

기존 클러스터 구성을 업데이트하여 API 인증모드를 활성화할 수 있습니다. update-cluster-config 명령을 실행하기 전에 플랫폼 버전이 업데이트되었는지 확인하십시오. CONFIG_MAP을 사용하는 기존 클러스터의 경우 먼저 인증 모드를 API_AND_CONFIG_MAP으로 업데이트한 다음 API로 업데이트해야 합니다.

aws eks update-cluster-config \
   --name <CLUSTER_NAME> \
   --access-config authenticationMode=API

기존 클러스터의 인증 모드 전환은 단방향 작업입니다. CONFIG_MAP에서 API_AND_CONFIG_MAP 인증 모드로 전환할 수 있으며, API_AND_CONFIG_MAP에서 API 인증 모드로 전환할 수 있습니다. 이러한 작업을 반대 방향으로 되돌릴 수는 없습니다. 즉, API에서 CONFIG_MAP 또는 API_AND_CONFIG_MAP 인증 모드로 다시 전환할 수 없습니다. 그리고 API_AND_CONFIG_MAP에서 CONFIG_MAP 인증 모드로 다시 전환할 수 없습니다.

기본 클러스터 관리자 제거

지금까지는 Amazon EKS 클러스터를 생성할 때 클러스터를 프로비저닝하는 데 사용된 보안 주체에게 영구적으로 Kubernetes 클러스터 관리자 권한이 부여되었습니다. 이 시나리오에서 AWS IAM 역할을 사용하여 Amazon EKS 클러스터를 생성하는 모범 사례가 등장했습니다. AWS IAM 역할을 사용하면 AWS IAM을 사용하여 누가 역할을 맡을 수 있는지 제어할 수 있는 간접 계층(layer-of-indirection)이 제공되었습니다. 역할을 수임(assume)할 수 있는 권한을 제거하거나 역할을 모두 제거하면 클러스터에 대한 사용자의 액세스 권한을 취소할 수 있습니다.

이 게시물을 작성한 날짜를 기준으로 사용자가 선택한 AWS IAM 보안 주체를 사용하거나 권한 없이 클러스터를 생성할 수 있습니다.아래 예제에서는 access-config에 BootstrapClusterCreatorAdminPermissions=False 플래그를 사용하여 클러스터를 생성하는 데 사용되는 보안 주체에 클러스터 관리자 액세스 권한이 부여되지 않도록 합니다.

# Create Amazon EKS cluster with no cluster administrator
$ aws eks create-cluster --name <CLUSTER_NAME> \
  --role-arn <CLUSTER_ROLE_ARN> \
  --resources-vpc-config subnetIds=<value>,securityGroupIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \
  --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false

클러스터에 대한 액세스 항목이 없는지 확인하려면 다음 AWS CLI 명령을 사용하여 기존 클러스터 액세스 항목을 나열할 수 있습니다.

# List access entries for cluster
$ aws eks list-access-entries --cluster-name <CLUSTER_NAME>

{
    "accessEntries": []
}

kubectl auth can-i —list 명령으로 AWS IAM 보안 주체를 사용하려고 하면 kubeconfig 파일이 제대로 구성되어 있어도 해당 보안 주체가 클러스터에 인증되지 않은 것을 볼 수 있습니다.

# Verify cluster creator cannot access cluster
$ kubectl auth can-i --list
error: You must be logged in to the server (Unauthorized)

기존 클러스터에서 클러스터 생성자의 관리자 역할을 제거하려면 클러스터를 액세스 항목을 지원하는 인증 모드로 업데이트한 후 연결된 액세스 항목에 대해 다음 명령을 실행하세요.

# Delete access entry
$ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \
  --principal-arn <IAM_PRINCIPAL_ARN>

기존 클러스터에 클러스터 관리자 추가

이제 클러스터 생성 시 클러스터 관리자를 처리하는 방법을 살펴보았으므로, 기존 클러스터에 클러스터 관리자를 추가하는 방법을 알아보겠습니다. AWS CLI 명령을 사용하여 다음 작업을 수행할 수 있습니다:

  • 클러스터 관리자 액세스 권한을 부여받을 클러스터 액세스 항목 생성
  • 앞서 생성한 클러스터 액세스 항목에 클러스터 관리자 액세스 정책 연결
# Create cluster access entry
$ aws eks create-access-entry --cluster-name <CLUSTER_NAME> \
  --principal-arn <IAM_PRINCIPAL_ARN>
  
{
    "accessEntry": {
        "clusterName": "<value>",
        "principalArn": "<value>",
        "kubernetesGroups": [],
        "accessEntryArn": "<ACCESS_ENTRY_ARN>",
        "createdAt": "2023-03-30T21:38:24.185000-04:00",
        "modifiedAt": "2023-03-30T21:38:24.185000-04:00",
        "tags": {},
        "username": "arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/<ROLE_NAME>/{{SessionName}}"
    }
}

AWS IAM 보안 주체와 연결된 액세스 항목을 생성한 후, 다음 AWS CLI 명령을 실행하여 AmazonEKSClusterAdminPolicy를 할당합니다. 클러스터 관리자 항목을 생성하므로 명령에서 —access-scope type=cluster 인수를 설정합니다:

# Associate access policy to access entry
$ aws eks associate-access-policy --cluster-name <CLUSTER_NAME> \
  --principal-arn <IAM_PRINCIPAL_ARN> \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
  --access-scope type=cluster
  
  {
    "clusterName": "<CLUSTER_NAME>",
    "principalArn": "<AWS_IAM_PRINCIPAL_ARN>",
    "associatedAccessPolicy": {
        "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
        "accessScope": {
            "type": "cluster",
            "namespaces": []
        },
        "associatedAt": "2023-04-03T13:44:09.788000-04:00",
        "modifiedAt": "2023-04-03T13:44:09.788000-04:00"
    }
}

네임스페이스 관리자 추가

네임스페이스 관리자는 특정 네임스페이스로 한정되는 관리자 권한을 갖게 됩니다. 네임스페이스와 같은 클러스터 범위의 리소스는 생성할 수 없게 됩니다. 해당 사용 사례를 설명하기 위해 읽기 전용 AWS IAM 역할을 기반으로 액세스 항목을 만들어 보겠습니다. 이 읽기 전용 역할에는 해당 AWS 계정에 대한 읽기 전용 액세스 권한이 있습니다. 이 예시는 인위적인 것처럼 보일 수 있지만 AWS IAM 정책과 Amazon EKS 클러스터 액세스 정책 간의 차이를 보여줍니다. 참고로 ReadOnly라는 역할에는 AWS 계정에 대한 읽기 전용 액세스 권한을 부여하는 arn:aws:iam::aws:policy/ReadOnlyAccess AWS IAM 정책이 연결되어 있습니다.

# Create access entry
$ aws eks create-access-entry --cluster-name <CLUSTER_NAME> \
  --principal-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly

  {
    "accessEntry": {
        "clusterName": "<CLUSTER_NAME>",
        "principalArn": "<IAM_PRINCIPAL_ARN>",
        "kubernetesGroups": [],
        "accessEntryArn": "arn:aws:eks:<REGION>:<AWS_ACCOUNT_ID>:accessEntry/<CLUSTER_NAME>/role/<AWS_ACCOUNT_ID>/ReadOnly/40c3cb02-38ed-3edc-4f8c-0043d4639029",
        "createdAt": "2023-04-18T16:18:06.556000-04:00",
        "modifiedAt": "2023-04-18T16:18:06.556000-04:00",
        "tags": {},
        "username": "arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/ReadOnly/{{SessionName}}"
    }
}

위 명령은 앞서 언급한 ReadOnly라는 AWS IAM 역할을 기반으로 하는 클러스터 액세스 항목을 생성합니다. 다음은 AmazonEKSAdminPolicy 정책을 새로 생성된 액세스 항목에 연결해 보겠습니다.

# Associate access policy to access entry

$ aws eks associate-access-policy --cluster-name <CLUSTER_NAME> \ 
  --principal-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy \ 
  --access-scope type=namespace,namespaces=test* 
  
  {
    "clusterName": "<CLUSTER_NAME>", 
    "principalArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly", 
    "associatedAccessPolicy": { 
        "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy", 
        "accessScope": {
            "type": "namespace", 
            "namespaces": [
                "test*"
            ]
        },
        "associatedAt": "2023-04-18T16:42:57.754000-04:00", 
        "modifiedAt": "2023-04-18T16:42:57.754000-04:00" 
    } 
  } 

이 명령을 실행하면 기본 AWS 계정에 대한 읽기 전용 액세스만 가진 AWS IAM ReadOnly 역할이 이제 test* 네임스페이스에 대한 네임스페이스 관리자 액세스 권한을 갖게 됩니다.

# Namespace admin cannot access namespaces not on the allowed list
$ kubectl -n kube-system get pods 
Error from server (Forbidden): pods is forbidden: User "arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/ReadOnly/<SESSION_ID>" cannot list resource "pods" in API group "" in the namespace "kube-system"

# Namespace admin can access namespaces on the allowed list
# This step assumes the namespaces exist, use clusteradmin to create these roles
# kubectl create ns test-1
$ kubectl auth can-i get pods -n test-1 
yes 

# Namespace admin can create pods in test1
$ kubectl create deployment nginx --image=nginx -n test-1 
deployment.apps/nginx created

읽기 전용 액세스 사용자 추가

이 사용 사례를 시작하기 위해 이전 사용 사례에서 사용한 기존 AWS IAM 읽기 전용 역할을 사용합니다. 이를 위해서는 기존 액세스 정책을 분리해야 합니다. 다음 명령어는 네임스페이스 관리자 액세스 항목에서 액세스 정책을 제거한 다음 액세스 항목과 관련된 정책을 나열합니다.

# Disassociate access policy from access entry
aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \
--principal-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy

# List associated access policies to access entry
aws eks list-associated-access-policies --cluster-name <CLUSTER_NAME> \
--principal-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly
{
    "clusterName": "<CLUSTER_NAME>",
    "principalArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly",
    "associatedAccessPolicies": []
}

위와 같이 AWS IAM 읽기 전용 역할 네임스페이스 관리자에게 클러스터에 대한 액세스 권한을 부여하는 액세스 정책을 분리했습니다. 다음 명령어를 사용하여 AmazonEKSViewPolicy를 액세스 항목에 연결하여 AWS IAM 역할 주체에 클러스터 전체의 읽기 전용 액세스를 제공한 후, 액세스 항목에서 클러스터 전체의 읽기 전용 액세스 권한이 있는지 확인합니다.

# Associate access policy to access entry 
$ aws eks associate-access-policy --cluster-name <CLUSTER_NAME> \ 
    --principal-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly \
    --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \ 
    --access-scope type=cluster 
{ 
    "clusterName": "<CLUSTER_NAME>", 
    "principalArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ReadOnly", 
    "associatedAccessPolicy": {
        "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy", 
        "accessScope": {
            "type": "cluster", "namespaces": []
        }, 
        "associatedAt": "2023-04-20T10:08:17.503000-04:00", 
        "modifiedAt": "2023-04-20T10:08:17.503000-04:00" 
    } 
} 

# Cluster read-only user can GET pods in kube-system namespace 
$ kubectl -n kube-system get po 
NAME                     READY    STATUS    RESTARTS    AGE 
aws-node-b9cpr           1/1      Running   0           2d20h 
 ... 
 
# Cluster read-only user can GET pods in test1 namespace 
$ kubectl -n test1 get po 
NAME                     READY    STATUS    RESTARTS    AGE 
nginx-7854ff8877-wnzfs   1/1      Running   0           47s 

# Cluster read-only user cannot DELETE pods in test1 namespace 
$ kubectl -n test1 delete deployment nginx 
Error from server (Forbidden): error when deleting "nginx": deployment "nginx" is forbidden: User "arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/ReadOnly/<SESSION_ID>" cannot delete resource "deployments" in API group in the namespace "test1"

Kubernetes RBAC(역할 기반 액세스 제어)와 함께 클러스터 액세스 항목 사용

앞서 언급한 것처럼 클러스터 액세스 관리 제어 및 관련 API는 Amazon EKS의 기존 RBAC 권한 부여자를 대체하지 않습니다. 대신, Kubernetes RBAC을 사용하여 원하는 권한을 적용하면서 Amazon EKS 액세스 항목을 RBAC 권한 부여자와 결합하여 AWS IAM 보안 주체에 클러스터 액세스 권한을 부여할 수 있습니다.

예를 들어, 다음 Amazon EKS API 명령은 클러스터 액세스 항목을 생성한 후 해당 항목에 Kubernetes 그룹을 추가합니다. kubectl apply 명령으로 Kubernetes 그룹을 클러스터 관리자 ClusterRole 리소스에 바인딩하는 ClusterRoleBinding 리소스를 적용합니다. 그 결과 Kubernetes RBAC을 사용하여 권한이 부여된 클러스터 액세스 항목이 생성됩니다.

# Create cluster access entry
$ aws eks create-access-entry --cluster-name <CLUSTER_NAME> \ 
  --principal-arn <IAM_PRINCIPAL_ARN> \
  --kubernetes-groups eks-admins 

# Apply cluster role binding
# This command assumes you have created crb.yaml from the yaml out of below command
$ kubectl apply -f crb.yaml 

# Get newly created cluster role binding
$ kubectl get cluster-admin-ae 
apiVersion: rbac.authorization.k8s.io/v1 
kind: ClusterRoleBinding 
metadata: 
  name: cluster-admin-ae
roleRef: 
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects: 
- apiGroup: rbac.authorization.k8s.io 
  kind: Group
  name: eks-admins

kubectl auth can-i —list 명령을 사용하여 클러스터 액세스 항목에 클러스터 관리자 권한이 있고 모든 Kubernetes 리소스에서 모든 작업을 수행할 수 있는지 확인할 수 있습니다.

# List Kubernetes permissions for authenticated user
$ kubectl auth can-i —list 
... 
Resources       Non-Resource URLs       Resource Names       Verbs
*.*             []                      []                   [*] 
                [*].                    []                   [*] 
... 

액세스 항목에서 AWS IAM 보안 주체 삭제

다음 create-access-entry 출력 스니펫의 accessEntryArn에서 볼 수 있듯이, 기본 AWS IAM 보안 주체에 대한 클러스터 액세스 항목의 참조는 고유합니다.

"accessEntryArn": "arn:aws:eks:us-west-2:<AWS_ACOUNT_ID>:accessEntry/<CLUSTER_NAME>/role/<AWS_ACCOUNT_ID>/ekstest/c8c3cfab-ad74-8943-9741-1297bb3885b6"

액세스 항목이 생성되면 클러스터 액세스를 유지하는 상태에서 AWS IAM 보안 주체를 변경할 수 없고, 액세스 항목 및 관련 액세스 정책을 다시 생성해야 합니다. 다음 시나리오에서는 다음 설정 단계가 완료 되었다고 가정합니다.

  • ekstest라는 AWS IAM 역할이 생성되었습니다.
  • ekstest 역할을 사용하여 클러스터 액세스 항목을 생성했습니다.
  • 클러스터 액세스 AmazonEKSViewPolicy는 ekstest AWS IAM 역할의 기반이 되는 액세스 항목과 연결되었습니다.

설정 후에는 액세스가 확인됩니다.

# Use whoami to get authenticated principal
$ kubectl whoami 
arn:aws:sts::<AWS_CLUSTER_ID>:assumed-role/ekstest/<SESSION_NAME> 

# GET pods from kube-system namespace 
$ kubectl -n kube-system get po 
NAME              READY    STATUS    RESTARTS    AGE 
aws-node-b9cpr    1/1      Running   0           2d22h
... 

kubectl whoami 플러그인은 현재 인증된 Kubernetes 클러스터 주체를 가리킵니다.

다음으로, ekstest AWS IAM 역할을 삭제하고 재생성한 후, Amazon EKS 클러스터 인증에 다시 사용해봅니다. 다음 명령어는 ekstest AWS IAM 역할이 Amazon EKS 클러스터에 성공적으로 인증 되었지만 액세스 항목은 더 이상 새 ekstest 역할 인스턴스를 승인하지 않는다는 것을 보여줍니다.

# Use whoami to get authenticated principal 
$ kubectl whoami 
Error: Unauthorized 

# Fail to GET pods from the kube-system namespace 
$ kubectl -n kube-system get po 
error: You must be logged in to the server (Unauthorized)

신규 ekstest 역할은 동일한 ARN을 사용하기 때문에 동일하게 보일 수 있지만, 다음 aws iam get-role 명령어에서 리턴되는 RoleId는 다릅니다. 이 RoleId (사용자 주체의 경우 UserId)는 클러스터 액세스 항목 데이터 저장소에서 액세스 항목을 AWS IAM 역할 또는 사용자 보안 주체에 연결하는 데 사용됩니다.

참고: Amazon EKS와 AWS IAM 명령줄 인터페이스(CLI) 권한은 분리되어 있기 때문에 Amazon EKS API는 AWS IAM 보안 주체를 참조하는 데 사용되는 AWS IAM 보안 주체 식별자(RoleId 또는 UserId)를 노출하지 않습니다

# Get AWS IAM role
$ aws iam get-role --role-name ekstest
{
    "Role": {
        "Path": "/",
        "RoleName": "ekstest",
        "RoleId": "<ROLE_ID>",
        "Arn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ekstest",
...
}

기본 AWS IAM 보안 주체를 변경하거나 재생성 할 경우의 모범 사례는 비결정적(non-deterministic) 동작을 방지하고 잘못된 보안 설정을 방지하기 위해 먼저 delete-access-entry 명령어를 통해 특정 Amazon EKS 클러스터에서 액세스 항목을 삭제하는 것입니다. 그 후, AWS IAM 보안 주체가 삭제되고 재생성되면 액세스 항목을 다시 생성하고 필요한 액세스 정책을 연결할 수 있습니다.

결론

Amazon EKS 클러스터 액세스 관리는 현재 Amazon EKS 클러스터에 대한 AWS IAM 보안 주체의 액세스를 관리하는 데 선호되는 수단입니다. 클러스터 액세스 관리를 사용하면 AWS IAM에서 관리하는 보안 주체를 Amazon EKS 액세스 항목으로 계속 활용하고 클러스터 액세스 정책을 통해 Kubernetes 권한을 적용할 수 있습니다. 클러스터 액세스 관리는 표준 API 접근 방식을 사용하여 Amazon EKS 권한 부여자를 통해 Kubernetes AuthZ 모델을 확장합니다. 클러스터 액세스 관리의 풍부한 기능 세트를 함께 사용하면 현재 Amazon EKS에서 사용되는 기존 Kubernetes 보안 체계를 변경하지 않고도 AWS IAM을 통합할 수 있습니다. Kubernetes RBAC 체계는 계속 작동하지만 더 이상 aws-auth ConfigMap을 편집할 필요가 없게 됩니다.

클러스터 액세스 관리를 사용하면 클러스터에 대한 액세스 권한을 잃지 않고 새로 생성된 클러스터에서 클러스터 생성 주체를 제거할 수도 있습니다. 이 기능은 자동화, 최소 권한 원칙 및 시간 기반 접근 관리를 통해 더 나은 DevSecOps사례를 제공합니다.

클러스터 액세스 관리를 사용하면 AuthN용 AWS IAM 보안 주체에 더 깔끔하게 통합할 수 있으면서도 AuthZ 권한은 AWS IAM과 별개이며 잘 알려진 Kubernetes 권한을 모델로 삼았습니다. 즉, AWS IAM을 사용하여 AuthN 보안 주체를 관리할 수 있지만 Amazon EKS 권한은 AWS IAM 권한과 별개입니다. 그 결과 AWS IAM 권한이 Amazon EKS 클러스터 권한에 영향을 주지 않는 보다 유연한 AuthZ 모델이 탄생했습니다.

마지막으로, 클러스터 액세스 관리를 통해 Amazon EKS 관리자는 클러스터 사용자 권한에 대한 라스트 마일 AuthZ 설정을 수행하기 위해 로컬 Kubernetes API로 전환하지 않고도 Amazon EKS API를 사용하여 클러스터 액세스 관리를 수행할 수 있습니다. 이는 Amazon EKS 클러스터를 구축하고 업데이트하는 자동화된 프로세스, 즉 DevSecOps 파이프라인에 대한 더 나은 접근 방식이기도 합니다.

클러스터 액세스 관리를 사용해 보세요

표준 Kubernetes AuthZ 접근 방식을 사용하면서 aws-auth ConfigMap을 회피할 수 있는 방법을 찾고 있다면 클러스터 액세스 관리를 사용해 볼 것을 권장합니다. Amazon EKS 운영 중단을 최소화하면서 필요와 일정에 따라 전환하여 두 모델을 동시에 실행할 수 있습니다.

향후 Amazon EKS의 특정 Kubernetes 버전에서는 지원되는 인증 소스에서 aws-auth ConfigMap이 제거될 예정이므로 액세스 항목으로 마이그레이션할 것을 권장합니다.

컨테이너 로드맵을 확인해 보세요

Amazon EKS 및 기타 컨테이너 서비스를 개선할 수 있는 방법에 대한 아이디어가 있으신 경우, 컨테이너 로드맵을 활용하여 피드백을 제공 해주시거나 기존 로드맵 항목을 확인하실 수 있습니다.

Jini Park

Jini Park

박진이 솔루션즈 아키텍트는 엔터프라이즈 고객을 대상으로 고객이 최적의 솔루션을 선택하여 비즈니스를 개선할 수 있도록 고객과 함께 효율적인 아키텍처를 구성하는 역할을 수행하고 있습니다.

Dongsoo Koo

Dongsoo Koo

구동수 솔루션즈 아키텍트는 디지털 기업 고객을 대상으로 고객의 비즈니스 성과 달성을 위해 고객과 함께 최적의 아키텍처를 구성하는 역할을 수행하고 있습니다.