eksctl은 AWS의 관리형 쿠버네티스 서비스인 EKS 클러스터를 생성하고 관리하는 CLI 도구입니다. 내부적으로는 CloudFormation 이라는 AWS의 리소스 프로비저닝 서비스를 사용하여, EKS 구성에 필요한 EC2, IAM Role 등의 AWS 리소스를 자동으로 생성합니다. eksctl을 사용하기 위해서는 클러스터에 접속하기 위한 서버로 사용되는 bastion host에 AWS의 리소스를 사용하기 위한 AWS CLI 설정이 되어 있어야 하고, 설정한 사용자(User) 혹은 역할(Role)이 eksctl을 사용하는데 필요한 IAM 권한을 가지고 있어야 합니다.
이번 글에서는 eksctl을 사용하여 EKS 클러스터를 구성하는 방법을 살펴보겠습니다. 클러스터에 접근하기 위한 bastion host로 AWS EC2 (Amazon LInux 2, t2.micro)를 1대 생성하여 사용하였습니다.
prerequisites
- AWS 계정 (필수)
- AWS CLI 사용 방법
- AWS IAM에 대한 이해
- 쿠버네티스의 기본 아키텍처 개념
※ AWS EKS는 AWS의 유료 서비스이므로 비용이 발생할 수 있습니다.
※ 본문에서 다루는 클러스터 구성은 기본값으로 생성된 예제이므로, 실제 운영 환경에서 사용하기 위한 클러스터를 구축하기에는 적합하지 않습니다.
준비 단계
1. kubectl 설치
먼저 쿠버네티스의 API 서버와 통신하기 위한 CLI 도구인 kubectl 바이너리를 설치합니다. curl 로 바이너리 파일을 받은 다음, 실행 권한 및 PATH 설정을 해 줍니다. 각 설치 단계에 대해 상세히 알고 싶다면 kubectl 설치 문서를 참고합니다.
$ curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 44.2M 100 44.2M 0 0 2651k 0 0:00:17 0:00:17 --:--:-- 3769k
$ chmod +x ./kubectl
$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
$ echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
$ kubectl version --short --client
Client Version: v1.21.2-13+d2965f0db10712
2. eksctl 설치
eksctl 역시 유사한 방법으로 설치합니다. 각 설치 단계에 대한 정보는 eksctl 설치를 참고합니다.
$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version
0.94.0
3. AWS IAM 설정
EKS와 연관된 AWS 리소스를 생성하기 위해서는 리소스 생성을 요청하는 사용자(User) 혹은 역할(Role)이 그 리소스를 생성할 수 있는 IAM 권한을 가지고 있어야 합니다. 루트 계정이 아니라면 해당 IAM 사용자 혹은 역할이 다음 네가지 정책을 가지고 있어야 합니다.
- AmazonEC2FullAccess (AWS Managed Policy)
- AWSCloudFormationFullAccess (AWS Managed Policy)
- EksAllAccess
- IamLimitedAccess
4가지 중 위 2개 정책은 AWS Managed 정책이므로 이미 생성되어 있습니다. 따라서 EksAllAccess 및 IamLimitedAccess 2개 정책만 별도로 생성합니다. IAM 정책 생성의 JSON 탭에서 정책 만들기를 참고하여 2개 정책을 추가합니다. 정책의 JSON 문서는 Minimum IAM policies에서 확인할 수 있습니다.
그 다음, 4가지 정책을 eksctl을 사용하려는 사용자, 사용자그룹 혹은 역할 자격 증명에 추가합니다.
4. AWS CLI 설정
모든 권한이 부여되었다면, 이제 bastion host에 AWS CLI 명령을 사용하기 위한 구성 및 자격 증명 파일을 설정할 차례입니다. aws configure 명령을 사용하며, 설정할 때에는 액세스 키 및 비밀 액세스 키 정보가 필요합니다. 키 정보를 확인하고 생성하는 방법은 IAM 사용자의 액세스 키 관리문서의 액세스 키 관리(콘솔) 섹션을 참고합니다.
$ aws configure
AWS Access Key ID [None]: AKIAABCDEFGH12345678 # Sample Access Key
AWS Secret Access Key [None]: ABCDefg12p3jo14jpoa23op41po231p3 # Sample Secret Access Key
Default region name [None]: ap-northeast-2
Default output format [None]: json
자격 증명 정보가 올바르게 설정되었다면, 홈 디렉토리의 .aws 디렉토리 아래 2개 파일이 생성된 것을 확인할 수 있습니다. 구성 옵션은 config 파일에, 자격 증명 정보는 credentials 파일에 기록됩니다. eksctl은 이 정보를 사용하여 AWS 리소스 생성 요청을 하게 됩니다.
$ cat .aws/config
[default]
output = json
region = ap-northeast-2
$ cat .aws/credentials
[default]
aws_access_key_id = AKIAABCDEFGH12345678
aws_secret_access_key = ABCDefg12p3jo14jpoa23op41po231p3
EKS 클러스터 생성
모든 준비가 끝났습니다. 이제 eksctl을 사용하여 간단한 예제 EKS 클러스터를 생성해보겠습니다. eksctl을 사용하면 아래 한줄의 명령어로 EKS 클러스터를 생성할 수 있습니다.
$ eksctl create cluster --name my-sample-cluster --region ap-northeast-2
2022-04-26 07:46:30 [ℹ] eksctl version 0.94.0
2022-04-26 07:46:30 [ℹ] using region ap-northeast-2
2022-04-26 07:46:30 [ℹ] setting availability zones to [ap-northeast-2a ap-northeast-2d ap-northeast-2c]
2022-04-26 07:46:30 [ℹ] subnets for ap-northeast-2a - public:192.168.0.0/19 private:192.168.96.0/19
2022-04-26 07:46:30 [ℹ] subnets for ap-northeast-2d - public:192.168.32.0/19 private:192.168.128.0/19
2022-04-26 07:46:30 [ℹ] subnets for ap-northeast-2c - public:192.168.64.0/19 private:192.168.160.0/19
2022-04-26 07:46:30 [ℹ] nodegroup "ng-4dd3dfbd" will use "" [AmazonLinux2/1.21]
2022-04-26 07:46:30 [ℹ] using Kubernetes version 1.21
2022-04-26 07:46:30 [ℹ] creating EKS cluster "my-sample-cluster" in "ap-northeast-2" region with managed nodes
2022-04-26 07:46:30 [ℹ] will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
2022-04-26 07:46:30 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-2 --cluster=my-sample-cluster'
2022-04-26 07:46:30 [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "my-sample-cluster" in "ap-northeast-2"
2022-04-26 07:46:30 [ℹ] CloudWatch logging will not be enabled for cluster "my-sample-cluster" in "ap-northeast-2"
2022-04-26 07:46:30 [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-2 --cluste
r=my-sample-cluster'
2022-04-26 07:46:30 [ℹ]
2 sequential tasks: { create cluster control plane "my-sample-cluster",
2 sequential sub-tasks: {
wait for control plane to become ready,
create managed nodegroup "ng-4dd3dfbd",
}
}
2022-04-26 07:46:30 [ℹ] building cluster stack "eksctl-my-sample-cluster-cluster"
2022-04-26 07:46:30 [ℹ] deploying stack "eksctl-my-sample-cluster-cluster"
2022-04-26 07:47:00 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-cluster"
2022-04-26 07:47:30 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-cluster"
...
2022-04-26 07:57:31 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-cluster"
2022-04-26 07:58:31 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-cluster"
2022-04-26 08:00:32 [ℹ] building managed nodegroup stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
2022-04-26 08:00:32 [ℹ] deploying stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
2022-04-26 08:00:32 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
2022-04-26 08:00:47 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
...
2022-04-26 08:03:35 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
2022-04-26 08:03:51 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-4dd3dfbd"
2022-04-26 08:03:51 [ℹ] waiting for the control plane availability...
2022-04-26 08:03:51 [✔] saved kubeconfig as "/home/ec2-user/.kube/config"
2022-04-26 08:03:51 [ℹ] no tasks
2022-04-26 08:03:51 [✔] all EKS cluster resources for "my-sample-cluster" have been created
2022-04-26 08:03:51 [ℹ] nodegroup "ng-4dd3dfbd" has 2 node(s)
2022-04-26 08:03:51 [ℹ] node "ip-192-168-46-231.ap-northeast-2.compute.internal" is ready
2022-04-26 08:03:51 [ℹ] node "ip-192-168-83-87.ap-northeast-2.compute.internal" is ready
2022-04-26 08:03:51 [ℹ] waiting for at least 2 node(s) to become ready in "ng-4dd3dfbd"
2022-04-26 08:03:51 [ℹ] nodegroup "ng-4dd3dfbd" has 2 node(s)
2022-04-26 08:03:51 [ℹ] node "ip-192-168-46-231.ap-northeast-2.compute.internal" is ready
2022-04-26 08:03:51 [ℹ] node "ip-192-168-83-87.ap-northeast-2.compute.internal" is ready
2022-04-26 08:03:53 [ℹ] kubectl command should work with "/home/ec2-user/.kube/config", try 'kubectl get nodes'
2022-04-26 08:03:53 [✔] EKS cluster "my-sample-cluster" in "ap-northeast-2" region is ready
맨 아래 EKS cluster is ready 문구가 출력되면 EKS 클러스터 생성이 정상적으로 완료된 것입니다. 클러스터가 Ready 상태가 되기까지 약 17분이 소요된 것을 확인할 수 있습니다.
CloudFormation 스택 확인
eksctl의 출력 로그를 살펴볼 수도 있지만, 보다 정확하게 어떤 AWS 리소스가 생성되었는지 확인하기 위해 AWS 웹 콘솔에서 CloudFormation 스택을 확인해봅시다.
eksctl이 2개의 CloudFormation 스택을 생성했습니다. 생성 시간을 보면 -cluster로 끝나는 EKS 컨트롤 플레인을 프로비저닝하는 스택이 먼저 생성된 것을 확인할 수 있습니다. 이 스택부터 살펴보겠습니다.
무려 34개의 AWS 리소스가 EKS 클러스터를 프로비저닝하기위해 생성된 것을 볼 수 있습니다. EKS Cluster 뿐만 아니라 클러스터가 위치할 리전의 VPC, 노드가 위치할 Subnet, 쿠버네티스 클러스터가 사용할 IAM Role과 IAM Policy, 인터넷 접근을 위한 NAT Gateway와 Internet Gateway, 컨트롤 플레인 전용 및 클러스터 전체 공유 2가지 Security Group 등이 생성되었습니다.
노드그룹을 프로비저닝하는 스택은 이름에 nodegroup이 포함되어 있으며, 상대적으로 훨씬 간단합니다. EKS의 노드 프로비저닝 및 수명 주기 관리를 자동화하는 ManagedNodeGroup, 노드용 EC2 인스턴스 시작에 필요한 구성정보를 포함하는 LaunchTemplate, 각 노드의 IAM Role 3가지 리소스로 스택이 구성되어 있습니다.
kubectl 사용해보기
다시 bastion host로 돌아와서 kubectl 명령어를 사용해서 클러스터의 노드 정보를 조회해보겠습니다. 생성된 2개의 노드가 정상적으로 잘 조회가 되는 모습입니다. 이제 클러스터를 사용할 준비가 되었습니다.
$ kubectl get no
NAME STATUS ROLES AGE VERSION
ip-192-168-46-231.ap-northeast-2.compute.internal Ready <none> 32m v1.21.5-eks-9017834
ip-192-168-83-87.ap-northeast-2.compute.internal Ready <none> 32m v1.21.5-eks-9017834
만약 예제와 달리 인터넷 접근을 허용하지 않는 Private Cluster를 구축하고 싶다면 어떻게 해야 할까요? 또한 서울 리전의 가용 영역 4개를 모두 사용하는 클러스터를 프로비저닝 할 수는 없을까요? 물론 기본 설정이 아니라, 사용자가 정의한 구성을 적용하여 EKS 클러스터를 생성할 수도 있습니다. 사용자 정의 클러스터를 생성하는 방법에 대해서는 여기를 참고하세요.
EKS 클러스터 삭제
클러스터와 노드의 사용을 끝낸 후에는 다음 명령으로 클러스터를 삭제합니다. 그렇지 않으면 EKS 및 EC2 비용이 지속적으로 발생할 수 있습니다.
$ eksctl delete cluster --name my-sample-cluster --region ap-northeast-2
2022-04-26 07:38:44 [ℹ] eksctl version 0.94.0
2022-04-26 07:38:44 [ℹ] using region ap-northeast-2
2022-04-26 07:38:44 [ℹ] deleting EKS cluster "my-sample-cluster"
2022-04-26 07:38:44 [ℹ] will drain 0 unmanaged nodegroup(s) in cluster "my-sample-cluster"
2022-04-26 07:38:45 [ℹ] deleted 0 Fargate profile(s)
2022-04-26 07:38:45 [✔] kubeconfig has been updated
2022-04-26 07:38:45 [ℹ] cleaning up AWS load balancers created by Kubernetes objects of Kind Service or Ingress
2022-04-26 07:38:46 [ℹ]
2 sequential tasks: { delete nodegroup "ng-e7cd9950", delete cluster control plane "my-sample-cluster" [async]
}
2022-04-26 07:38:46 [ℹ] will delete stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950"
2022-04-26 07:38:46 [ℹ] waiting for stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950" to get deleted
2022-04-26 07:38:46 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950"
2022-04-26 07:39:02 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950"
...
2022-04-26 07:42:14 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950"
2022-04-26 07:42:34 [ℹ] waiting for CloudFormation stack "eksctl-my-sample-cluster-nodegroup-ng-e7cd9950"
2022-04-26 07:42:35 [ℹ] will delete stack "eksctl-my-sample-cluster-cluster"
2022-04-26 07:42:35 [✔] all cluster resources were deleted
References
[1] https://eksctl.io/usage/minimum-iam-policies/
[2] https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/getting-started-eksctl.html
'Cloud > AWS' 카테고리의 다른 글
[AWS EKS] API서버 flag 값 확인하기 (0) | 2022.05.17 |
---|---|
[AWS 기초] Cloud Practitioner Essential (0) | 2022.05.10 |
[AWS 기초] #9 마이그레이션 및 혁신 (0) | 2021.11.09 |
[AWS 기초] #8 요금 및 지원 (0) | 2021.11.09 |
[AWS 기초] #7 모니터링 및 분석 (0) | 2021.11.09 |
댓글