Cloud/AWS 기초

AWS EKS로 안정적인 서비스 운영하기

치킨맛코드 2022. 8. 23. 20:33

본 내용은 2020 aws Community day, 최용호(넥슨코리아)님의 쿠알못이 Amazon EKS로 안정적인 서비스 운영하기 영상을 정리 한 내용입니다. 

영상 링크 : https://youtu.be/O3znWPUdt18

 

 

도커를 사용할때 많은 명령어를 사용하곤 한다. 특히 run과 같은 명령어를 통해 컨테이너를 생성할 수 있다. k8s도 마찬가지로 kubectl을 사용해서 run을 사용할 수 있다. 

일반적으로 k8s에서는 pod를 생성할때 Deployment를 만들게 되면, 이것을 통해서 ReplicaSet이 만들어지고, ReplicaSet을 통해서 최종적으로 pod가 만들어 진다. Deployment를 통해서 pod에서 변경된 이미지를 배포할 때 어떤 전략으로 배포를 할 것이고, 문제가 생겼을때 어떻게 롤백을 할 것인지를 관리해 준다. ReplicaSet을 통해서 명시된 Pod의 갯수가 명확한지 등에 대해 관리할 수 있다. 이러한 과정은 kubectl get events 명령어를 통해서 확인할 수 있다.

 

쿠버네티스의 구성요소는 아래 내용을 참고하자.

https://chicode.tistory.com/181

 

K8s의 구성 요소 및 개념

kubenetes는 에플리케이션의 배포 및 조정, 관리를 자동으로 하기 위한 오픈소스 시스템이다. k8s은 에플리케이션을 배포, 유지 관리 및 확장하기위한 메커니즘을 총체적으로 제공한다. 구성요소는

chicode.tistory.com

Watch 메커니즘(좌)와 pub/sub 구조예시(우)

이때 k8s내부에서 각 component(api서버, Controller Manager, Scheduler, etcd, Kubelet, Kubepronxy)들은 Watch라는 메커니즘을 가지고 있다. Components는 API server를, API는 etcd를 watch(subscribe, pub/sub구조)하고있다. 예를들어 api server에 변경사항이 발생한다면, etcd로 변경사항이 업데이트가 될 것이다. 당연히 etcd에도 변경사항이 발생이 되며, 이 변경사항을 api server로 notify하게된다. 마찬가지로 api server에서 components로 notify하게 된다. Schedulers는 worker node에 있는 kubelet가 메니져를 통해 수집하여 API server로 전달한 데이터(CPU/Memory 등)를 바탕으로하여 최적의 node에 pod를 할당한다. 혹은 affinity(특정 파드를 선호), taint(특정 파드 거부) 설정 등을 통해 우선순위를 설정할 수 도 있다. 이렇게 변경된 사항은 worker node로 전달되어 kubelet이 pod를 생성한다. 구체적인 도식화를 하면 아래와 같다.

 

변경사항 출처(aws community day 2020)

Api server가 장애가 발생한다면 곧 클러스터 전체의 장애가 발생하는것 이기에, 이를 방지하고자 고가용성 서버를 활용한다. k8s의 모든 데이터가 저장되는 etcd에서 장애가 발생하는 경우에도 마찬가지로 고가용성을 활용해야한다.

etcd를 고가용성으로 활용하기 위해서는 반드시 3개 이상의 az를 활용해야한다. 그 이유는 "Raft" 라는 알고리즘 때문이다. Raft는 선출된 리더를 통해서 투표(합의)를 기반으로 찬/반을 설정하는 알고리즘인데, 선출직으로서 단 1개만 존재할 수 있는 리더, 그리고 그를 따르는 추종자, 리더가 없을때 차기 리더가 될 가능성이 있는 후보자로 총 3가지의 지위가 존재한다. 

고가용성 서버

이렇게 복잡한 서비스들을 일일이 관리하기에는 쉽지않지만, AWS의 EKS기능을 활용해서 Master Node를 관리할 수 있으며, EKS Node groups을 활용해서 Worker node를 관리할 수 도 있다.

 

EKS를 설치하는 방법은 다양하다. AWS에 직접 접근해서 Console창에서 설치를 해도 되며, CLI를 활용할 수 도 있다. eksctl이나 IaC가 가능한 Terraform을 활용할 수 도 있다. 이 중 가장 간편한건 eksctl이다.

eksctl create cluster \
==> eksctl 명령어를 활용해 cluster를 생성한다.
    --name eks-chicode \
==> cluster의 이름은 eks-chicode이다.
    --region ap-northeast-2 \
==> eks-chicode의 지역은 서울이다.
    --version 1.19 \
==> 버전은 1.19를 사용한다.
    --managed \
==> worker node를 생성하는 명령어.
    --asg-access
==> Auto Scalling을 사용한다.

 

어떤 방법을 사용하더라도 eks를 설치한 후 반드시 가장 먼저 해야할 부분은 IAM을 관리하는것이다. 기본적으로 생성한 user의 iam유저가 master권한을 획득하며, 해당 유저는 k8s의 모든 자원을 활용할 수 있다. 

kubectl edit configmap aws-auth -n kube-system
==> worker node에 대한 권한을 확인할 수 있는 명령어이다.
mapRoles: 파트에서는 role을 설정할 수 있다.
mapUsers: 파트에서는 사용자를 추가할 수 있다.
kbuectl edit clusterrole cluster-admin
==> cluster-admin이라는 role을 생성한다.
iam의 role과 같은 개념이다.
kbuectl edit clusterrolebinding cluster-admin
==> 생성된 role을 할당해 주는 명령어이다.

IAM을 설정한 후 Network를 활용해 봐야한다. 따로 관리가 되어있지 않다면 a라는 node의 pod와 b node의 pod가 같은 ip를 받을 수 도 있다. 그렇게 된다면, 외부에서 접근을 할 때 큰 혼란이 발생될 수 있다. 이것을 방지하기 위해서 각 컨테이너가 서로 다른 ip를 부여받을 수 있도록 지원해 주는 Overay Network(플러그인으로 지원된다.)를 사용한다. AWS에서는 AWS CNI라는 기능을 제공한다.

 

AWS CNI는 ip를 할당받을때 실제 vpc 내부의 ip를 할당받게 된다. 그렇기에 vpc를 생성할때 ip range를 작게 설정한다면 pod가 생성되지 않을 수 도 있다. 또한 너무 크게 설정을 할 경우 ENI(IPAM)에 의해 생성이 실패될 수 도 있다. 그래서 아래의 공식을 활용해서 최대 pod 수를 잘 설정해야 한다.

최대 pod수 = (인스턴스 유형에 따른 ENI * (ENI별 IP 수 -1))

 

pod는 기본적으로 휘발성이기에, pod가 삭제되면 내부의 데이터도 같이 증발한다. 그렇기에 안정적인 저장소(EBS, EFS ...)을 연동해서 사용할 수 도 있다. ebs를 생성하는것은 정말 간단한데, storage class를 생성 및 명시를 한 후, persisten volume claim(몇 GB을 사용할것이다. 등등)을 생성한다. 이 후 마운트를 하게된다면 pod를 생성될때 EBS가 따로 생성된다.

 

Master Node의 경우 Cloudwatch를 사용해서 로그를 모니터링을 할 수 있다. worker node의 pod의 경우 container insights를 바탕으로 하여 정책을 추가한후, 명령어를 실행한다면 바로 연동이 되어 역시 cloudwatch를 통해 확인할 수 있다.