0부터 시작하는 AWS 공부 - EKS 구축하기 - EKS 구축 & IAM

Jaehong Lee·2023년 4월 8일
3
post-thumbnail

1. IAM

IAM 이란

AWS의 리소스에 대한 개별적으로 접근 제어와 권한을 가지도록 계정 OR 그룹을 생성하는 서비스

IAM의 기능

  • AWS 계정 관리 및 리소스 / 유저 / 서비스에 대한 권한 제어
  • 권한 부여 및 서비스 사용에 대한 인증 정보 부여
  • 유저 생성 및 관리
  • 다른 유저와 리소스 공유

정책 VS 역할

  • 정책과 역할의 가장 큰 차이점은 권한 획득 기간이다. 정책은 회수하기 전까지 계속해서 획득하고 있지만, 역할은 지정한 시간동안만 획득하게 된다
  • 이로 인해, 역할은 지정 시간 후 자동으로 권한이 회수되는 장점을 가지고 있다
  • 정책은 역할, 사용자, 그룹에 부여된다

EKS & IAM

EKS에서는 IAM 을 통해 인증 & 인가를 한다

  • API SERVER에 접근하기 위한 인증 & 인가 정보를 담고 있는 Kubeconfig 내용을 확인하면, IAM에 대한 인증 정보를 토큰 값으로 저장하고 있다
  1. 사용자가 API SERVER에 명령을 보내면, 먼저 IAM을 통해 클러스터에 접근할 수 있는 사용자인지 인증한다

  2. 이후, RBAC를 통해 사용자에게 해당 명령이 허가되있는지 인가한다

  3. 인증 & 인가를 통과하면, Admission Control을 통해 적절한 요청인지 확인한다. Admission Control는 관리자 정책에 따라 세부적인 작업을 제한하거나, 변경하는 것이다

    • 비유하자면, 인가는 작업 수행할 수 있는 권한을 확인, Admission Control은 관리자가 추가로 특정 행동을 제한하거나 변경하는 것

EKS & 정책

참조 : https://whchoi98.gitbook.io/aws-iam/iam-policy
참조 : https://velog.io/@bbkyoo/Amazon-EKS%EB%9E%80
참조 : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/security-iam-awsmanpol.html

정책은 AWS에서 생성 및 관리하는 정책인 AWS 관리형 정책 / 사용자가 생성 및 관리하는 고객 관리형 정책 / 단일 사용자, 그룹, 역할에 직접 추가하는 방식인 AWS 인라인 정책으로 나뉜다

EKS와 관련된 AWS 관리형 정책에 대해 알아보자

  • AmazonEKS_CNI_Policy : AWS CNI가 EKS에서 동작하는 Pod에 네트워크를 제공하기 위해, 워커 노드의 IP 주소 설정 변경에 필요한 권한들이 담긴 정책

  • AmazonEKSClusterPolicy : 클러스터가 오토스케일링, EC2, ELB, IAM 등 다른 AWS 서비스를 호출하기 위한 권한들이 담긴 정책. 예를 들어, 이 정책이 있어야 EBS 볼륨을 동적으로 프로비저닝 및 관리할 수 있으며, ELB를 동적으로 프로비저닝 할 수 있다

    • EKS에서 서비스인 LB를 배포하면, 자동적으로 AWS의 ELB가 생성된다
    kind: Service
    metadata:
      name: thisislb
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
        service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-09cb84f01fb487e40,subnet-023760585c7ddb14f
    • 위와 같이 LB 서비스 배포시, ELB 종류와 배치될 Subnet을 선택할 수 있다
    • 서비스 배포 후, 생성되는 ELB DNS 주소에 접속하면 Pod에 잘 접속된다. 위 사진은 nlb를 배포한 예시이다
  • AmazonEKSWorkerNodePolicy : 워커노드에 EKS 클러스터에 연결할 수 있는 권한이 담긴 정책

  • AmazonEC2ContainerRegistryReadOnly : ECR에서 이미지를 가져오기 위한 권한이 담긴 정책

  • AWSLoadBalancerControllerIAMPolicy : 클러스터에서 인그레스를 배포할 때, AWS의 ALB나 NLB 인그레스를 사용하기 위한 컨트롤러인 AWS Load Balancer Controller를 위한 권한이 담긴 정책

    • 우리는 NGINX 인그레스를 사용하므로 위 정책이 필요 없지만, 알아만 두자

EKS 작업용 정책 생성

Cli를 통해 EKS만 제어할 수 있는 정책을 생성하자

  • 정책 생성을 누르자

  • 서비스로 EKS를 선택하고, 작업은 모든 EKS 작업을 선택하자

  • 모든 리소스를 선택하자

HMJ-EKS-USER-POLICY를 생성하자

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "eks:*",
            "Resource": "*"
        }
    ]
}
  • json으로 확인하면 위와 같다

IAM 계정 생성 & 역할 부여

IAM 계정을 생성하자. 해당 계정은 EKS 작업용 계정으로, 콘솔 접근이 불가능하며, Cli를 통해 EKS 작업만 가능해야 한다

  • 사용자 이름을 설정하자
  • 콘솔 접근이 불가능해야 하므로, AWS Management Console에 대한 사용자 액세스 권한 제공은 체크 해제하자

  • 계정을 생성하고, 위에서 생성한 정책을 부여하자

  • 콘솔 접근 권한을 제공하지 않았으므로, 콘솔로 접근할 수 없다

Access Key 생성

  • 생성한 사용자에 들어가서 보안 증명 자격을 선택하자

  • Access Key를 만들어주자

  • Cli 선택

  • 생성했으면, CSV 파일을 꼭 다운 받자

2. EKS Cluster

Cluster IAM 역할 생성

  • 역할을 만들어주자

  • AWS 서비스를 선택하자

  • 사용 사례는 EKS - Cluster 를 선택하자

  • 부여되는 정책은 AmazonEKSClusterPolicy 이다

  • 이름을 설정하고, 역할을 생성하자

Control Node 보안 그룹 생성

EKS 에서 사용하는 일반적인 주요 포트는 다음과 같다

  • TCP 443 : kube-api-server
  • TCP 10250 : kubelet api
  • TCP / UDP 53 : coredns, dns

EKS에서는 443으로 kubelet api 통신이 가능하므로 443 포트에 대해서만 설정하면 된다

  • Control Node 용 보안 그룹을 생성하자

  • 인바운드 규칙을 생성하자
  • Bastion Host에서 Kube Api Server에 접근할 수 있도록, 443번 포트만 인바운드 허용해주자
  • 추가적인 규칙은 아래에서 NODE GROUP 보안 그룹을 생성하고 추가할 것이다

Bastion Host의 보안 그룹에 들어가자

  • Control Node 보안 그룹을 향해 443번 포트에서 HTTPS를 사용하여 트래픽을 보내는 아웃바운드 규칙을 추가해주자

EKS 클러스터 생성

  • 이름과 버전, 역할을 선택해주자

  • VPC와 ENI가 배치되는 서브넷, 보안그룹을 선택하자
  • 서브넷은 워커 노드가 배치되는 서브넷이 아니라, 워커 노드와 통신하기 위해 사용되는 서브넷이다. 우리는 구조상, Private Subnet 두 곳에 배치하자

  • 클러스터 엔드포인트 액세스를 선택해주자. 우리는 Bastion Host를 거쳐서만 EKS API 엔드포인트에 접속할 수 있도록 Private을 선택하자
  • Public : 외부망에서 EKS API 엔드포인트에 연결 가능
  • Public & Private : 외부망, VPC의 연결된 네트워크 내에서 EKS API 엔드포인트에 액세스 가능
  • Private : VPC의 연결된 네트워크에서만 EKS API 엔드포인트에 연결 가능

추가 설정 없이 생성해주자!

  • 생성하게 되면 Cluster 보안 그룹이 자동으로 생성된다
  • 해당 보안 그룹은 Cluster 내의 Control Plane과 Node Group의 통신에 대한 안전 장치이다. 이 안전 장치를 통해 Cluter 내에서 Control과 Worker가 무조건 통신이 가능하게 한다

OIDC 자격 증명 공급자 생성

EKS 클러스터에서 추가 기능을 사용할 경우, 추가할 기능에 대한 정책을 OIDC 자격 증명 공급자를 통해 EKS OIDC와 연결해야 한다

  • 이를 통해 K8S의 Service Account가 추가 기능에 대한 IAM 리소스에 액세스할 수 있다

OpenID Connect는 권한 허가 프로토콜인 OAuth 2.0 기술을 이용하여 만들어진 인증 레이어이다. 이를 통해 손쉽게 외부 서비스를 통해 사용자 인증을 구현할 수 있다

참조 : https://hudi.blog/open-id/

  • OIDC은 인증이 주 목적이고, OAuth는 인가가 주 목적이다
  • OIDC는 인증이 주 목적이기에, OAuth보다 인증 과정이 빠르고, 간단하다

IAM 정책을 EKS OIDC와 연결해주기 위해선, OIDC 자격 증명 공급자를 사용하는 역할을 생성하고, 해당 역할에 IAM 정책을 부여해야 한다. 이를 위해서 OIDC 자격 증명 공급자를 생성하자

  • OIDC 공급자 URL을 복사하자

  • IAM -> 자격 증명 공급자 -> 공급자 추가에 들어가자
  • OIDC를 선택하고, URL을 붙여넣자
  • 붙여넣기 후에 지문 가져오기를 눌러주자

  • 대상으로 sts.amazonaws.com을 입력하자

공급자를 추가해주자

  • 생성한 OIDC 자격 증명 공급자의 ID를 잘 기억하자

CNI IAM 역할 생성 및 적용

생성한 EKS 클러스터에서 추가 기능인 AWS VPC CNI를 사용하려면, OIDC 자격 증명 공급자를 사용하는 역할을 생성하고, 해당 역할에 CNI 정책을 부여해야 한다. 이를 통해 EKS OIDC와 CNI 정책을 연결할 수 있다. 생성한 역할은 AWS VPC CNI에 부여해야 한다

  • 역할 만들기에 들어가자
  • 생성한 OIDC 자격 증명 공급자와 대상을 선택하자

  • 부여할 정책으로 EKS_CNI_Policy를 선택하자

역할을 생성해주자. 이제 신뢰 관계 편집을 해주어야 한다

  • 신뢰 관계는 역할을 맡을 수 있는 보안 주체와 조건을 정의한다

  • 생성한 역할의 요약에 들어가 신뢰 관계 편집을 눌러주자
"Condition": {
                "StringEquals": {
                    "oidc.eks.ap-northeast-2.amazonaws.com/id/****************:aud": "sts.amazon.com"
                }
            }
  • 위 부분을 찾자. 해당 부분은 OIDC 자격 증명 공급자의 대상이 sts.amazon.com인지 확인하는 부분이다. 자격 증명 공급자 생성 시, 웹 자격 증명 부분에서 Audience로 sts.amazon.com을 지정했기 때문에, 위 부분은 없어도 상관 없다. 따라서 해당 부분을 아래와 같이 바꿔주자
  • StringEquals 은 Key와 Value를 비교하는 것이다. 즉, OIDC 자격 증명 공급자의 Audience가 sts.amazon.com인지 확인하는 것이다
"Condition": {
                "StringEquals": {
                    "oidc.eks.ap-northeast-2.amazonaws.com/id/****************:sub": "system:serviceaccount:kube-system:aws-node"
                }
            }
  • 위와 같이 바꿔주면 된다
  • OIDC 자격 증명 공급자의 SUB 부분과 system:serviceaccount:kube-system:aws-node가 일치하는지 확인하는 것이다
"Condition": {
                "StringEquals": {
                    "oidc.eks.ap-northeast-2.amazonaws.com/id/****************:aud": "sts.amazon.com",
                    "oidc.eks.ap-northeast-2.amazonaws.com/id/****************:sub": "system:serviceaccount:kube-system:aws-node"
                }
            }
  • aud 비교 부분을 바꾸지 않고, 위와 같이 추가해도 된다

정책을 업데이트 하고, EKS 콘솔에 들어가자

  • 구성 -> 추가 기능에 들어가서 vpc-cni를 선택하고, 편집을 눌러주자

  • 생성한 역할을 부여해주자

3. EKS Node Group

Node Group IAM 역할 생성

  • 역할을 생성해주자

  • 2 가지 정책을 연결해주자. 해당 정책에 대한 설명은 위에 IAM 란에 있다

NODE GROUP 보안 그룹

  • 보안그룹을 생성하자

  • API SERVER 및 Kubelet API 용 443 번 포트에 대한 인바운드 규칙을 추가하자. 소스는 Control Node 보안 그룹이다
  • NODE GROUP에 속한 노드끼리 통신이 가능해야 하므로, 스스로에 대해 모든 트래픽 인바운드를 허용하자. 소스는 NODE GROUP 보안 그룹이다

Control Plane 보안 그룹에 들어가자

  • NODE GROUP 보안 그룹에 대해 443번 포트에 대한 인바운드 규칙을 추가해주자
  • 해당 포트를 통해 Control Plane의 Api-Server가 Worker Node들의 Kubelet과 통신한다

전체 보안 그룹 확인

최종적인 보안 그룹 설정은 다음과 같다

보안 그룹 구조

  • 주요 보안 그룹 구조는 위 그림과 같다
  1. Bastion Host에 대한 ssh 접근 ( 22 ) - 외부 사용자
  2. Control Node의 Api Server 접근 ( 443 ) - Bastion Host와 Worker Node
  3. Worker Node의 Kubelet 접근 ( 443 ) - Control Node

  • Bastion Host 보안 그룹
  • 단, 아웃바운드에서 모든 주소에 대해 모든 트래픽을 허용하는 규칙은 위험하다
    • 해당 규칙을 아직 허용한 이유는 aws cli를 통해 aws eks에 접근하여 kubeconfig를 가져오기 위한 것이다. 따라서, 모든 작업자가 kubeconfig를 가져왔다면, 아래와 같이 해당 규칙을 삭제하자
    • 위와 같이 모든 트래픽에 대한 아웃바운드 규칙을 삭제하더라도 EKS 클러스터의 API SERVER를 향한 아웃바운드 트래픽은 허용했기에 EKS 사용에는 문제없다 ( 443 )
    • AWS CLI는 TCP 포트 443에서 HTTPS를 사용하여 AWS 서비스에 요청을 보낸다

  • Control Node 보안 그룹

  • NodeGroup 보안 그룹

NODE GROUP 생성

EKS 콘솔에 들어가자

  • 노드 그룹 추가를 눌러주자

  • 이름과 역할을 선택하자

  • 서브넷은 Private 서브넷 2 개를 지정하자

  • SSH 액세스를 허용하고, 미리 생성한 KEY-PAIR & 보안 그룹을 선택하자
  • 액세스를 허용하고, NODE GROUP을 생성하게 되면 remote access라는 보안 그룹이 생기는데, 이는 NODE GROUP에 속한 NODE끼리 SSH 접속을 허용하는 보안 그룹이다

다른 사양이나 설정은 기본 설정을 사용한다. 이제 NODE GROUP을 생성해주자

  • 잘 생성됬는지 EKS 콘솔창에 들어가 확인하자

접속하기

Kubernetes 작업용 IAM 계정을 만들었지만, 이를 허용하는 것은 클러스터를 생성한 계정만 가능하다. 클러스터를 생성한 계정으로 일단 접속하자

### aws configure
AWS Access Key ID [None]: 계정 액세스 키 입력
AWS Secret Access Key [None]: 계정 시크릿 액세스 키 입력
Default region name [None]:
Default output format [None]:
  • AWS Access Key 정보를 세팅하자
  • aws configure를 통해 입력한 credential 정보는 AWS에 프로그래밍적인 접근을 할 때 인증정보로 사용된다
aws eks update-kubeconfig \
--region ap-northeast-2 \
--name 클러스터이름
[ec2-user@ip-192-168-11-50 .kube]$ kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-12-162.ap-northeast-2.compute.internal   Ready    <none>   33m   v1.25.7-eks-a59e1f0
ip-192-168-13-69.ap-northeast-2.compute.internal    Ready    <none>   33m   v1.25.7-eks-a59e1f0
  • node 상태를 확인하자

잘 접속된다!!!


EKS에 IAM USER 추가하기는 다음 편에서 이어진다

profile
멋진 엔지니어가 될 때까지

0개의 댓글