ID 및 액세스 관리 - Amazon EKS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

ID 및 액세스 관리

Identity and Access Management(IAM)는 인증 및 권한 부여라는 두 가지 필수 기능을 수행하는 AWS 서비스입니다. 인증에는 자격 증명 확인이 수반되는 반면 권한 부여는 AWS 리소스에서 수행할 수 있는 작업을 관리합니다. AWS 내에서 리소스는 EC2와 같은 다른 AWS 서비스이거나 IAM 사용자 또는 역할과 같은 AWS 보안 주체일 수 있습니다. 리소스가 수행할 수 있는 작업을 관리하는 규칙은 IAM 정책으로 표시됩니다.

EKS 클러스터에 대한 액세스 제어

Kubernetes 프로젝트는 베어러 토큰, X.509 인증서, OIDC 등 kube-apiserver 서비스에 대한 요청을 인증하기 위한 다양한 전략을 지원합니다. EKS는 현재 웹후크 토큰 인증, 서비스 계정 토큰 및 2021년 2월 21일부터 OIDC 인증을 기본적으로 지원합니다.

웹후크 인증 전략은 보유자 토큰을 확인하는 웹후크를 호출합니다. EKS에서 이러한 보유자 토큰은 kubectl 명령을 실행할 때 AWS CLI 또는 aws-iam-authenticator 클라이언트에 의해 생성됩니다. 명령을 실행하면 토큰이 kube-apiserver로 전달되어 인증 웹후크로 전달됩니다. 요청이 잘 구성된 경우 웹후크는 토큰 본문에 포함된 미리 서명된 URL을 호출합니다. 이 URL은 요청의 서명을 검증하고 사용자 계정, Arn 및 UserId와 같은 사용자에 대한 정보를 kube-apiserver에 반환합니다.

인증 토큰을 수동으로 생성하려면 터미널 창에 다음 명령을 입력합니다.

aws eks get-token --cluster-name <cluster_name>

프로그래밍 방식으로 토큰을 가져올 수도 있습니다. 다음은 Go로 작성된 예제입니다.

package main import ( "fmt" "log" "sigs.k8s.io/aws-iam-authenticator/pkg/token" ) func main() { g, _ := token.NewGenerator(false, false) tk, err := g.Get("<cluster_name>") if err != nil { log.Fatal(err) } fmt.Println(tk) }

출력은 다음과 비슷해야 합니다.

{ "kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": { "expirationTimestamp": "2020-02-19T16:08:27Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" } }

각 토큰은 로 시작하고 그 k8s-aws-v1. 뒤에 base64 인코딩 문자열이 옵니다. 디코딩할 때 문자열은 다음과 비슷한 것과 유사해야 합니다.

https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393

토큰은 Amazon 자격 증명과 서명을 포함하는 미리 서명된 URL로 구성됩니다. 자세한 내용은 https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html 참조하십시오.

토큰의 TTL(Time To Live)은 15분이며, 그 이후에는 새 토큰을 생성해야 합니다. 이는와 같은 클라이언트를 사용할 때 자동으로 처리kubectl되지만 Kubernetes 대시보드를 사용하는 경우 새 토큰을 생성하고 토큰이 만료될 때마다 다시 인증해야 합니다.

사용자의 자격 증명이 AWS IAM 서비스에 의해 인증되면 kube-apiserver는 kube-system 네임스페이스의 aws-auth ConfigMap을 읽어 사용자와 연결할 RBAC 그룹을 결정합니다. aws-auth ConfigMap은 IAM 보안 주체, 즉 IAM 사용자 및 역할과 Kubernetes RBAC 그룹 간에 정적 매핑을 생성하는 데 사용됩니다. RBAC 그룹은 Kubernetes RoleBindings 또는 ClusterRoleBindings. Kubernetes 리소스(객체) 모음에 대해 수행할 수 있는 작업 세트(동사)를 정의한다는 점에서 IAM 역할과 유사합니다.

클러스터 액세스 관리자

이제 Amazon EKS 클러스터에 대한 AWS IAM 보안 주체의 액세스를 관리하는 기본 방법인 Cluster Access Manager는 AWS API의 기능이며 EKS v1.23 이상 클러스터(신규 또는 기존)에 대한 옵트인 기능입니다. AWS IAM과 Kubernetes RBACs 간의 자격 증명 매핑을 간소화하여 AWS와 Kubernetes APIs 간에 전환하거나 액세스 관리를 위해 aws-auth ConfigMap을 편집할 필요가 없으며 운영 오버헤드를 줄이고 잘못된 구성을 해결하는 데 도움이 됩니다. 또한이 도구를 사용하면 클러스터 관리자가 클러스터를 생성하는 데 사용되는 AWS IAM 보안 주체에 자동으로 부여된 cluster-admin 권한을 취소하거나 세분화할 수 있습니다.

이 API는 다음 두 가지 개념에 의존합니다.

  • 액세스 항목: Amazon EKS 클러스터에 인증할 수 있는 AWS IAM 보안 주체(사용자 또는 역할)에 직접 연결된 클러스터 자격 증명입니다.

  • 액세스 정책: Amazon EKS 클러스터에서 작업을 수행할 수 있는 액세스 항목에 대한 권한을 제공하는 Amazon EKS별 정책입니다.

시작 시 Amazon EKS는 사전 정의된 및 AWS 관리형 정책만 지원합니다. 액세스 정책은 IAM 엔터티가 아니며 Amazon EKS에서 정의 및 관리합니다.

Cluster Access Manager는 API 서버 요청과 관련된 Kubernetes AuthZ 결정에 대한 허용 및 전달(거부 아님)을 지원하는 액세스 정책과 업스트림 RBAC의 조합을 허용합니다. 업스트림 RBAC 및 Amazon EKS 권한 부여자 모두 요청 평가 결과를 확인할 수 없는 경우 거부 결정이 발생합니다.

이 기능을 통해 Amazon EKS는 세 가지 인증 모드를 지원합니다.

  1. CONFIG_MAPaws-auth configMap만 계속 사용합니다.

  2. API_AND_CONFIG_MAP EKS 액세스 항목 APIs와 aws-auth configMap 모두에서 인증된 IAM 보안 주체를 소싱하여 액세스 항목의 우선순위를 지정합니다. 기존 aws-auth 권한을 액세스 항목으로 마이그레이션하는 데 적합합니다.

  3. API는 EKS 액세스 항목 APIs. 이것이 새로운 권장 접근 방식입니다.

시작하기 위해 클러스터 관리자는 Amazon EKS 클러스터를 생성 또는 업데이트하여 기본 인증을 API_AND_CONFIG_MAP 또는 API 메서드로 설정하고 액세스 항목을 정의하여 원하는 AWS IAM 보안 주체에 액세스 권한을 부여할 수 있습니다.

$ 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_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false

위 명령은 클러스터 생성자의 관리자 권한 없이 이미 Amazon EKS 클러스터를 생성하는 예제입니다.

update-cluster-config 명령을 사용하여 API authenticationMode를 활성화하도록 Amazon EKS 클러스터 구성을 업데이트하고,를 사용하여 기존 클러스터에서 업데이트하려면 먼저 로 업데이트API_AND_CONFIG_MAP한 다음 로 업데이트CONFIG_MAP해야 합니다API. 이러한 작업은 되돌릴 수 없습니다. 즉,에서 API_AND_CONFIG_MAP 또는 APICONFIG_MAP전환하거나에서 로 전환할 API_AND_CONFIG_MAP 수 없습니다CONFIG_MAP.

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

API는 클러스터에 대한 액세스를 추가 및 취소하고 지정된 클러스터에 대한 기존 액세스 정책 및 액세스 항목을 검증하는 명령을 지원합니다. 기본 정책은 다음과 같이 Kubernetes RBACs 일치하도록 생성됩니다.

EKS 액세스 정책 Kubernetes RBAC

AmazonEKSClusterAdminPolicy

cluster-admin

AmazonEKSAdminPolicy

admin

AmazonEKSEditPolicy

edit

AmazonEKSViewPolicy

view

$ 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" } ] } $ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] }

기본적으로 생성되는 유일한 항목인 클러스터 생성자 관리자 권한 없이 클러스터를 생성할 때는 액세스 항목을 사용할 수 없습니다.

aws-auth ConfigMap(사용되지 않음)

Kubernetes와 AWS 인증을 통합하는 한 가지 방법은 kube-system 네임스페이스에 있는 aws-auth ConfigMap을 사용하는 것입니다. AWS IAM 자격 증명(사용자, 그룹 및 역할) 인증을 Kubernetes 역할 기반 액세스 제어(RBAC) 권한 부여에 매핑하는 역할을 담당합니다. aws-auth ConfigMap은 프로비저닝 단계에서 Amazon EKS 클러스터에 자동으로 생성됩니다. 처음에는 노드가 클러스터에 조인할 수 있도록 생성되었지만, 언급한 대로이 ConfigMap을 사용하여 IAM 보안 주체에 RBACs 액세스를 추가할 수도 있습니다.

클러스터의 aws-auth ConfigMap을 확인하려면 다음 명령을 사용할 수 있습니다.

kubectl -n kube-system get configmap aws-auth -o yaml

다음은 aws-auth ConfigMap의 기본 구성 샘플입니다.

apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes - system:node-proxier rolearn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/kube-system-<SELF_GENERATED_UUID> username: system:node:{{SessionName}} kind: ConfigMap metadata: creationTimestamp: "2023-10-22T18:19:30Z" name: aws-auth namespace: kube-system

이 ConfigMap의 기본 세션은 기본적으로 3개의 파라미터로 구성된 mapRoles 블록data의 아래에 있습니다.

  • 그룹: IAM 역할을 매핑할 Kubernetes 그룹/그룹입니다. 기본 그룹이거나 clusterrolebinding 또는에 지정된 사용자 지정 그룹일 수 있습니다rolebinding. 위 예제에서는 시스템 그룹만 선언했습니다.

  • rolearn: 다음 형식을 사용하여 Kubernetes 그룹/그룹이 추가하는에 매핑될 AWS IAM 역할의 ARN입니다arn:<PARTITION>:iam::<AWS_ACCOUNT_ID>:role/role-name.

  • username: AWS IAM 역할에 매핑할 Kubernetes 내 사용자 이름입니다. 사용자 지정 이름일 수 있습니다.

AWS IAM 사용자에 대한 권한을 매핑하여 aws-authConfigMap의 data mapUsers에서에 대한 새 구성 블록을 정의하고 userarn에 대한 rolearn 파라미터를 대체할 수도 있지만, 모범 사례로 사용자는 mapRoles 항상 대신 사용하는 것이 좋습니다.

권한을 관리하기 위해 Amazon EKS 클러스터에 대한 액세스 권한을 추가하거나 제거하는 aws-auth ConfigMap을 편집할 수 있습니다. aws-auth ConfigMap을 수동으로 편집할 수 있지만, 이는 매우 민감한 구성이며 부정확한 구성은 Amazon EKS 클러스터 외부에서 사용자를 잠글 수 eksctl있으므로와 같은 도구를 사용하는 것이 좋습니다. 자세한 내용은 아래 aws-auth ConfigMap을 변경하려면 도구 사용 하위 섹션을 참조하세요.

클러스터 액세스 권장 사항

EKS 클러스터 엔드포인트를 프라이빗으로 설정

기본적으로 EKS 클러스터를 프로비저닝할 때 API 클러스터 엔드포인트는 퍼블릭으로 설정됩니다. 즉, 인터넷에서 액세스할 수 있습니다. 인터넷에서 액세스할 수 있지만 모든 API 요청을 IAM에서 인증한 다음 Kubernetes RBAC에서 승인해야 하므로 엔드포인트는 여전히 안전한 것으로 간주됩니다. 즉, 기업 보안 정책에서 인터넷에서 API에 대한 액세스를 제한하도록 요구하거나 클러스터 VPC 외부로 트래픽을 라우팅하지 못하도록 하는 경우 다음을 수행할 수 있습니다.

  • EKS 클러스터 엔드포인트를 프라이빗으로 구성합니다. 이 주제에 대한 자세한 내용은 클러스터 엔드포인트 액세스 수정을 참조하세요.

  • 클러스터 엔드포인트를 퍼블릭으로 두고 클러스터 엔드포인트와 통신할 수 있는 CIDR 블록을 지정합니다. 블록은 클러스터 엔드포인트에 액세스할 수 있는 화이트리스트에 등록된 퍼블릭 IP 주소 집합입니다.

  • 화이트리스트 CIDR 블록 세트를 사용하여 퍼블릭 액세스를 구성하고 프라이빗 엔드포인트 액세스를 활성화됨으로 설정합니다. 이렇게 하면 컨트롤 플레인이 프로비저닝될 때 클러스터 VPC에 프로비저닝되는 교차 계정 ENIs를 통해 kubelet(작업자)과 Kubernetes API 간의 모든 네트워크 트래픽을 강제로 적용하면서 특정 범위의 퍼블릭 IPs에서 퍼블릭 액세스를 허용할 수 있습니다.

인증에 서비스 계정 토큰을 사용하지 마십시오.

서비스 계정 토큰은 수명이 긴 정적 자격 증명입니다. 침해, 분실 또는 도난된 경우 공격자는 서비스 계정이 삭제될 때까지 해당 토큰과 연결된 모든 작업을 수행할 수 있습니다. 경우에 따라 CI/CD 파이프라인 애플리케이션과 같이 클러스터 외부에서 Kubernetes API를 사용해야 하는 애플리케이션에 예외를 부여해야 할 수 있습니다. 이러한 애플리케이션이 EC2 인스턴스와 같은 AWS 인프라에서 실행되는 경우 인스턴스 프로파일을 사용하고 이를 Kubernetes RBAC 역할에 매핑하는 것이 좋습니다.

AWS 리소스에 대한 최소 권한 액세스 사용

IAM 사용자는 Kubernetes API에 액세스하기 위해 AWS 리소스에 권한을 할당받을 필요가 없습니다. IAM 사용자에게 EKS 클러스터에 대한 액세스 권한을 부여해야 하는 경우 해당 사용자의 aws-auth ConfigMap에서 특정 Kubernetes RBAC 그룹에 매핑되는 항목을 생성합니다.

클러스터 생성자 보안 주체에서 클러스터 관리자 권한 제거

기본적으로 Amazon EKS 클러스터는 클러스터 생성자 보안 주체에 바인딩된 영구 cluster-admin 권한으로 생성됩니다. Cluster Access Manager API를 사용하면 API_AND_CONFIG_MAP 또는 API 인증 모드를 사용할 false때를 로 설정하는이 권한 없이 클러스터--access-config bootstrapClusterCreatorAdminPermissions를 생성할 수 있습니다. 클러스터 구성에 대한 원치 않는 변경을 방지하기 위한 모범 사례로 간주되는 액세스를 취소합니다. 이 액세스를 취소하는 프로세스는 동일한 프로세스를 따라 클러스터에 대한 다른 액세스를 취소합니다.

API는 액세스 정책에서 IAM 보안 주체의 연결만 해제할 수 있는 유연성을 제공합니다.이 경우 입니다AmazonEKSClusterAdminPolicy.

$ aws eks list-associated-access-policies \ --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN> $ aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN. \ --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy

또는 cluster-admin 권한과 연결된 액세스 항목을 완전히 제거합니다.

$ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] } $ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN>

클러스터에 액세스할 수 없는 인시던트, 긴급 또는 휴지통 시나리오 중에 필요한 경우이 액세스 권한을 다시 부여할 수 있습니다.

클러스터가 여전히 CONFIG_MAP 인증 방법으로 구성된 경우 모든 추가 사용자에게 aws-auth ConfigMap을 통해 클러스터에 대한 액세스 권한을 부여해야 하며, aws-auth ConfigMap이 구성된 후에는 클러스터를 생성한 엔터티에 할당된 역할을 삭제하고 인시던트, 긴급 또는 휴지통 시나리오가 발생하거나 aws-authConfigMap이 손상되어 클러스터에 액세스할 수 없는 경우에만 다시 생성할 수 있습니다. 이는 프로덕션 클러스터에서 특히 유용할 수 있습니다.

여러 사용자가 클러스터에 대해 동일한 액세스 권한이 필요한 경우 IAM 역할 사용

각 개별 IAM 사용자에 대한 항목을 생성하는 대신 해당 사용자가 IAM 역할을 수임하고 해당 역할을 Kubernetes RBAC 그룹에 매핑하도록 허용합니다. 특히 액세스 권한이 필요한 사용자 수가 증가함에 따라 유지 관리가 더 쉬워집니다.

중요

ConfigMap에 의해 매핑된 IAM aws-auth 엔터티를 사용하여 EKS 클러스터에 액세스할 때 설명된 사용자 이름은 Kubernetes 감사 로그의 사용자 필드에 기록됩니다. IAM 역할을 사용하는 경우 해당 역할을 수임하는 실제 사용자는 기록되지 않으며 감사할 수 없습니다.

여전히 aws-auth configMap을 인증 방법으로 사용하는 경우 IAM 역할에 K8s RBAC 권한을 할당할 때 사용자 이름에 \{{SessionName}}을 포함해야 합니다. 이렇게 하면 감사 로그에 세션 이름이 기록되므로 CloudTrail 로그와 함께 실제 사용자가이 역할을 수임하는 사람을 추적할 수 있습니다.

- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole username: testRole:{{SessionName}} groups: - system:masters

RoleBindings 및 ClusterRoleBindings를 생성할 때 최소 권한 액세스 사용

AWS 리소스에 대한 액세스 권한을 부여하는 것과 마찬가지로 RoleBindings 및 ClusterRoleBindings에는 특정 함수를 수행하는 데 필요한 권한 집합만 포함되어야 합니다. 반드시 필요한 경우가 아니면 역할 및 ClusterRoles["*"]에서를 사용하지 마세요. 할당할 권한이 확실하지 않은 경우 audit2rbac과 같은 도구를 사용하여 역할을 자동으로 생성하고 Kubernetes 감사 로그에서 관찰된 API 호출을 기반으로 바인딩하는 것이 좋습니다.

자동 프로세스를 사용하여 클러스터 생성

이전 단계에서 볼 수 있듯이 Amazon EKS 클러스터를 생성할 때 API_AND_CONFIG_MAP 또는 API 인증 모드를 사용하지 않고 클러스터 생성자에게 cluster-admin 권한을 위임하지 않으면 클러스터를 생성하는 페더레이션 사용자와 같은 IAM 엔터티 사용자 또는 역할에 클러스터의 RBAC 구성에 대한 system:masters 권한이 자동으로 부여됩니다. 여기에 설명된 대로 CONFIG_MAP 인증 방법을 사용하고 aws-authConfigMap을 사용하는 클러스터 생성자 보안 주체에서 클러스터 관리자 권한 제거 경우에도이 액세스는 취소할 수 없습니다. 따라서 다른 사용자 또는 엔터티가 수임할 권한 없이 전용 IAM 역할에 연결된 인프라 자동화 파이프라인을 사용하여 클러스터를 생성하고 파이프라인을 트리거할 수 있는 액세스 권한이 있는이 역할의 권한, 정책을 정기적으로 감사하는 것이 좋습니다. 또한이 역할은 클러스터에서 일상적인 작업을 수행하는 데 사용해서는 안 되며, 예를 들어 SCM 코드 변경을 통해 파이프라인에 의해 트리거된 클러스터 수준 작업에만 사용해야 합니다.

전용 IAM 역할을 사용하여 클러스터 생성

Amazon EKS 클러스터를 생성하면 클러스터를 생성하는 페더레이션 사용자와 같은 IAM 엔터티 사용자 또는 역할에 클러스터의 RBAC 구성에 대한 system:masters 권한이 자동으로 부여됩니다. 이 액세스는 제거할 수 없으며 aws-auth ConfigMap을 통해 관리되지 않습니다. 따라서 전용 IAM 역할로 클러스터를 생성하고이 역할을 수임할 수 있는 사람을 정기적으로 감사하는 것이 좋습니다. 이 역할은 클러스터에서 일상적인 작업을 수행하는 데 사용해서는 안 되며, 대신이 목적으로 aws-auth ConfigMap을 통해 클러스터에 대한 액세스 권한을 추가 사용자에게 부여해야 합니다. aws-auth ConfigMap을 구성한 후에는 역할을 보호해야 하며 클러스터에 액세스할 수 없는 시나리오의 경우 임시 승격된 권한 모드/중단 창에서만 사용해야 합니다. 이는 직접 사용자 액세스가 구성되지 않은 클러스터에서 특히 유용할 수 있습니다.

클러스터에 대한 액세스를 정기적으로 감사

액세스가 필요한 사람은 시간이 지남에 따라 변경될 수 있습니다. aws-auth ConfigMap을 정기적으로 감사하여 액세스 권한이 부여된 사람과 할당된 권한을 확인할 계획입니다. kubectl-who-can 또는 rbac-lookup과 같은 오픈 소스 도구를 사용하여 특정 서비스 계정, 사용자 또는 그룹에 바인딩된 역할을 검사할 수도 있습니다. 감사에 대한 섹션으로 이동하면이 주제를 자세히 살펴보겠습니다. 추가 아이디어는 NCC 그룹의이 문서에서 확인할 수 있습니다.

aws-auth configMap에 의존하는 경우 도구를 사용하여 변경합니다.

aws-auth ConfigMap 형식이 잘못 지정되면 클러스터에 대한 액세스 권한이 손실될 수 있습니다. ConfigMap을 변경해야 하는 경우 도구를 사용합니다.

eksctl eksctl CLI에는 aws-auth ConfigMap에 자격 증명 매핑을 추가하는 명령이 포함되어 있습니다.

CLI 도움말 보기:

$ eksctl create iamidentitymapping --help ...

Amazon EKS 클러스터에 매핑된 자격 증명을 확인합니다.

$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION ARN USERNAME GROUPS ACCOUNT arn:aws:iam::788355785855:role/kube-system-<SELF_GENERATED_UUID> system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier

IAM 역할을 클러스터 관리자로 설정:

$ eksctl create iamidentitymapping --cluster <CLUSTER_NAME> --region=<region> --arn arn:aws:iam::123456:role/testing --group system:masters --username admin ...

자세한 내용은 eksctl 문서를 검토하세요.

keikoproj의 aws-auth

aws-auth by keikoproj에는 cli와 go 라이브러리가 모두 포함되어 있습니다.

도움말 다운로드 및 보기 CLI 도움말:

$ go get github.com/keikoproj/aws-auth ... $ aws-auth help ...

또는 kubectl용 krew 플러그인 관리자aws-auth를 사용하여를 설치합니다.

$ kubectl krew install aws-auth ... $ kubectl aws-auth ...

go 라이브러리를 포함한 자세한 내용은 GitHub의 aws-auth 문서를 검토하세요.

AWS IAM Authenticator CLI

aws-iam-authenticator 프로젝트에는 ConfigMap을 업데이트하기 위한 CLI가 포함되어 있습니다.

GitHub에서 릴리스를 다운로드합니다.

IAM 역할에 클러스터 권한 추가:

$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config ...

인증 및 액세스 관리에 대한 대체 접근 방식

IAM은 EKS 클러스터에 액세스해야 하는 사용자를 인증하는 선호되는 방법이지만 인증 프록시 및 Kubernetes 위장을 사용하여 GitHub와 같은 OIDC 자격 증명 공급자를 사용할 수 있습니다. https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation 이러한 두 솔루션의 게시물은 AWS 오픈 소스 블로그에 게시되었습니다.

중요

EKS는 기본적으로 프록시를 사용하지 않고 OIDC 인증을 지원합니다. 자세한 내용은 시작 블로그인 Amazon EKS에 대한 OIDC 자격 증명 공급자 인증 소개를 참조하세요. 다양한 인증 방법에 대한 커넥터가 있는 인기 있는 오픈 소스 OIDC 공급자인 Dex로 EKS를 구성하는 방법을 보여주는 예는 Dex & dex-k8s-authenticator를 사용하여 Amazon EKS에 인증하기를 참조하세요. 블로그에 설명된 대로 OIDC 공급자가 인증한 사용자 이름/사용자 그룹이 Kubernetes 감사 로그에 표시됩니다.

AWS SSO를 사용하여 Azure AD와 같은 외부 자격 증명 공급자와 AWS를 페더레이션할 수도 있습니다. 이를 사용하기로 결정한 경우 AWS CLI v2.0에는 SSO 세션을 현재 CLI 세션과 쉽게 연결하고 IAM 역할을 수임할 수 있는 명명된 프로파일을 생성하는 옵션이 포함되어 있습니다. IAM 역할이 사용자의 Kubernetes RBAC 그룹을 결정하는 데 사용kubectl되므로를 실행하기 전에 역할을 수임해야 합니다.

EKS 포드의 자격 증명 및 자격 증명

Kubernetes 클러스터 내에서 실행되는 특정 애플리케이션은 Kubernetes API를 호출하여 제대로 작동하려면 권한이 필요합니다. 예를 들어 AWS Load Balancer Controller는 서비스의 엔드포인트를 나열할 수 있어야 합니다. 또한 컨트롤러는 AWS APIs를 호출하여 ALB를 프로비저닝하고 구성할 수 있어야 합니다. 이 섹션에서는 포드에 권한과 권한을 할당하는 모범 사례를 살펴봅니다.

Kubernetes 서비스 계정

서비스 계정은 포드에 Kubernetes RBAC 역할을 할당할 수 있는 특수한 유형의 객체입니다. 클러스터 내의 각 네임스페이스에 대해 기본 서비스 계정이 자동으로 생성됩니다. 특정 서비스 계정을 참조하지 않고 포드를 네임스페이스에 배포하면 해당 네임스페이스의 기본 서비스 계정이 포드에 자동으로 할당되고 보안 암호, 즉 해당 서비스 계정의 서비스 계정(JWT) 토큰이 포드에의 볼륨으로 마운트됩니다/var/run/secrets/kubernetes.io/serviceaccount. 해당 디렉터리에서 서비스 계정 토큰을 디코딩하면 다음 메타데이터가 표시됩니다.

{ "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "default", "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", "sub": "system:serviceaccount:default:default" }

기본 서비스 계정에는 Kubernetes API에 대한 다음과 같은 권한이 있습니다.

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2020-01-30T18:13:25Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "43" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery uid: 350d2ab8-438c-11ea-9438-063a49b60fba rules: - nonResourceURLs: - /api - /api/* - /apis - /apis/* - /healthz - /openapi - /openapi/* - /version - /version/ verbs: - get

이 역할은 인증되지 않고 인증된 사용자에게 API 정보를 읽을 수 있는 권한을 부여하며 공개적으로 액세스할 수 있는 안전한 것으로 간주됩니다.

포드 내에서 실행되는 애플리케이션이 Kubernetes APIs를 호출할 때 해당 API를 호출할 수 있는 권한을 명시적으로 부여하는 서비스 계정을 포드에 할당해야 APIs. 사용자 액세스 지침과 마찬가지로 서비스 계정에 바인딩된 역할 또는 ClusterRole은 애플리케이션이 작동하는 데 필요한 API 리소스 및 메서드로 제한되어야 합니다. 기본이 아닌 서비스 계정을 사용하려면 포드의 spec.serviceAccountName 필드를 사용하려는 서비스 계정의 이름으로 설정하면 됩니다. 서비스 계정 생성에 대한 자세한 내용은 https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions 참조하십시오.

참고

Kubernetes 1.24 이전에는 Kubernetes가 각 서비스 계정에 대한 보안 암호를 자동으로 생성합니다. 이 보안 암호는 /var/run/secrets/kubernetes.io/serviceaccount 포드에 탑재되었으며 포드가 Kubernetes API 서버에 인증하는 데 사용됩니다. Kubernetes 1.24에서는 포드가 실행될 때 서비스 계정 토큰이 동적으로 생성되며 기본적으로 1시간 동안만 유효합니다. 서비스 계정의 보안 암호는 생성되지 않습니다. Jenkins와 같이 Kubernetes API에 인증해야 하는 클러스터 외부에서 실행되는 애플리케이션이 있는 경우와 같은 서비스 계정을 참조하는 주석과 kubernetes.io/service-account-token 함께 유형의 보안 암호를 생성해야 합니다metadata.annotations.kubernetes.io/service-account.name: <SERVICE_ACCOUNT_NAME>. 이러한 방식으로 생성된 보안 암호는 만료되지 않습니다.

서비스 계정에 대한 IAM 역할(IRSA)

IRSA는 Kubernetes 서비스 계정에 IAM 역할을 할당할 수 있는 기능입니다. 서비스 계정 토큰 볼륨 프로젝션이라는 Kubernetes 기능을 활용하여 작동합니다. IAM 역할을 참조하는 서비스 계정으로 포드를 구성하면 Kubernetes API 서버가 시작 시 클러스터에 대한 퍼블릭 OIDC 검색 엔드포인트를 호출합니다. 엔드포인트는 Kubernetes에서 발급한 OIDC 토큰과 볼륨으로 마운트된 결과 토큰에 암호화 방식으로 서명합니다. 이 서명된 토큰을 사용하면 포드가 AWS APIs 관련 IAM 역할을 호출할 수 있습니다. AWS API가 호출되면 AWS SDKs 호출합니다sts:AssumeRoleWithWebIdentity. 토큰의 서명을 검증한 후 IAM은 Kubernetes에서 발급한 토큰을 임시 AWS 역할 자격 증명으로 교환합니다.

IRSA를 사용할 때는 AWS SDK 세션을 재사용하여 AWS STS에 대한 불필요한 호출을 방지하는 것이 중요합니다.

IRSA용 (JWT) 토큰을 디코딩하면 아래 표시된 예제와 유사한 출력이 생성됩니다.

{ "aud": [ "sts.amazonaws.com" ], "exp": 1582306514, "iat": 1582220114, "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "kubernetes.io": { "namespace": "default", "pod": { "name": "alpine-57b5664646-rf966", "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" }, "serviceaccount": { "name": "s3-read-only", "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" } }, "nbf": 1582220114, "sub": "system:serviceaccount:default:s3-read-only" }

이 특정 토큰은 IAM 역할을 수임하여 포드 보기 전용 권한을 S3에 부여합니다. 애플리케이션이 S3에서 읽기를 시도하면 토큰이 다음과 유사한 임시 IAM 자격 증명 세트로 교환됩니다.

{ "AssumedRoleUser": { "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" }, "Audience": "sts.amazonaws.com", "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oesl1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZeuE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0Hbi/PWAtlI8YJcDX69cM30JAHDdQHltm/4scFptW1hlvMaPWReCAaCrsHrATyka7ttw5YlUyvZ8EPogj6fwHlxmrXM9h1BqdikomyJU00gm1FJelfP1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkWsCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZGCkyDLIa8MBn9KPXeJd/yjTk5IifIwO/mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVCM+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } }

EKS 컨트롤 플레인의 일부로 실행되는 변형 웹후크는 AWS 역할 ARN과 웹 자격 증명 토큰 파일의 경로를 환경 변수로 포드에 주입합니다. 이러한 값은 수동으로 제공할 수도 있습니다.

AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token

kubelet은 총 TTL의 80%보다 오래된 경우 또는 24시간 후에 프로젝션된 토큰을 자동으로 교체합니다. AWS SDKs는 교체 시 토큰을 다시 로드할 책임이 있습니다. IRSA에 대한 자세한 내용은 https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html 참조하십시오.

EKS Pod Identity

EKS Pod Identity는 re:Invent 2023에서 시작된 기능으로, AWS 계정의 각 클러스터에 대해 Open Id Connect(OIDC) ID 제공업체(IDP)를 구성할 필요 없이 kubernetes 서비스 계정에 IAM 역할을 할당할 수 있습니다. EKS Pod Identity를 사용하려면 모든 적격 작업자 노드에서 DaemonSet 포드로 실행되는 에이전트를 배포해야 합니다. 이 에이전트는 EKS 추가 기능으로 사용할 수 있으며 EKS Pod Identity 기능을 사용하기 위한 사전 조건입니다. 이 기능을 사용하려면 애플리케이션에서 지원되는 버전의 AWS SDK를 사용해야 합니다.

포드에 대해 EKS 포드 ID가 구성되면 EKS는에서 포드 ID 토큰을 탑재하고 새로 고칩니다/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token. 이 토큰은 AWS SDK에서 EKS Pod Identity Agent와 통신하는 데 사용됩니다.이 에이전트는 포드 자격 증명 토큰과 에이전트의 IAM 역할을 사용하여 AssumeRoleForPodIdentity API를 호출하여 포드에 대한 임시 자격 증명을 생성합니다. 포드에 전달되는 포드 자격 증명 토큰은 EKS 클러스터에서 발급되고 암호화 방식으로 서명된 JWT이며 EKS 포드 자격 증명과 함께 사용할 수 있는 적절한 JWT 클레임을 포함합니다.

EKS Pod Identity에 대한 자세한 내용은 이 블로그를 참조하세요.

EKS Pod Identity를 사용하기 위해 애플리케이션 코드를 수정할 필요는 없습니다. 지원되는 AWS SDK 버전은 자격 증명 공급자 체인을 사용하여 EKS Pod Identity에서 사용할 수 있는 자격 증명을 자동으로 검색합니다. IRSA와 마찬가지로 EKS 포드 자격 증명은 포드 내에서 변수를 설정하여 AWS 자격 증명을 찾는 방법을 안내합니다.

EKS Pod Identity에 대한 IAM 역할 작업

  • EKS Pod Identity는 EKS 클러스터와 동일한 AWS 계정에 속한 IAM 역할만 직접 수임할 수 있습니다. 다른 AWS 계정의 IAM 역할에 액세스하려면 SDK 구성 또는 애플리케이션 코드에서 프로필을 구성하여 해당 역할을 수임해야 합니다. https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html

  • 서비스 계정에 대해 EKS Pod Identity를 구성하는 경우 Pod Identity Association을 구성하는 사람 또는 프로세스에 해당 역할에 대한 iam:PassRole 권한이 있어야 합니다.

  • 각 서비스 계정에는 EKS Pod Identity를 통해 연결된 IAM 역할이 하나만 있을 수 있지만 동일한 IAM 역할을 여러 서비스 계정과 연결할 수 있습니다.

  • EKS Pod Identity와 함께 사용되는 IAM 역할은 pods.eks.amazonaws.com 서비스 보안 주체가 이를 수임하고 세션 태그를 설정할 수 있도록 허용해야 합니다. 다음은 EKS Pod Identity가 IAM 역할을 사용하도록 허용하는 역할 신뢰 정책의 예입니다.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ], "Condition": { "StringEquals": { "aws:SourceOrgId": "${aws:ResourceOrgId}" } } } ] }

AWS는 교차 서비스 혼동된 대리자 문제를 방지하기 aws:SourceOrgId 위해와 같은 조건 키를 사용할 것을 권장합니다. 위 예제 역할 신뢰 정책에서 ResourceOrgId는 AWS 계정이 속한 AWS Organization의 AWS Organizations Organization ID와 동일한 변수입니다. EKS는 EKS Pod Identity로 역할을 수임할 때와 aws:SourceOrgId 동일한 값을 전달합니다.

ABAC 및 EKS 포드 ID

EKS Pod Identity가 IAM 역할을 맡으면 다음 세션 태그를 설정합니다.

EKS Pod Identity 세션 태그

kubernetes-네임스페이스

EKS Pod Identity와 연결된 포드가 실행되는 네임스페이스입니다.

kubernetes-service-account

EKS Pod Identity와 연결된 kubernetes 서비스 계정의 이름입니다.

eks-cluster-arn

EKS 클러스터의 ARN, 예: . arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName} 클러스터 ARN은 고유하지만 동일한 AWS 계정 내에서 동일한 이름의 동일한 리전에서 클러스터가 삭제되고 다시 생성되면 동일한 ARN을 갖게 됩니다.

eks-cluster-name

EKS 클러스터의 이름입니다. EKS 클러스터 이름은 AWS 계정과 다른 AWS 계정의 EKS 클러스터 내에서 동일할 수 있습니다.

kubernetes-pod-name

EKS의 포드 이름입니다.

kubernetes-pod-uid

EKS에 있는 포드의 UID입니다.

이러한 세션 태그를 사용하면 속성 기반 액세스 제어(ABAC)를 사용하여 AWS 리소스에 대한 액세스 권한을 특정 kubernetes 서비스 계정에만 부여할 수 있습니다. 이때 kubernetes 서비스 계정은 네임스페이스 내에서만 고유하고 kubernetes 네임스페이스는 EKS 클러스터 내에서만 고유하다는 점을 이해하는 것이 매우 중요합니다. 이러한 세션 태그는 다음과 같은 aws:PrincipalTag/<tag-key> 전역 조건 키를 사용하여 AWS 정책에서 액세스할 수 있습니다. aws:PrincipalTag/eks-cluster-arn

예를 들어 IAM 또는 리소스 정책을 사용하여 계정의 AWS 리소스에 액세스할 수 있도록 특정 서비스 계정에만 액세스 권한을 부여하려면 다른 클러스터eks-cluster-arn가 및를 가질 수 있으므로 의도한 클러스터의 해당 서비스 계정만 해당 리소스에 액세스할 수 kubernetes-service-account 있도록 kubernetes-service-accountskubernetes-namespace 태그를 확인해야 합니다kubernetes-namespaces.

이 예제 S3 버킷 정책은 ,이 kubernetes-service-account kubernetes-namespace eks-cluster-arn 모두 예상 값을 충족하는 경우에만 연결된 S3 버킷의 객체에 대한 액세스 권한을 부여합니다. 여기서 EKS 클러스터는 AWS 계정에서 호스팅됩니다111122223333.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::ExampleBucket/*" ], "Condition": { "StringEquals": { "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" } } } ] }

EKS Pod Identity와 IRSA 비교

EKS Pod Identity와 IRSA는 모두 임시 AWS 자격 증명을 EKS 포드에 전달하는 데 선호되는 방법입니다. IRSA에 대한 특정 사용 사례가 없는 한 EKS를 사용할 때는 EKS Pod Identity를 사용하는 것이 좋습니다. 이 표는 두 기능을 비교하는 데 도움이 됩니다.

# EKS Pod Identity IRSA

AWS 계정에서 OIDC IDP를 생성할 수 있는 권한이 필요합니까?

아니요

클러스터당 고유한 IDP 설정 필요

아니요

ABAC와 함께 사용할 관련 세션 태그를 설정합니다.

아니요

iam:PassRole 검사가 필요합니까?

아니요

AWS 계정에서 AWS STS 할당량을 사용하나요?

아니요

다른 AWS 계정에 액세스할 수 있음

역할 체인을 사용하여 간접적으로

sts:AssumeRoleWithWebIdentity를 사용하여 직접

AWS SDKs와 호환

노드에 Pod Identity Agent Daemonset이 필요합니까?

아니요

EKS 포드 권장 사항에 대한 자격 증명 및 자격 증명

IRSA를 사용하도록 aws-node 데몬 세트 업데이트

현재 aws-node 데몬 세트는 EC2 인스턴스에 할당된 역할을 사용하여 포드에 IPs 할당하도록 구성됩니다. 이 역할에는 AmazonEKS_CNI_Policy 및 EC2ContainerRegistryReadOnly와 같은 여러 AWS 관리형 정책이 포함되어 있습니다.이 정책은 노드에서 실행되는 모든 포드가 ENIs를 연결/분리하거나, IP 주소를 할당/할당 해제하거나, ECR에서 이미지를 가져올 수 있도록 효과적으로 허용합니다. 이는 클러스터에 위험을 초래하므로 IRSA를 사용하도록 aws-node 데몬 세트를 업데이트하는 것이 좋습니다. 이를 위한 스크립트는이 가이드의 리포지토리에서 찾을 수 있습니다.

aws-node 데몬 세트는 버전 v1.15.5 이상에서 EKS Pod Identity를 지원합니다.

작업자 노드에 할당된 인스턴스 프로파일에 대한 액세스 제한

IRSA 또는 EKS Pod Identity를 사용하는 경우 먼저 IRSA 또는 EKS Pod Identity를 사용하도록 포드의 자격 증명 체인을 업데이트하지만 포드는 여전히 작업자 노드에 할당된 인스턴스 프로파일의 권한을 상속할 수 있습니다. 이러한 권한이 필요하지 않은 포드의 경우 인스턴스 메타데이터에 대한 액세스를 차단하여 애플리케이션이 노드가 아닌 필요한 권한만 갖도록 할 수 있습니다.

주의

인스턴스 메타데이터에 대한 액세스를 차단하면 IRSA 또는 EKS Pod Identity를 사용하지 않는 포드가 작업자 노드에 할당된 역할을 상속하지 못합니다.

아래 예제와 같이 인스턴스가 IMDSv2만 사용하도록 하고 홉 수를 1로 업데이트하여 인스턴스 메타데이터에 대한 액세스를 차단할 수 있습니다. 노드 그룹의 시작 템플릿에 이러한 설정을 포함할 수도 있습니다. 인스턴스 메타데이터를 비활성화하면 노드 종료 핸들러 및 인스턴스 메타데이터에 의존하는 기타 사물과 같은 구성 요소가 제대로 작동하지 않습니다.

$ aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1 ...

Terraform을 사용하여 관리형 노드 그룹에 사용할 시작 템플릿을 생성하는 경우 메타데이터 블록을 추가하여이 코드 조각에 표시된 대로 홉 수를 구성합니다.

tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" …​ metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } …​

노드에서 iptable을 조작하여 EC2 메타데이터에 대한 포드의 액세스를 차단할 수도 있습니다. 이 방법에 대한 자세한 내용은 인스턴스 메타데이터 서비스에 대한 액세스 제한을 참조하세요.

IRSA 또는 EKS Pod Identity를 지원하지 않는 이전 버전의 AWS SDK를 사용하는 애플리케이션이 있는 경우 SDK 버전을 업데이트해야 합니다.

IRSA 역할에 대한 IAM 역할 신뢰 정책의 범위를 서비스 계정 이름, 네임스페이스 및 클러스터로 지정합니다.

신뢰 정책은 네임스페이스 또는 네임스페이스 내의 특정 서비스 계정으로 범위가 지정될 수 있습니다. IRSA를 사용할 때는 서비스 계정 이름을 포함하여 역할 신뢰 정책을 최대한 명시적으로 만드는 것이 가장 좋습니다. 이렇게 하면 동일한 네임스페이스 내의 다른 포드가 역할을 수임하는 것을 효과적으로 방지할 수 있습니다. CLI는 이를 사용하여 서비스 계정/IAM 역할을 생성할 때 이를 자동으로 eksctl 수행합니다. 자세한 내용은 https://eksctl.io/usage/iamserviceaccounts/ 참조하십시오.

IAM을 직접 사용할 때 조건을 사용하는 역할의 신뢰 정책에 조건을 추가하여 :sub 클레임이 예상한 네임스페이스 및 서비스 계정인지 확인합니다. 예를 들어, 이전에는 하위 클레임이 "system:serviceaccount:default:s3-read-only"인 IRSA 토큰이 있었습니다. 이는 default 네임스페이스이고 서비스 계정은 입니다s3-read-only. 다음과 같은 조건을 사용하여 클러스터의 지정된 네임스페이스에 있는 서비스 계정만 해당 역할을 수임할 수 있도록 합니다.

"Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" } }

애플리케이션당 하나의 IAM 역할 사용

IRSA와 EKS Pod Identity를 모두 사용하면 각 애플리케이션에 고유한 IAM 역할을 부여하는 것이 가장 좋습니다. 이렇게 하면 다른 애플리케이션에 영향을 주지 않고 한 애플리케이션을 수정할 수 있으므로 격리가 개선되고 애플리케이션에 필요한 권한만 부여하여 최소 권한의 보안 주체를 적용할 수 있습니다.

EKS Pod Identity와 함께 ABAC를 사용하는 경우 여러 서비스 계정에서 공통 IAM 역할을 사용하고 액세스 제어를 위해 세션 속성에 의존할 수 있습니다. 이는 대규모로 운영할 때 특히 유용합니다. ABAC를 사용하면 더 적은 IAM 역할로 운영할 수 있기 때문입니다.

애플리케이션에서 IMDS에 액세스해야 하는 경우 IMDSv2를 사용하고 EC2 인스턴스의 홉 제한을 2로 늘립니다.

IMDSv2에서는 PUT 요청을 사용하여 세션 토큰을 가져와야 합니다. 초기 PUT 요청에는 세션 토큰에 대한 TTL이 포함되어야 합니다. 최신 버전의 AWS SDKs 이러한 토큰과 해당 토큰의 갱신을 자동으로 처리합니다. 또한 IP 전달을 방지하기 위해 EC2 인스턴스의 기본 홉 제한이 의도적으로 1로 설정되어 있다는 점에 유의해야 합니다. 결과적으로 EC2 인스턴스에서 실행되는 세션 토큰을 요청하는 포드는 결국 시간이 초과되어 IMDSv1 데이터 흐름 사용으로 대체될 수 있습니다. EKS는 v1과 v2를 모두 활성화하고 eksctl에서 프로비저닝하거나 공식 CloudFormation 템플릿을 사용하여 노드에서 홉 제한을 2로 변경하여 IMDSv2 지원을 추가합니다. CloudFormation

서비스 계정 토큰의 자동 탑재 비활성화

애플리케이션이 Kubernetes API를 호출할 필요가 없는 경우 automountServiceAccountToken 속성을 애플리케이션의 PodSpecfalse에서 로 설정하거나 포드에 더 이상 자동으로 마운트되지 않도록 각 네임스페이스의 기본 서비스 계정을 패치합니다. 예:

kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'

각 애플리케이션에 전용 서비스 계정 사용

각 애플리케이션에는 자체 전용 서비스 계정이 있어야 합니다. 이는 Kubernetes API와 IRSA 및 EKS Pod Identity의 서비스 계정에 적용됩니다.

중요

IRSA를 사용할 때 현재 위치 클러스터 업그레이드를 수행하는 대신 클러스터 업그레이드에 블루/그린 접근 방식을 사용하는 경우 각 IRSA IAM 역할의 신뢰 정책을 새 클러스터의 OIDC 엔드포인트로 업데이트해야 합니다. 블루/그린 클러스터 업그레이드에서는 이전 클러스터와 함께 최신 버전의 Kubernetes를 실행하는 클러스터를 생성하고 로드 밸런서 또는 서비스 메시를 사용하여 이전 클러스터에서 실행되는 서비스에서 새 클러스터로 트래픽을 원활하게 이동할 수 있습니다. EKS Pod Identity와 함께 블루/그린 클러스터 업그레이드를 사용하는 경우 새 클러스터의 IAM 역할과 서비스 계정 간에 포드 ID 연결을 생성합니다. 그리고 sourceArn 조건이 있는 경우 IAM 역할 신뢰 정책을 업데이트합니다.

루트가 아닌 사용자로 애플리케이션 실행

컨테이너는 기본적으로 루트로 실행됩니다. 이렇게 하면 웹 자격 증명 토큰 파일을 읽을 수 있지만 컨테이너를 루트로 실행하는 것은 모범 사례로 간주되지 않습니다. 또는 PodSpec에 spec.securityContext.runAsUser 속성을 추가하는 것이 좋습니다. 의 값은 임의 값runAsUser입니다.

다음 예제에서는 포드 내의 모든 프로세스가 runAsUser 필드에 지정된 사용자 ID로 실행됩니다.

apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ]

루트가 아닌 사용자로 컨테이너를 실행하면 토큰에 기본적으로 0600 [루트] 권한이 할당되므로 컨테이너가 IRSA 서비스 계정 토큰을 읽지 못합니다. fsgroup=65534 [Nobody]를 포함하도록 컨테이너의 securityContext를 업데이트하면 컨테이너가 토큰을 읽을 수 있습니다.

spec: securityContext: fsGroup: 65534

Kubernetes 1.19 이상에서는이 변경이 더 이상 필요하지 않으며 애플리케이션은 아무도 없음 그룹에 추가하지 않고도 IRSA 서비스 계정 토큰을 읽을 수 있습니다.

애플리케이션에 대한 최소 권한 액세스 권한 부여

Action Hero는 애플리케이션과 함께 실행하여 애플리케이션이 제대로 작동하는 데 필요한 AWS API 호출 및 해당 IAM 권한을 식별할 수 있는 유틸리티입니다. 애플리케이션에 할당된 IAM 역할의 범위를 점진적으로 제한하는 데 도움이 된다는 점에서 IAM Access Advisor와 유사합니다. 자세한 내용은 AWS 리소스에 대한 최소 권한 액세스 권한 부여에 대한 설명서를 참조하세요.

IRSA 및 포드 ID와 함께 사용되는 IAM 역할에 권한 경계를 설정하는 것이 좋습니다. 권한 경계를 사용하여 IRSA 또는 포드 자격 증명에서 사용하는 역할이 최대 권한 수준을 초과하지 않도록 할 수 있습니다. 권한 경계 정책 예제를 사용하여 권한 경계를 시작하는 방법에 대한 예제 가이드는이 github 리포지토리를 참조하세요.

EKS 클러스터에 대한 불필요한 익명 액세스 검토 및 취소

모든 API 작업에 대해 이상적으로는 익명 액세스를 비활성화해야 합니다. 익명 액세스는 Kubernetes 기본 제공 사용자 시스템:익명에 대한 RoleBinding 또는 ClusterRoleBinding을 생성하여 부여됩니다. rbac-lookup 도구를 사용하여 system:anonymous user가 클러스터에 대해 갖는 권한을 식별할 수 있습니다.

./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' system:anonymous cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer

system:public-info-viewer 이외의 모든 역할 또는 ClusterRole은 system:anonymous user 또는 system:unauthenticated 그룹에 바인딩되어서는 안 됩니다.

특정 APIs. 클러스터의 경우 익명 사용자가 특정 APIs에만 액세스할 수 있도록 하고 인증 없이 해당 APIs 노출해도 클러스터가 취약하지 않도록 합니다.

Kubernetes/EKS 버전 1.14 이전에는 system:unauthenticated 그룹이 기본적으로 system:discovery 및 system:basic-user ClusterRoles에 연결되었습니다. 클러스터를 버전 1.14 이상으로 업데이트한 경우에도 클러스터 업데이트가 이러한 권한을 취소하지 않으므로 클러스터에서 이러한 권한이 계속 활성화될 수 있습니다. system:public-info-viewer를 제외한 "system:unauthenticated"가 있는 ClusterRoles를 확인하려면 다음 명령을 실행할 수 있습니다(jq 유틸리티 필요).

kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name'

또한 다음을 사용하여 "system:unauthenticated"를 제외한 모든 역할에서 "system:public-info-viewer"를 제거할 수 있습니다.

kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f -

또는 kubectl describe 및 kubectl edit을 사용하여 수동으로 확인하고 제거할 수 있습니다. system:unauthenticated 그룹에 클러스터에 대한 system:discovery 권한이 있는지 확인하려면 다음 명령을 실행합니다.

kubectl describe clusterrolebindings system:discovery Name: system:discovery Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:discovery Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated

system:unauthenticated 그룹에 클러스터에 대한 system:basic-user 권한이 있는지 확인하려면 다음 명령을 실행합니다.

kubectl describe clusterrolebindings system:basic-user Name: system:basic-user Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:basic-user Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated

system:unauthenticated 그룹이 클러스터의 system:discovery 및/또는 system:basic-user ClusterRoles에 바인딩된 경우 system:unauthenticated 그룹에서 이러한 역할을 연결 해제해야 합니다. 다음 명령을 사용하여 system:discovery ClusterRoleBinding을 편집합니다.

kubectl edit clusterrolebindings system:discovery

위 명령은 아래와 같이 편집기에서 system:discovery ClusterRoleBinding의 현재 정의를 엽니다.

# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2021-06-17T20:50:49Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "24502985" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery uid: b7936268-5043-431a-a0e1-171a423abeb6 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:discovery subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:authenticated - apiGroup: rbac.authorization.k8s.io kind: Group name: system:unauthenticated

위의 편집기 화면의 "제목" 섹션에서 system:unuthenticated 그룹에 대한 항목을 삭제합니다.

system:basic-user ClusterRoleBinding에 대해 동일한 단계를 반복합니다.

IRSA를 사용하여 AWS SDK 세션 재사용

IRSA를 사용하는 경우 AWS SDK를 사용하여 작성된 애플리케이션은 포드에 전달된 토큰을 사용하여를 호출sts:AssumeRoleWithWebIdentity하여 임시 AWS 자격 증명을 생성합니다. 이는 컴퓨팅 서비스가 임시 AWS 자격 증명을 Lambda 함수와 같은 AWS 컴퓨팅 리소스에 직접 전달하는 다른 AWS 컴퓨팅 서비스와 다릅니다. 즉, AWS SDK 세션이 초기화될 때마다에 대한 AWS STS 호출AssumeRoleWithWebIdentity이 이루어집니다. 애플리케이션이 빠르게 확장되고 많은 AWS SDK 세션을 초기화하는 경우 코드가를 많이 호출하므로 AWS STS에서 제한이 발생할 수 있습니다AssumeRoleWithWebIdentity.

이 시나리오를 방지하려면에 대한 불필요한 호출AssumeRoleWithWebIdentity이 이루어지지 않도록 애플리케이션 내에서 AWS SDK 세션을 재사용하는 것이 좋습니다.

다음 예제 코드에서 세션은 boto3 python SDK를 사용하여 생성되며 동일한 세션은 클라이언트를 생성하고 Amazon S3 및 Amazon SQS와 상호 작용하는 데 사용됩니다. AssumeRoleWithWebIdentity는 한 번만 호출되며 AWS SDK는 자동으로 만료될 my_session 때의 자격 증명을 새로 고칩니다.

import boto3 = Create your own session my_session = boto3.session.Session() = Now we can create low-level clients from our session sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') s3response = s3.list_buckets() sqsresponse = sqs.list_queues() #print the response from the S3 and SQS APIs print("`s3 response:`") print(s3response) print("`—`") print("`sqs response:`") print(sqsresponse) ```

EC2와 같은 다른 AWS 컴퓨팅 서비스에서 IRSA를 사용하는 EKS로 애플리케이션을 마이그레이션하는 경우 이는 특히 중요한 세부 정보입니다. AWS SDK 세션을 초기화하는 다른 컴퓨팅 서비스에서는 사용자가 지시하지 않는 한 AWS STS를 호출하지 않습니다.

대체 접근 방식

IRSA 및 EKS Pod Identity는 포드에 AWS 자격 증명을 할당하는 데 선호되는 방법이지만 애플리케이션에 최신 버전의 AWS SDKs를 포함해야 합니다. 현재 IRSA를 지원하는 SDKs의 전체 목록은 https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, EKS Pod Identity는 https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html 참조하십시오. 호환되는 SDK로 즉시 업데이트할 수 없는 애플리케이션이 있는 경우 kube2iamkiam을 포함하여 Kubernetes 포드에 IAM 역할을 할당하는 데 사용할 수 있는 몇 가지 커뮤니티 구축 솔루션이 있습니다. AWS는 이러한 솔루션을 승인, 허용 또는 지원하지 않지만 커뮤니티에서는 IRSA 및 EKS Pod Identity와 유사한 결과를 얻기 위해 이러한 솔루션을 자주 사용합니다.

aws에서 제공하지 않는 이러한 솔루션 중 하나를 사용해야 하는 경우 실사를 수행하고 그렇게 하면 보안에 미치는 영향을 이해해야 합니다.

도구 및 리소스