나는 그동안 AWS EC2 서비스를 활용해 여러 번 애플리케이션 서버를 배포해 왔다. EC2는 클라우드의 대표 서비스이자 단순한 컴퓨팅 대여 서비스로, 클라우드 환경에 최적화되어 있어 대표적인 사례가 많기 때문에 자연스럽게 사용한 것 같다. 사실 뭐 그 이상의 기능까지도 필요 없었던 것도 사실이다.. 하지만 기존에 내가 인프라를 구축하는 프로젝트들과는 달리 이번 프로젝트는 이미 기존에 ECS를 사용하고 있었다. 기존 시스템을 관리해야 하기도 하고, 새로 리팩토링을 하면서 새롭게 ECS를 사용할 예정이기 때문에 이 기회에 ECS를 정리하고 사용해보려 한다.
AWS는 결국 서비스를 판매하는 판매처이기 때문에 서비스에 대해서 잘 설명해주고 있다. 그래서 이 글은 AWS 공식 홈페이지와 설명서들을 기준으로 ECS의 개념부터 실습 방법까지 정리할 예정이다.
ECS란?
AWS ECS는 Amazon Elastic Container Service로 AWS의 서비스 중 하나이다.
AWS에 의하면 AWS ECS를 다음과 같이 말한다.
" Amazon Elastic Container Service(Amazon ECS)는 컨테이너 애플리케이션을 쉽게 배포, 관리 및 확대할 수 있도록 도와주는 완전 관리형 컨테이너 오케스트레이션 서비스입니다. 완전 관리형 서비스인 Amazon ECS에는 AWS 구성과 운영 모범 사례가 내장되어 있습니다. Amazon Elastic Container Registry와 같은 AWS 도구 및 Docker와 같은 서드파티 도구와 통합됩니다. 이러한 통합을 통해 환경이 아닌 애플리케이션 구축에 더욱 집중할 수 있습니다. 컨트롤 플레인을 관리하는 복잡한 과정 없이 클라우드의 AWS 리전와 온프레미스에서 컨테이너 워크로드를 실행하고 확장할 수 있습니다."
ECS를 알기 전..
aws 자체에서도 ecs가 뭔지 설명해 주는 문서가 있다. 이 내용을 이해하려면 먼저 ‘컨테이너’가 무엇인지 알아야 한다. 이 문서의 영상에서도 컨테이너를 먼저 설명하고 있다. https://ecsworkshop.com/introduction/
간단하게 요약해보자면 AWS ECS는 컨테이너를 쉽게 배포, 관리, 확장할 수 있도록 지원하는 완전 관리형 오케스트레이션 서비스이다. 이를 이해하기 위해서는 먼저 세 가지 핵심 개념을 알아야 한다.
1. 컨테이너의 등장과 필요성
과거 개발자와 운영팀은 애플리케이션 배포 시 가상 머신이나 물리 서버를 사용했다. 그러나 한 서버에서 여러 애플리케이션이 실행되면 각 애플리케이션이 서로 다른 라이브러리나 운영체제 버전에 의존하게 되어 의존성 충돌이 발생하고, “내 노트북에서는 잘 되는데 서버에서는 안 된다”는 환경 차이 문제가 빈번했다.
컨테이너는 애플리케이션과 그 실행에 필요한 라이브러리, 설정 등을 하나로 묶어 격리된 환경에서 실행할 수 있게 해 준다. 전통적인 가상 머신에 비해 훨씬 가볍고 빠르게 구동되며, Docker와 같은 플랫폼을 통해 모든 의존성을 하나의 이미지로 패키징함으로써 어디서나 동일하게 실행할 수 있게 되어 환경 간 차이로 인한 문제를 크게 줄여준다. Docker를 사용하면 개발자가 로컬에서 테스트한 그대로의 이미지를 운영 환경에서도 그대로 실행할 수 있어, 환경 간 차이로 인한 문제를 크게 줄일 수 있다.
2. Docker와 Dockerfile의 간편성과 일관성
Docker는 컨테이너 이미지를 빌드, 테스트, 배포할 수 있는 플랫폼이다. Dockerfile은 컨테이너 빌드를 위한 간단한 텍스트 파일로, 운영체제, 필요한 패키지 설치, 코드 위치, 실행 명령 등을 순차적으로 정의한다. Dockerfile에 기반하여 이미지를 빌드하면, 이 단 하나의 이미지로 어디서든 일관된 환경에서 컨테이너를 실행할 수 있다. 이러한 간편성과 일관성은 컨테이너 도입의 핵심 동기이며, 개발자와 운영자 모두에게 큰 편의를 제공한다.
3. Amazon ECS: 컨테이너 오케스트레이션의 핵심
AWS의 Elastic Container Service(ECS)는 Docker 컨테이너를 관리하고 운영하기 위한 완전 관리형 오케스트레이션 서비스이다. ECS는 클러스터와 태스크의 스케줄링, 상태 모니터링 등 복잡한 작업을 AWS가 대신 처리하며, CloudWatch, Auto Scaling, ELB, IAM 등 다양한 AWS 서비스와 원활하게 연동된다. 또한, EC2 기반 클러스터뿐만 아니라 서버리스 옵션인 Fargate도 지원하여 사용자가 인프라 관리에 신경 쓰지 않고 애플리케이션 개발에 집중할 수 있도록 도와준다.
오케스트레이션이란 여러 컨테이너의 배포, 스케줄링, 확장, 업데이트, 복구 등의 작업을 자동화하고 조율하는 기술로, 복잡한 환경에서도 원하는 상태를 안정적으로 유지할 수 있도록 해준다. AWS ECS는 이러한 오케스트레이션 기능을 완전 관리형으로 제공하여, 사용자가 복잡한 운영 작업을 신경 쓰지 않아도 컨테이너를 손쉽게 배포하고 관리할 수 있게 해준다.
따라서 AWS ECS는 컨테이너를 쉽게 배포, 관리, 확장할 수 있도록 도와주는 완전 관리형 오케스트레이션 서비스로, 인프라와 클러스터, 서버 유지 보수 등 복잡한 운영 작업을 AWS가 대신 처리해 주기 때문에 개발자는 애플리케이션 개발에 더욱 집중할 수 있다.
Amazon ECS란?
지금부터는 https://www.youtube.com/watch?v=B3kdqNJ7WXc&t=2271s 영상을 기반으로 내용을 정리했다. AWS ECS라는 상품을 잘 설명한 판매처의 영상이다^^ 물론 저기에 있는 걸 다 실제로 적용할 필요는 없다. 더불어 저 영상 속에서는 너무 AWS 내에서 모든 걸 다 해결하려고 하기 때문에 개념 위주로 보기엔 정말 좋은 것 같다. (결국 만든 사람이 설명해 주는 영상이라 정확하긴 해서 좋았다.)
다시 돌아와서 말하자면 결국 ESC는 완전 관리형 컨테이너 서비스이다. 즉, 컨테이너화 된 애플리케이션을 배포하거나 스케일링 하는데 필요한 인프라를 AWS가 관리해 준다. 따라서 이렇게 인프라 관리를 최소화해서, 개발자들이 개발에만 집중적으로 할 수 있도록 도와준다.
컨테이너 오케스트레이션부터 클러스터 관리, 스케줄링 등을 ECS가 자동으로 처리해 준다. 또한, 컴퓨팅 옵션도 EC2부터 서버리스 컴퓨팅 엔진인 Fargate를 제공하며, 더불어 온프레미스에서도 컨테이너 워크로드의 라이프사이클을 콘솔에서 관리할 수 있다.
사진과 같이 2.25억개의 태스크가 실행되며, 초당 추천만 개의 API를 처리한다. 여러 지역에서 가능하며, 고객의 65%가 ECS를 사용할 정도로 많은 서비스들이 ECS를 사용하고 있다고 한다. ECS는 단순성, 안정성, 확장성을 기반으로 많이 사용되고 있으며, 더불어 보안이나 가용성까지 인프라를 안정적으로 유지하기 위한 요소들을 갖추고 있다.
vs EKS
ECS를 검색해보면 EKS와 비교하는 많은 글들을 확인할 수 있다. 두 서비스 모두 컨테이너 오케스트레이션 환경을 관리해 준다는 점이 같기 때문인 것 같다. 하지만 접근 방식에 차이가 있다.
- ECS의 특징 (단순성)
- ECS는 구조가 비교적 간단하며, ECS Service와 ECS Task로 구성되어 있다.
- 컨트롤 플레인 기능(컨테이너 스케줄링, 상태 관리 등)을 사용자가 직접 관리할 필요 없이, 인스턴스에 설치된 ECS 에이전트와 AWS 컨트롤 플레인이 연결되는 구조이다.
- ECS 컨트롤 플레인에 대한 과금은 없다는 장점이 있다.
- EKS (관리형 쿠버네티스)
- EKS도 AWS에서 컨트롤 플레인을 관리해 준다. 하지만 클러스터당 과금이 발생한다.
- 데이터 플레인에는 Manage Node와 자체 관리형 노드가 있다. 따라서 쿠버네티스 오브젝트(서비스, 디플로이먼트, 파드 등)의 이해가 필요하다.
- 주기적인 컨트롤 플레인 업그레이드 및 데이터 플레인 컴포넌트 업그레이드가 클러스터 버전에 따라 진행된다.
ECS는 강력한 단순성을, EKS는 쿠버네티스의 광범위한 에코시스템과 유연성을 제공한다. 선택은 각 프로젝트의 필요에 맞게 하면 된다.
ECS 구성 요소
1. Cluster
리전 내 서비스 및 작업의 논리적 그룹화 (테스크와 서비스를 논리적으로 그룹화하는 역할)이다. IAM은 클러스터에 대한 사용자 권한이 제어된다.
- 기본 인프라로 EC2 인스턴스를 사용할지, Fargate를 사용할지를 선택할 수 있다.
- 컨테이너 인사이트(Container Insights) 기능을 통해 인스턴스 수준이 아닌 클러스터 단위로 모니터링할 수 있다.
- 자동 스케일링 : EC2 선택 시, ECS AMI를 사용한 오토스케일링 그룹을 구성하여 컨테이너 인스턴스로 등록한다.
- 작업을 스케일링할 때도 스케줄링 범위가 클러스터 안에 조인되어 있는 컨테이너 인스턴스가 대상이 되며, CloudWatch Metrics도 크게는 클러스터 단위로 집계가 된다.
2. Task
ECS에서 실행되는 가장 작은 실행 단위이다. 한 개 이상의 컨테이너(최대 10개까지)를 실행하며, 선택한 컴퓨팅 옵션(EC2, Fargate)에서 실행된다. Task는 최소 실행 단위라 하나의 Task를 실행시킬 수 있다. 이는 ECS API의 RunTask 명령어로 가능하며, 배치 작업 형태로도 운영할 수 있다.
1. ECS 클러스터에서 최소 실행 단위
- 네트워킹, 스토리지, 파라미터, IAM 역할, 컴퓨팅 리소스 등을 구성한다.
2. 작업 정의(Task Definaition) 내용을 기반으로 작업 배포
작업 정의에는 구체적으로 어떤 내용을 기술할까?
- 배포 타입(컴퓨팅 타입) : Fargate, EC2, External
- 컨테이너 이미지 맵핑을 통한 정의 작업 (정의한 컨테이너가 어떤 이미지를 사용하는지)
- 작업 역할을 부여해 API 요청을 받을 때 권한에 따라 동작 (작업이 실행될 때 권한 설정, 볼륨 설정)
- 작업 크기 설정 (vcpu, 메모리를 얼만큼 할당할 것인지)
3. 작업 당 한 개 또는 최대 10개의 컨테이너 구성 가능
3. Task Definition (작업 정의)
JSON 형식의 템플릿으로, 태스크 실행에 필요한 상세 정보를 기술한다.
사진의 예시 Task Definaition을 보면, 상단 주황색 박스가 컨테이너에 대한 정의(containerDefinitions)이다. (Container Resource, Container Port, Image, Log Driver Configuration, Health Check..)
containerDefinitions에서는 여러 컨테이너를 정의할 수 있다. 그 안에는 컨테이너의 이름과 이미지 경로, Port, LogDriver, 헬스 체크 경로와 체크 횟수들을 정의하는 공간이다.
하단 파란색 박스는 Task 레벨의 구성(Task Level Config)이다. (Task Role, Task excution Role, Network Mode, revision..)
사용자가 정의한 작업이 어떤 컴퓨팅 공간에서 사용될지 역할은 어떤 것들을 사용할지를 정의한다. containerDefinitions 바깥 부분에 정의하게 되고 작업 정의를 여러 개 만들게 되면 리비전의 따라 버전 관리도 가능하다. (만약 컨테이너 이미지의 CPU 아키텍처가 ARM 기반일 경우에는 작업 정의 내 CPU 아키텍처를으로 지정을 해서 raviton Processors를 활용할 수도 있다.)
이러한 JSON 파일은 사용자가 직접 작성할 수도 있지만 ecs 콘솔 상에서 클릭 몇 번으로 자동으로 구성하는 것도 가능하다.
4. Service
작업 정의를 만들어 놓으면 이것을 기반으로 작업이 실행된다. 이때, 우리는 작업을 하나만 실행할 수도 있지만 같은 작업을 여러 개 실행할 수도 있다. ECS Service는 지정된 Task Definition을 기반으로 클러스터 내에서 원하는 수의 작업을 컨테이너 인스턴스에 지속적으로 유지 관리해 주는 구성요소이다.
- 로드밸런스(ALB, NLB)와 연결할 수 있기 때문에 여러 작업 간의 트래픽 분산이 가능하다.
- Service Discovery를 통해 서비스 검색 기능(클라이언트가 자동으로 서비스 인스턴스의 위치(IP와 포트)를 찾을 수 있음)을 활용할 수 있어 고가용성과 확장성을 쉽게 구현할 수 있다.
1. ECS 위에서 여러 개의 작업을 실행 : 여러개의 작업의 개수를 유지해 준다.
2. Unhealthy Task 확인 및 교체 : 앞단에 로드 밸런서를 붙일 경우 헬스체크를 주기적으로 실행해서 Unhealthy 상태의 태스크를 자동으로 교체한다.
3. 서비스 타입
- Replica : 여러 개의 태스크를 동시에 실행하고 유지한다. (고가용성을 확보)
- Daemon : 각 컨테이너 인스턴스 당 하나의 태스크를 배포한다. (한 개씩 배포되기 때문에 별도로 오토스케일링을 적용할 수 없고, 보통 로그 수집이나 모니터링 에이전트 실행 등 특정 용도로 사용)
4. 배포 옵션 구성
- Rolling Update
- Blue/Green Deploy
- Service Auto Scaling
사진처럼 서비스까지 만들었으면 외부로부터 트래픽을 받을 준비를 할 수 있다. 앞단에 ALB, NLB를 연결해서 여러 태스크들을 트래픽을 분산시킬 수 있다. 만약 여러 서비스가 있다면 ALB 경로 기반 라우팅을 활용해서 하나의 ALB만으로 여러 서비스로 라우팅 가능하며, 문제가 발생하더라도 태스크를 재시작해 안정적인 서비스를 제공해 주는 Auto Healing 기능을 갖춘 형태이다.
Rolling Update
ECS에서 배포는 빌트인 기능으로 Rolling Update가 내장되어 있다. 롤링 업데이트는 애플리케이션의 이전 버전과 새로운 버전을 순차적으로 교체하며 다운타임을 최소화하는 방법이다. 기본적으로 서비스를 생성할 때 롤링 업데이트로 지정된다.
ECS 배포가 진행될 때 MinimumHealthyPercent를 지정할 수 있다. 배포를 할 때 러닝 상태의 태스크가 최소 몇 퍼센트로 유지되어야 하는지에 대한 설정 값이다. 반대로 MaximumHealthyPercent는 러닝 상태와 펜딩 상태를 합한 태스크의 개수가 최대 몇 개까지 허용될 수 있는지를 나타내는 설정 값이다.
Blue/Green Deploy
Blue/Green 배포는 블루라는 환경, 그린이라는 환경을 배포해서 새로운 애플리케이션을 실행하는 배포 전략이다. 블루 환경은 현재 버전 그린 환경엔 새로운 버전에 애플리케이션이 동작하게 된다. 새 버전에 문제가 없는지 확인하고 트래픽을 전환하여 새 버전에 대한 안정성을 높일 수 있다. 문제가 발생해도 빠르게 기존 버전으로 되돌릴 수 있다. 이 전략은 ECS와 CodeDeploy 서비스를 함께 사용한다. 타겟 그룹을 하나 더 만들어서 블루 그린 환경을 구성하면 된다.
Fargate (서버리스)
서버리스 컴퓨팅 엔진인 Fargate는 인스턴스를 관리할 필요가 없기 때문에 운영 관점에서 권장되는 컴퓨팅 엔진이다. EC2처럼 on-demand(필요할 때 즉시)로 사용할 수 있고, 스팟 인스턴스도 지원한다. Fargate에서 사용할 VCPU와 메모리를 지정할 수 있다. (사진처럼 정해진 비율 안에서 지정해야 한다.)
vs EC2
EC2와 Fargate의 큰 차이점 중 하나는 Task가 VM에 들어가는 개수의 차이이다. 하나의 EC2에는 여러 개의 Task가 배치될 수 있지만, 한 개의 Fargate에는 한 개의 Task만 할당될 수 있다. Fargate는 Task당 격리가 VM 레벨로 되어있기 때문에 커널이나 CPU, 메모리, 리소스를 공유하지 않는다. 또한, 플랫폼 버전에 따른 운영 체제 업데이트, 보안 업데이트, 버그 수정 등이 사용자가 관리할 필요 없이 업데이트되기 때문에 안전한 환경에서 애플리케이션 개발에만 집중할 수 있다는 장점이 있다.
Fargate 장점
- Task 간 리소스 격리 및 보안 강화
- 운영 체제 업데이트, 보안 패치 등을 AWS가 자동으로 관리하며 OS, 컨테이너 런타임, ECS 에이전트 등 패치 적용
- 컨테이너에 대한 privileged Mode X (접근 불가)
- awsvpc 네트워크 모드가 필요하므로 작업당 ENI가 할당됨
- 사용자가 Runtime에 액세스 할 수 없음 (SSH -> 호스트로)
- Task에 AWS System Manager(SSM)로 접근 가능
Fargate 제약
- 배포 환경에서 호스트 OS(실제 서버 운영 체제)에 직접 설치해야 하는 보안 규정(compliance)이나 특정 소프트웨어가 필요한 경우, 해당 환경에서는 AWS Fargate와 같이 호스트 OS를 직접 제어할 수 없는 옵션은 사용할 수 없다. 즉, 호스트 OS에 대한 직접적인 접근이나 커스터마이징이 필요할 경우 불가능하다.
- GPU를 지원하지 않는다.
- 작업 정의의 네트워크 모드 중에서 awsvpc 모드만 지원한다. 따라서, Static Public ip를 할당할 수 없기 때문에 서비스 생성 시에 NLB로 구성한다. (이는 awsvpc mode를 사용하는 EC2도 포함된다.)
ECS Network
ECS 컨테이너 인스턴스에 Task를 배치하면 보통 보안 강화를 위해 Private Subnet에 배치하게 된다. Pulbic Subnet은 외부에서 접근하기 위한 로드 밸런서(ELB)와 트래픽을 외부로 라우팅 하기 위한 NAT Gateway가 준비되어 있다.
먼저 외부로 요청을 보낼 때, 사진처럼 NAT Gateway를 사용해서 Internet으로 요청을 보내고 응답을 받아오는 형태이다. 따라서 PG사, SaaS API처럼 외부에 요청을 보내는 다양한 케이스에선 위 사진처럼 NAT Gateway를 주로 활용한다. 외부 API 요청을 할 때 업체 측에서 인바운드 요청을 받기 위한 IP를 요구한다면, NAT 게이트웨이에 고정 IP를 제공해서 서비스를 하는 경우도 있다.
다음 사진은 일반적으로 이미지를 불러오는 경우이다. 일반적으로 AWS 환경에서 컨테이너 이미지를 가져올 때는 AWS ECR 서비스에 이미지를 저장해 놓고 불러오는 경우가 많다. AWS ECR은 VPC 외부에 있는 서비스이기 때문에 외부 통신으로 이미지를 가져와야 한다. 이때 NAT Gateway를 통해 이미지를 불러올 수도 있지만, 데이터 전송 비용을 절감하기 위해 NAT Gateway가 아닌 VPC Endpoint를 활용하여 서비스에 접근할 수 있다. (ERC뿐만 아니라 외부에 위치한 S3, DB에 접근할 때도 유용하다.)
(추가적으로 NAT Gateway를 사용하지 않고 좀 더 프라이빗한 클러스터를 구성하신다면 ECS 컨트롤 플레인과 통신하기 위한 VPC Endpoint를 추가적으로 구성해야 한다.)
마지막으로 Pulbic Subnet의 Task가 위치한 경우에는 NAT Gateway가 아닌 Internet Gateway로 직접 데이터를 전송하는 형태가 된다. 이렇게 기본적인 트래픽 라우팅의 사례를 알아봤다.
ECS Network Mode
ECS 네트워크 모드에서는 도커 네트워크 개념을 기반으로 세 가지 네트워크 모드를 지원한다.
이해하기 위해선 먼저 도커가 어떤 식으로 네트워크를 격리하는지 알아야 한다. Container는 자체적인 namespace를 가지고 있다. 네임스페이스 안에는 Routing Table, Socket, Netfilter가 포함되어 있다. 이렇게 격리된 네트워크 환경을 연결해 주는 것이 바로 veth(Virtual Ethernet Interface)이다. veth는 컨테이너의 네트워크 네임스페이스와 호스트의 네트워크 네임스페이스를 연결하는 가상의 이더넷 인터페이스이다. 이를 통해 컨테이너 간이나 컨테이너와 외부 네트워크 간의 트래픽이 전달된다. 도커에 네트워크는 호스트 옵션을 사용하면 컨테이너가 호스트의 네트워크 네임스페이스를 직접 사용할 수가 있다. 이렇게 되면 네트워크의 홉이 줄어들어 네트워크 성능을 최대화할 수 있지만 동시에 호스트와 포트 충돌의 위험이 있어 주의가 필요하다.
1. host Mode
- 컨테이너가 EC2 인스턴스의 네트워크 네임스페이스를 직접 공유한다.
- 같은 호스트에 동일한 포트를 사용해 여러 컨테이너를 가질 수 없으므로 포트 충돌에 주의해야 한다.
- 네트워크 성능이 우수하다는 장점이 있으나, 작업 정의에서 반드시 호스트 포트를 지정해야 한다.
2. bridge Mode
- 컨테이너가 도커 브리지 네트워크에 연결된다.
- 동일한 호스트 내 여러 컨테이너가 충돌 없이 같은 포트를 사용할 수 있도록 자동으로 동적 포트 할당(호스트 포트 0 사용)을 지원한다.
- 동적 포트 할당은 외부에 노출되는 포트 충돌을 방지하는 장점이 있다.
- 호스트 모드나 aws vpc 모드에서는 동적 포트 할당 기능이 지원되지 않는다.
3. awsvpc Mode
- Fargate를 포함한 ECS 환경에서 권장되는 네트워크 모드이다.
- 각 Task에 개별 ENI(가상 LAN카드)가 할당되어 VPC 내에서 독립적인 프라이빗 IP를 부여받는다.
- 보안 그룹을 개별적으로 적용할 수 있어 보안성이 강화된다.
- VPC 플로우 로그를 활성화하여 네트워크 트래픽 분석도 가능하다.
주의사항
- Task Provisioning 시 ENI가 추가되므로 provisioning 시간이 늘어날 수 있음
- 인스턴스마다 연결 가능한 ENI 수에 제한이 있음 (ex. C5 라지 인스턴스는 최대 3개 연결)
- VPC Trunking Mode를 활성화하면 추가적인 ENI 할당이 가능함
Service Communication
ECS 환경에서 서비스 간 통신을 위해 다양한 방법이 있다.
1. Cloud Map을 활용한 Discovery Service
- 간단한 DNS 디스커버리 서비스이며, 간단한 시스템 구성 요소이다.
- 클라이언트와 프로바이더를 직접 연결한다.
- 클라이언트가 서비스 엔드포인트를 찾기 위해 먼저 Route 53에 쿼리를 보내고, 클라우드 맵에 등록된 ECS 서비스의 IP 주소와 포트 정보를 기반으로 DNS 레코드가 업데이트되어 최신 정보를 반환한다.
- 하지만 이 방식은 호출 응답 시간 등과 같이 트래픽 정보를 제공하지 않는 단점이 있다.
2. Elastic Load Balancer
- ELB를 통해 연결하는 가장 쉬운 방법이며, ELB의 풍부한 기능 사용이 가능하다.
- 서비스 생성 시 ELB를 추가하여 트래픽 분산 및 헬스 체크 기능을 제공함으로써 안정성을 높일 수 있다.
- 하지만 각 서비스마다 ELB가 추가되면 비용이 증가하고, 하나의 ELB를 거치면서 지연 시간이 발생할 수 있다.
3. App Mesh
- 풍부한 트래픽 가시성이 제공되고, 세밀한 트래픽 제어가 가능하며, 암호화 및 인증도 제공된다.
- 사이드카 패턴을 활용하여 서비스 간 트래픽 제어 및 가시성 확보, 상호 인증(mtLS) 지원 등의 기능을 제공할 수 있으나, 설정이 복잡하여 러닝 커브가 존재한다.
4. ECS Service Conncet
- ECS 콘솔에서 클릭 몇 번으로 간편하게 서비스 커넥트를 생성한다.
- 서비스 통신 시에는 프론트엔드와 백엔드 서비스가 Service Connect Agent를 통해 통신하게 된다.
- 각 서비스에 대한 정보는 클라우드 맵의 네임스페이스에 등록이 되어있다. ECS는 Cloud Map으로부터 Service Discovery 정보를 가져와서 Service Connect Agent에 업데이트한다.
- 애플리케이션이 배포되면 Service Connect와 관련된 정보가 클라우드 맵에 등록이 되는 구조이다.
- Service Connect를 활성화하면 기존 메트릭 외에 트래픽 헬스 정보가 추가되어 인커밍, 아웃커밍에 대한 메트릭, 요청 정보와 같은 트래픽 정보가 제공되어 간편하지만 강력한 기능을 갖췄다.
Service ECS Security
AWS를 활용해 봤다면 IAM 권한을 두거나, 보안그룹, 정보 관리 등을 통해 보안을 강화했을 것이다. ECS도 마찬가지이다. 방법은 다양하고 각 환경에 필요에 맞게 세분화해서 설정하면 되는 당연한? 소리이다.. 하지만 ECS 영상에서 다뤘기 때문에 나도 간단히 정리를 해보자면 다음과 같다.
1. IAM 역할
- 태스크 롤(Task Role): 태스크 자체가 AWS 리소스(S3, SQS 등)에 접근할 때 필요한 권한을 부여한다.
- 태스크 실행 롤(Task Execution Role): 태스크가 프로비저닝 될 때 로그 드라이버 설정, 시크릿 매니저나 파라미터 스토어에서 민감 정보를 가져오는 작업 등, ECS 에이전트가 수행하는 작업에 필요한 권한을 부여한다.
- 서비스 링크드 롤: ENI 생성 등 ECS 관리 작업 시 내부적으로 사용되며, 사용자가 별도로 관리할 필요는 없다.
- 최소 권한 원칙에 따라 각 역할에 필요한 최소한의 권한만 부여하는 것이 중요하다.
2. 사용자 액세스 및 보안 그룹
- 컨테이너나 호스트에 대한 액세스는 인증된 사용자만 가능하도록 하고, Amazon ECR은 인증된 사용자만 이미지 푸시/풀 작업이 가능하도록 IAM 정책을 적용해야 한다.
- 보안 그룹은 최소 권한 모델을 준수하도록 설정하여, 불필요한 외부 접근을 차단한다.
- 만약 ECS 서비스가 ALB를 통해 오로라 DB에 접근해야 하는 경우, 해당 서비스의 보안 그룹만 오로라 DB의 인바운드 룰에 추가하는 식으로 관리한다.
3. 민감 정보 관리
- API 키, DB 비밀번호 등 민감 정보는 컨테이너 내부에 직접 저장하지 않고, AWS Secrets Manager나 Parameter Store를 활용해 안전하게 관리한다.
- 태스크 정의에서 시크릿을 참조하여, 컨테이너 시작 시 필요한 민감 정보가 주입되도록 구성한다.
4. 호스트 액세스
- 기본적으로 ECS에서는 호스트 레벨의 접근이 제한되지만, 필요시 AWS Systems Manager의 세션 매니저를 활용하여 키 관리 없이 접근할 수 있다.
Monitoring & Observability
물론 모니터링과 옵저버빌리티가 중요하고 좋은 건 알고 있다. 기존 서비스에서는 아직 두 시스템이 구축되진 않았고.. 정말 실제 서비스를 운영하는 게 아니라면 의무적인 요소는 아니어서 개념적인 것만 정리할 예정이다. (실제 영상에선 AWS Native 서비스들을 추천한다ㅎㅎ 당연한 게.. 저긴 AWS 자체가 상품을 판매하는 것이라 자사 상품을 소개하는 건 당연하다. AWS를 통해 다 진행하면 쉽고 편리하게 설정할 수 있다는 장점도 있겠지만 비용이나 다른 의존적인 측면에서 다 좋은 건 아니라 생각하기 때문에 각 상황에 맞게 알아보고 쓰면 될 것 같다.)
Logging & Monitoring
운영 시 User Access를 감시하거나 트러블 슈팅을 할 때 활용할 수 있다. 컨테이너와 애플리케이션 내부에 이벤트 로깅을 구현해서 Task에 이상이 발생하거나 배포 이후 문제가 발생했는지 확인하기 위한 로깅이 필요하다. 또한, 여러 Task들이 프로덕션 환경에서 실행되기 때문에 분산되어 있는 로그들을 중앙화된 저장소에서 분석하는 것이 필요할 수 있다.
Network and Host
- VPC Flow log를 활성화해서 VPC 내의 네트워크 트래픽을 캡처한다.
- CloudWatch를 활용해 컨테이너 호스트 로그를 중앙 집중화 및 알림 설정한다.
- 상태, 효율성, 가용성을 보장하기 위해 컨테이너 호스트를 모니터링한다.
Container
- 중앙 집중식 모니터링 및 저장을 위해 컨테이너화된 애플리케이션 로깅을 활성화한다.
1. 모니터링
- 전통적인 모니터링 도구는 CPU, 메모리 사용량, 요청 처리 시간 등 시스템의 일부 지표를 추적한다.
- CloudWatch Metrics, Logs, Alarms 등을 활용하여 각 컴포넌트의 상태를 실시간으로 모니터링한다.
2. 옵저버빌리티 (Observability)
- 모니터링이 빙산의 수면 일부만 보는 것이라면, 옵저버빌리티는 빙산 전체를 파악하는 것이다.
- 로그, 매트릭, 트레이스 정보를 통합하여 시스템 전체의 동작과 문제의 근본 원인을 파악할 수 있도록 도와준다.
- AWS 네이티브 도구(CloudWatch, X-Ray)와 관리형 오픈소스 서비스(Managed Grafana, Prometheus, AWS Distro for OpenTelemetry)를 활용하여 전체 스택에 대한 가시성을 확보할 수 있다.
결론
원래는 실습까지 함께 다루려고 했지만, 영상을 정리하다 보니 내용이 생각보다 방대해져서(사실 ECS란 무엇인가 간단한 설명과 실습을 다룰 예정이었으나 영상에서 다양한 설정까지 다루고 있어서 방대해졌다.. 하지만 한 번쯤 제대로 AWS를 알고 써보는 것도 좋을 것이라 생각돼서 깊게 써봤다.) 별도의 글로 나누어 작성할 예정이다.
결국 이 글에서 가장 중요한 점은, Amazon ECS가 기본적으로 Cluster, Task, Task Definition, Service라는 네 가지 구성 요소를 통해 컨테이너화된 애플리케이션을 배포, 스케줄링, 관리하는 완전 관리형 오케스트레이션 서비스라는 것이다. 즉, 작업 정의를 통해 작업(Task)을 만들고, 이를 클러스터에 배포하여 서비스를 운영할 수 있다는 점이다. 이 외의 세부적인 네트워크 구조나 서비스 구조 등은 처음 접하는 사람에게는 다소 복잡하게 느껴질 수 있다. 이는 점차 각 상황에 맞게 공부하면서 설계하면 좋을 것 같다.
각 상황에 맞게 보안, 네트워크, 모니터링 등의 요소를 적절히 설정하면서 ECS 환경을 구축하면, 안정적이고 효율적인 컨테이너 운영이 충분히 가능하다. ECS의 가장 큰 장점은 바로 이러한 단순성과 자동화된 관리 기능에 있다. 물론, 단점도 존재할 수 있으나(초기 설정의 복잡성, 특정 컴퓨팅 옵션 선택 시 제약 등), 각 상황에 맞게 적절히 판단하고 구축한다면 충분히 괜찮은 서비스임은 분명하다.
물론 아직 나도 ECS에 대해 다 알지는 못한다.(AWS에는 별 기능이 많아서..) 기존 프로젝트에서도 Docker를 활용했으므로 EC2를 통한 배포 방식과 비교했을 때, 배포 서비스(즉, EC2에서 ECS를 쓴다는 점) 외에는 큰 차이가 없다고 생각된다. 더불어 현 프로젝트에서 인프라 담당자가 따로 없기 때문에 ECS를 사용하면 AWS에 인프라 운영을 전적으로 위임할 수 있어서 한 번에 간편하게 관리하기 좋다는 장점이 크게 다가왔다. 그래서 이번 기회에 ECS를 공부하고 현 프로젝트에서도 계속 사용해보려 한다. 여유가 생기면 하나씩 기능들을 적용해보며 그 과정을 기록해 보겠다...ㅎㅎ
'Infra' 카테고리의 다른 글
[Infra] AWS 인프라 입문 (VPC, Subnet, Route Table, NAT Gateway, AZ..) (0) | 2025.03.05 |
---|---|
[Infra] Nginx란 무엇인가? 그리고 왜 사용하는가? (feat. Apache) (2) | 2024.11.08 |