IT 개발노트

[AWS] ECS 및 EKS 개념 정리 본문

기초튼튼

[AWS] ECS 및 EKS 개념 정리

limsungju 2023. 5. 16. 23:45

마이크로 서비스를 개발하면, 각각의 용도로 여러 컨테이너가 필요하며, 그 개수는 상황에 따라 빠르게 늘어날 수 있다. 컨테이너 개수가 늘어나면서 리소스 등 관리 포인트가 늘어나는데 이것을 자동화해주는 것이 컨테이너 오케스트레이션 툴이라고 한다. 툴 중엔 가장 유명한 쿠버네티스(k8s)가 있고, Docker Swarm, Nomad, Mesos 등이 있으며 AWS에는 ECS (Elastic Container Service)라는 서비스가 있다.

ECR (Elastic Container Registry)

ECR은 컨테이너를 위한 프라이빗 도커 레포지토리이며, ECR를 사용하면 AWS 컨테이너 서비스와 호환성 측면에서 이점이 있다. 클러스터를 ECR과 쉽게 연결할 수 있으며, 새로운 버전의 이미지가 올라오면 자동으로 클러스터에 넘어가게끔 설정할 수도 있는 등 다양한 기능을 누릴 수 있다.

ECR 서비스는 꽤나 단순하고 직관적이다. 프라이빗 레포지토리를 생성하고, 애플리케이션 이미지, 다양한 이미지 및 버전을 레포지토리에 등록할 수 있고, 레포지토리 엔드포인트로 클러스터에서 이미지를 다운로드할 수 있다.

ECS (Elastic Container Servie) 란

ECS는 위에도 언급했듯이 컨테이너의 라이프사이클을 관리하는 AWS의 컨테이너 오케스트레이션 서비스이다. 컨테이너 라이프사이클엔  'Container Start', 'Re-Schedule', 'Load Balancing' 등이 포함된다. ECS는 내부적으로 Cluster, Task, Sevice 이렇게 세 가지 메인으로 구성되어 있는데, 간단히 설명하자면 다음과 같다.

- Cluster : 여러 컨테이너의 하드웨어 리소스를 논리적으로 그룹화한 녀석이며, 컨테이너 라이프사이클을 관리한다.
- Task : VM에 어떻게 컨테이너를 배포할지 내용을 품고 있는 템플릿 메타데이터 (mem, cpu, env 어떻게 배포할지)
- Service : Auto-Scaling, LB 등 컨테이너를 어떻게 배포, 실행, 관리할지 Task보다 advanced 한 설정 내용을 품고 있는 녀석

스케줄링 : k8s 방식으로 설명하자면, 새로 생성된 파드 중 노드가 할당되지 않은 녀석을 스케줄러가 탐지해, 해당 파드를 가동할 최적의 노드를 찾는다. 최적의 노드는 파드 배치가 가능한 노드에 일련의 Function을 돌려 스케줄러가 점수를 매기고, 가장 높은 점수의 노드를 채택한다.

위의 이미지는 ECS 컨테이너 서비스 이용한 하나의 예제이다. DockerFile을 이용해, AWS의 레포지토리 서비스인 ECR에 도커 이미지를 업로드하고, 그리고 ECR에 올라온 이미지로 ECS 컨테이너 서비스로 이미지를 컨테이너화 하여 관리할 수 있다.

ECS 동작 방식 with EC2

그렇다면 어떻게 ECS는 동작할까? 먼저 ECS 내부적으로 AWS ECS 서비스를 이용하려면 먼저 ECS Cluster를 생성해야 한다. ECS Cluster는 Controle Plane과 같으며, 소속되어 있는 모든 컨테이너의 라이프사이클을 관리하는 녀석이다. ECS Cluster는 기본적으로 각각의 컨테이너를 관리하기 모든 서비스가 탑재되어 있다.

컨테이너를 관리하는 Control Plane이 ECS Cluster라는 것을 알았다. 그렇다면 컨테이너는 어디에 있을까? 컨테이너는 VM에서 동작하며, 여기서 VM이란 EC2 인스턴스가 되겠다. EC2는 컨테이너를 호스팅 역할을 하며, ECS Cluster와 연결되어 함께 동작한다. EC2에는 Docker Runtime, Container Runtime 가 있어 컨테이너를 시작할 수 있으며, ECS agent가 설치되어 있어 Control Plane인 ECS Cluster가 VM을 관리할 수 있는 것이다.

* container runtime : 컨테이너 엔진이라고도 불리며, OS위에 컨테이너를 실행하기 위한 소프트웨어 구성 요소이다. 리포지토리에 컨테이너 로드, 컨테이너 수명주기, 로컬 리소스 모니터링 및 컨테이너를 위한 리소스 분리 등을 담당한다. 일반적으로 container runtime은 오케스트레이션과 같이 동작한다. 오케스트레이션은 클러스에 있는 모든 노드의 확장, 보안, 네트워크 등을 담당하고, container runtime은 클러스터 안의 노드 위에 가동되는 컨테이너 개개인을 담당한다.

ECS with EC2를 정리하자면, EC2를 생성해야 하고, 그것을 ECS Cluster에 연결해야 하며, 새로운 컨테이너를 생성한다면 EC2 인스턴스에 충분한 리소스가 남아 있는지를 고려하고, 또한 OS 및 Docke Runtime, ECS Agent도 관리해야 한다. 물론 이 작업을 위해 유저는 그에 맞는 권한이 있는 있어야 한다. 즉, ECS with EC2는 ECS Cluster가 컨테이너 서비스를 관리해주지만 VM의 경우 사용자가 직접 신경 써줘야 하는 부분이 있다는 것이다.

하지만 이런 인프라 관리마저도 AWS에 맡기고 싶다면(컨테이너 라이프사이클, 인프라 호스팅)? 이 경우, EC2 인스턴스의 대체품으로 AWS Fargate를 고려해 볼 수 있다. Fargate는 이용하면 EC2처럼 프로비저닝 작업은 필요 없다. Fargate는 어떻게 동작할까?

ECS 동작 방식 with Fargate

 Fargate는 서버리스 방식으로 컨테이너를 시작할 수 있는 서비스다. AWS 위에 동작시키고 싶은 컨테이너가 있다면 ECS Cluster에 Fargate 방식으로 배포하면 된다. Fargate는 컨테이너를 분석해 얼마만큼의 리소스가 필요한지, 자동으로 해당 컨테이너를 위해 리소스를 프로비저닝 해, 프로비저닝 된 리소스 위해 배포 및 실행한다. 이 모든 것이 다 자동이다. 새로운 컨테이너가 추가되어 Fargate에 배포하여도, Fargate는 동일하게 동작한다. 즉, EC2처럼 미리 프로비저닝 할 것이 없어 VM에 신경이 덜 쓰인다. 

EC2 방식과 Fargate 방식의 비용 차이

비용적인 측면에서 보았을 때, Fargate 방식은 컨테이너 구동을 위해 요구되는 필요한 리소스만 확인과 얼마나 오래 돌릴 것인지 확인만 하면 된다. 둘을 간단하게 정리하자면 다음과 같다.

- EC2 방식: 컨테이너를 적게 돌리건 말건 호스팅에 쓰인 EC2에 대한 비용이 청구
- Fargate 방식: 컨테이너를 가동을 위해 얼마만큼의 리소스가 요구되었는지, 얼마만큼의 기간 동안 가동할 것이지

이렇게만 들으면 Fargate가 무조건 좋아 보이지만, 만약 기본 인프라에 대한 액세스, 컨테이너를 가동하는 실제 인프라에 접근이 필요하다면 EC2 방식이 접근 측면에서 더 높은 유연성을 보여준다. 

EKS (Elastic Kubernetes Servie) 란

컨테이너 오케스트레이션 관련해 위에도 정리했지만, 현재 관련 툴 중에 가장 인기 있는 것은 쿠버네티스(이하 K8S)이며, 프로젝트를 K8S로 구현하고자 한다면 AWS EKS를 이용할 수 있다. EKS는 ECS의 대체품으로 AWS의 k8s 서비스이다. 여기서 EKS와 ECS의 차이점을 간단하게 집고 넘어간다. 

EKS ECS
오픈소스 AWS에 국한된 서비스
EC2 내 여러 Pod가 묶여 하나의 ENI 공유 가능 EC2 내 Task 별로 ENI를 할당받음
타 플랫폼으로 이식이 쉽다.
(타 클라우드 플랫폼, On-Premise 등에도 실행 가능)
타 플랫폼으로 이식이 어렵다.
(AWS에 최적화 되어 있으며, 타 AWS 서비스와 함께 클러스러를 이용하고 있으면)

EKS 동작 방식

ECS와 비슷하게 동작한다. EKS 서비스를 사용하려면 먼저 EKS Cluster를 생성하는데 Control Plane과 Control Plane에 종속된 워커 노드로 구성된다. Control Plane은 etcd나 API Server 등 K8S 소프트웨어를 실행하는 Control Plane 노드로 구성되어 있다. Control Plane은 AWS에서 관리하는 계정에서 실행되며, K8S API는 사용자의 클러스터에 EKS endpoint를 통해 노출된다.  각각의 EKS 클러스터는 독립적이다.

그리고 워커 노드는 EC2위에 동작하며 API Endpoint를 통해 Control Plane과 연결된다. 워커 노드가 Contorl Plane과 통신할 수 있는 이유는 ECS와 비슷하게 워커 노드에 container agent와 k8s 프로세스가 설치되어 있기 때문이다. 이것은 타 플랫폼에서도 동일하다. 모든 작업이 끝났다면, 사용자는 간단하게 kubectl 명령어로 컨테이너를 클러스터 내로 배포할 수 있다.

추가로 K8S의 모든 상태를 저장 및 조회할 수 있는 Etcd는 백업 및 관리가 아주 중요한데, EKS는 AWS에서 관리하는 서비스인 만큼 이 부분도 AWS가 알아서 처리해줘 사용자는 마스터 노드를 신경 쓸 것이 없다.

K8S라는 오픈소스 플랫폼을 AWS 환경위에서 서비스라는 형태로 동작하도록 만든것이 EKS다. AWS에 올라갔다고 달라질 것은 없다. 즉, 기존에 K8S를 다뤘던 사용자라면 무리없이 EKS도 활용할 수 있다.

K8S 동작 방식

K8S 작동 방식 자체에 대해 간단하기 집고 넘어 가보자. 먼저 K8S의 구성 요소는 간단하게 다음과 그림과 같이 정리할 수 있다.

이미지 출처 : https://sensu.io/blog/how-kubernetes-works

중간에서 교통정리를 해주는 'API Server'
여유공간을 확인하고 서버를 어떻게 배포할지 정해주는 '스케쥴러'
컨테이너의 상태를 체크하는 '컨트롤러'
모든 상태를 저장 및 조회할 수 있는 DB와 같은 'etcd'
마스터의 'API Server' 와 통신하며 노드의 팟을 관리하는 'Kubelet'


위 구성은 다음과 같은 프로세스로 움직이며 쿠버네티스를 동작시킨다. 각각의 컴포넌트는 마치 각자 역할을 분담받은 관리자처럼 움직이며, 특히 스케줄러의 경우 라벨링으로 각각 분담하는 노드를 지정할 수 있다. 다음 예제는 관리자가 Pod 1개 추가 요청했을 때의 프로세스다.

1. 관리자가 Pod를 추가 요청
2. 중앙 관리자인 API Server가 그 요청을 받고 etcd 저장
3. 컨트롤러가 지속적인 체크를 하다 etcd의 Pod 생성 요청을 발견
4. 컨트롤러가 Pod 생성 요청
5. API Server가 요청을 받고 etcd에 'Pod 생성 요청중'이라는 상태 저장
6. 스케줄러가 지속적인 체크를 하다 etcd의 Pod 할당 요청 발견
7. 스케줄러는 어느 노드에 Pod를 배치할지 정하여 요청
8. API Server는 그것을 etcd에 저장
9. kubelet은 자신이 할당된 노드에 실행이 안된 Pod가 있는지 모니터링
10. API Server로부터 Pod 생성 요청을 확인
11. Pod 생성 후, etcd에 상태를 업데이트
12. 위의 과정을 무한 루핑 하며 서로를 체크