[AWS] Amazon EKS 소개 및 기본사용법

2019년1월 11일에 한국사용자들이 많은 요청과 고대를 하였던 Amazon EKS가 서울리전에 출시되어서 그 사용을 위한 사전 준비사항과 초기 구성에 대해 여기서 소개해 드리고자 합니다.

Amazon EKS 소개

Kubernetes는 컨테이너로 애플리케이션을 배포, 관리하는 것을 자동화할 수 있고 주로 대규모 서비스에서 사용하는 구글에서 개발한 오픈 소스 시스템입니다. Kubernetes는 AWS, GCP, Azure등 다양한 벤더 환경에서 원활히 동작하며 도커 외에도 다양한 컨테이너들을 지원하고 있어 최근 급격히 사용이 늘고 있습니다. 사실상의 대세가 된 Kubernetes를 Amazon에서도 적극 수용해서, Amazon EKS관리형 서비스를 출시하여 Kubernetes를 제어 플레인을 직접 구성하지 않고서도 손쉽게 사용할 수 있도록 편리함을 제공하고 있습니다. 사실 Kubernetes를 사용할 때 반드시 Amazon EKS를 사용할 필요는 없지만, AWS에서 제공하는 ELB, IAM, VPC등 특정 기능들을 같이 활용하고자 할 때는 무척 유용합니다.

Amazon EKS 사전 준비

역할 생성

IAM>Roles>Create role의 서비스 목록에서 EKS를 선택하고 사용사례에 "EKS에서 사용자를 대신하여 클러스터를 관리하도록 허용"을 선택하고 마지막 단계에서 역할이름에 "eksServiceRole"을 입력하고 역할생성을 합니다.

클러스터 용 VPC 생성

– Cloud Formation을 사용하여 클러스터 용 VPC, Subnet, Security Group을 생성합니다.
1. Cloud Formation>Create stack>템플릿 선택: Amazon S3 템플릿 URL 지정을 선택하고 아래 URL을 붙여 넣습니다.

https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-01-09/amazon-eks-vpc-sample.yaml

주의! 2019-01-09 이전 날짜의 템플릿파일을 서울리전에서 사용시 오류가 있습니다. (3번째 AZ가 없는 관계로)

2. 세부정보지정 페이지에서 스택이름 예:"mytest-eks"를 입력합니다. VPC주소범위나 Subnet 주소범위도 여기서 지정할 수 있습니다.

3. 마지막 단계에서 Create를 선택하면, 자동으로 VPC, Subnet, Security Group이 생성됩니다.

kubectl 설치 및 설정

1. Amazon EKS용 kubectl 설치
다양한 OS별 자세한 설치 방법은 여기를 참고하여 주시기 바랍니다. 여기서는 관리자용 클라이언트로 별도의 EC2를 생성하여 설치하도록 하겠습니다. 별도의 계정이나 VPC에서 Amazon Linux 2 AMI로 저사양의 EC2를 먼저 생성하고 SSH접속 후 아래 과정대로 진행합니다.

Linux 환경에서 kubectl 설치:

# curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.11.5/2018-12-06/bin/linux/amd64/kubectl
# chmod +x kubectl
# mv kubectl /usr/bin/
# kubectl version –short –client
Client Version: v1.11.5

aws-iam-authenticator 설치:

# curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.11.5/2018-12-06/bin/linux/amd64/aws-iam-authenticator
# chmod +x aws-iam-authenticator
# mv aws-iam-authenticator /usr/bin/
# aws-iam-authenticator help

여기까지 완료하였다면 이제 Amazon EKS 클러스터를 생성할 수 있습니다.

Amazon EKS 클러스터 생성


Kubernetes는 클러스터 API 서버와 통신하기 위해 kubectl이라는 명령줄 유틸리티를 사용합니다. 그런데, Amazon EKS 클러스터에 kubectl이 접근하기 위해서는 IAM인증이 필요합니다. Kubernetes 버전 1.10부터 Kubernetes용 AWS IAM Authenticator를 설치하고 인증에 사용할 kubectl 구성 파일을 사용하여 Amazon EKS를 사용할 kubectl 클라이언트를 구성할 수 있습니다.

AWS CLI로도 생성이 가능하지만 여기서는 Amazon콘솔의 Service>EKS에서 [Create cluster]를 선택합니다. 여기서 생성되는 EKS Control Plane는 시간 당 $0.20(약 $150/월) 비용이 발생합니다.

Cluster name, Kubernetes version, Role name, VPC, Subnet, Security group를 선택하여 EKS cluster를 생성합니다. 여기서 필요한 정보는, 앞에서 자동으로 생성한 클러스터용 VPC의 Cloud Formation 스택>출력 탭에서 확인해 볼 수 있습니다.
클러스터 생성은 약 5-10분 정도 소요되는데, 생성이 완료되어도 사용자의 콘솔에서는 EKS Control Plane을 구성하는 리소스들이 보이지 않습니다. 다만, 클러스터의 Worker Node에 attach될 ENI가 각 AZ마다 1개 생성된 것은 볼 수 있습니다.

Amazon EKS용 kubectl 구성

AWS CLI의 eks update-kubeconfig 명령으로 클러스터에 대한 kubeconfig 파일을 생성합니다. 만약, AWS CLI를 설치하고 싶지 않거나, kubeconfig를 수동으로 관리하고자 한다면 Amazon EKS에 대한 kubeconfig 생성를 참조하십시오.

앞에서 준비한 관리자용 클라이언트 EC2에서 AWS CLI의 버전을 확인해 봅니다. 1.16.18버전 이상이 설치되어 있지 않다면, 아래 명령어로 설치 혹은 최신 버전으로 업그레이드합니다.

# aws –version
aws-cli/1.15.83 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.10.82
# pip install awscli –upgrade –user
# aws –version
aws-cli/1.16.91 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.81

클러스터를 생성한 계정의 IAM유저의 보안자격증명을AWS CLI에 설정합니다.

# aws configure
AWS Access Key ID [None]: AKIAIHE#########FELA
AWS Secret Access Key [None]: uqm8MSDK######################Ddz29PcAz5
Default region name [ap-northeast-2]:
Default output format [None]:
# aws sts get-caller-identity
{
"Account": "4952894#####",
"UserId": "AIDAJU5LO##########LQ",
"Arn": "arn:aws:iam::4952894#####:user/[username]"
}

AWS CLI update-kubeconfig 명령을 사용하여 클러스터에 대한 kubeconfig를 생성하거나 업데이트합니다.

# aws eks update-kubeconfig –name mytest
Added new context arn:aws:eks:ap-northeast-2:49528#######:cluster/mytest to /root/.kube/config
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 1m

Amazon EKS작업자 노드 구성

클러스터용 VPC와 Kubernetes 제어 플레인이 생성되었고 kubectl이 설치 및 구성이 되었으므로 이제 Worker Node를 구성할 수 있습니다. Worker Node를 구성하면 EC2인스턴스들이 생성되므로, 제어 플레인 $0.20/hours 비용 외에 추가로 EC2 인스턴스 비용이 청구됩니다.

Worker Node 시작

Cloud Formation>스택>[Create stack]을 선택합니다.
템플릿에서 다음 URL을 붙여 넣고 다음을 선택합니다.

https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-01-09/amazon-eks-nodegroup.yaml

세부정보지정 페이지에서 아래 파라미터들을 넣고 다음을 선택합니다.

스택 이름: (예: mytest-eks-nodeA)
ClusterName: 위 단계에서 생성한 Amazon EKS 클러스터 이름과 정확하게 일치해야 합니다. 그렇지 않은 경우 Worker Node를 클러스터에 조인할 수 없습니다. (예: mytest)
ClusterControlPlaneSecurityGroup: 위 단계에서 생성된 AWS CloudFormation 출력의 SecurityGroups 값을 선택합니다.(예: mytest-eks-ControlPlaneSecurityGroup-GNNM8LC0N44O)
NodeGroupName: 이 이름은 나중에 Worker Node에 대해 생성된 Auto Scaling 노드 그룹을 식별하는 데 사용할 수 있습니다.(예: mytest-eks-nodeA)
NodeAutoScalingGroupMinSize: 예: 1
NodeAutoScalingGroupDesiredCapacity: 예: 3
NodeAutoScalingGroupMaxSize: 예: 4
NodeInstanceType: Worker Node에 대한 인스턴스 유형을 선택합니다.(예: t2.small)
NodeImageId: Amazon Marketplace에서 "amazon-eks-node" 혹은 "amazon-eks-gpu-node"로 검색하면 나오는 AMI 중 커뮤니티AMI 메뉴에 있는 amazon-eks-node-1.11-v20190109의 AMI ID를 입력(예: ami-0b7baa90de70f683f)
주의: CloudFormation 템플릿 버전과 호환되는 AMI를 사용해야 합니다. "aws s3 ls s3://amazon-eks/cloudformation"를 실행하면 기존 버전들을 확인할 수 있으며 호환표는 아래와 같습니다.

CloudFormation Version

EKS AMI versions

amazon-vpc-cni-k8s

2019-01-09

amazon-eks-node-1.11-v20190109

V1.3.0

2018-12-10

amazon-eks-node-(1.11,1.10)-v20181210

v1.2.1

2018-11-07

amazon-eks-node-v25+

v1.2.1 (for t3 and r5 instances)

2018-08-30

amazon-eks-node-v23+

v1.1.0

2018-08-21

amazon-eks-node-v23+

v1.1.0

KeyName: 시작 이후 SSH를 사용하여 작업자 노드에 연결하는 데 사용할 수 있는 Amazon EC2 SSH 키 페어 이름을 입력합니다.
BootstrapArguments: 비워둠
VpcId: Amazon EKS 클러스터 VPC 생성에서 생성한 VPC에 대한 ID를 입력합니다.
Subnets: Amazon EKS 클러스터 VPC 생성에서 생성한 서브넷을 선택합니다.

옵션 페이지와 검토페이지를 확인 후 생성을 선택합니다.

스택이 생성된 후 출력 탭을 선택하여 NodeInstanceRole을 메모하여 나중에 Amazon EKS 작업자 노드를 구성할 때 사용합니다.

아래는 Worker Node 생성을 위한 스택에서 파라미터 입력 예입니다.

Worker Node를 클러스터에 조인

AWS Authenticator 구성 맵 다운로드, 편집 및 적용:

# curl -O https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-01-09/aws-auth-cm.yaml
# vi aws-auth-cm.yaml <- 위에서 메모한 NodeInstanceRole를 rolearn의 값으로 교체 후 저장

# kubectl apply -f aws-auth-cm.yaml
configmap/aws-auth created
# kubectl get nodes –watch
NAME STATUS ROLES AGE VERSION
ip-192-168-122-60.ap-northeast-2.compute.internal Ready <none> 2m v1.11.5
ip-192-168-132-24.ap-northeast-2.compute.internal Ready <none> 2m v1.11.5
ip-192-168-177-2.ap-northeast-2.compute.internal Ready <none> 2m v1.11.5

잠시 후, 노드의 상태가 Ready가 되면 정상적으로 적용된 것입니다.

샘플 애플리케이션 시작해 보기

샘플 게스트 북 애플리케이션을 생성해서 생성한 클러스터를 확인해 봅니다. 아래 명령을 차례로 진행합니다.

# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-master-controller.json
replicationcontroller/redis-master created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-master-service.json
service/redis-master created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-slave-controller.json
replicationcontroller/redis-slave created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-slave-service.json
service/redis-slave created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/guestbook-controller.json
replicationcontroller/guestbook created
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/guestbook-service.json
service/guestbook created
# kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
guestbook LoadBalancer 10.100.110.135 a5baba20e22cf11e9845d0a50976ac11-468761890.ap-northeast-2.elb.amazonaws.com 3000:31955/TCP 30s app=guestbook
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 5h <none>
redis-master ClusterIP 10.100.125.201 <none> 6379/TCP 1m app=redis,role=master
redis-slave ClusterIP 10.100.169.153 <none> 6379/TCP 47s app=redis,role=slave

마지막 과정에서 EXTERNAL-IP가 이용 가능하게 되면 웹 브라우저를 포트 3000의 해당 주소로 가리켜 게스트 북을 확인합니다. 예: a5baba20e22cf11e9845d0a50976ac11-468761890.ap-northeast-2.elb.amazonaws.com/3000

게스트 북 객체 정리

샘플 애플리케이션의 테스트 후 요금 발생을 방지하기 위해 생성한 리소스를 삭제합니다. 아래 명령은 게스트 북 애플리케이션의 모든 서비스와 복제 컨트롤러를 삭제합니다.

# kubectl delete rc/redis-master rc/redis-slave rc/guestbook svc/redis-master svc/redis-slave svc/guestbook

Amazon EKS 정리

먼저, 클러스터에서 실행 중인 모든 서비스를 조회하고 EXTERNAL-IP 값과 연결된 모든 서비스를 삭제합니다. ELB에 의해 설정되고 Kubernetes에서 삭제하여 ELB와 연결된 리소스가 적절하게 릴리스 되어야 합니다.

# kubectl get svc –all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default guestbook LoadBalancer 10.100.110.135 a5baba20e22cf11e9845d0a50976ac11-468761890.ap-northeast-2.elb.amazonaws.com 3000:31955/TCP 36m
default kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 6h
default redis-master ClusterIP 10.100.125.201 <none> 6379/TCP 36m
default redis-slave ClusterIP 10.100.169.153 <none> 6379/TCP 36m
kube-system kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 6h
# kubectl delete svc guestbook
service "guestbook" deleted
# kubectl delete svc redis-master
service "redis-master" deleted
# kubectl delete svc redis-slave
service "redis-slave" deleted
# kubectl get svc –all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 6h
kube-system kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 6h

다음으로 worker node 스택을 삭제하면, 스택 생성시 생성된 리소스를 자동 삭제합니다.

Amazon EKS 클러스터를 삭제합니다. (수 분 소요)

EKS클러스터용 VPC를 생성한 스택을 삭제합니다. 이 리소스는 비용이 따로 발생하지 않으므로 남겨 두어도 됩니다.

맺음말

이상으로 Amazon EKS에 대한 소개와 기본 구성 및 간단한 어플리케이션 테스트를 하여 보았습니다. 컨테이너를 기반으로 한 서비스를 검토하시는 분들에게 도움이 되길 바랍니다. 감사합니다.

참조:
한글 https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/getting-started.html
영문 https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html (한글메뉴얼은 최신 정보가 아직 업데이트가 안되어 있을 수 있습니다)