본문 바로가기

개발

AWS에서 ECS 도입을 시도하면서 경험한 것들...

반응형

이 글을 쓰는 목적

우선, 저는 ECS를 적용하지 않았습니다. 다만, ECS 도입을 시도하면서 굉장히 많은 것들을 알게 되었고 해당 경험을 정리하고 싶었습니다. 서버 개발에 대한 지식이 별로 없는 상태에서 'AWS 공식 문서', 'Medium', '국내의 각종 블로그'를 보면서 ECS 적용법을 공부하려니 어려움을 많이 겪었습니다. 간단하게 적용해보는 예제들은 많이 있었지만 실제 서비스에 적용하려니 막히는 부분이 많았습니다. 그래도 약 80시간의 사투 끝에 어느 정도 구조를 이해하게 되었고, 지금 우리 상황에서는 ECS를 도입하는 것이 좋지 않겠다는 결론에 도달했습니다. 혹시나 비슷한 고생을 하시는 분들에게 도움이 되길 바랍니다. 단, 해당 글에서 ECS에 대한 튜토리얼을 제공하지는 않습니다. 글 중간중간 도움을 받았던 콘텐츠들을 소개하겠습니다.

제가 알게 된 것이 잘못된 것일 수도 있습니다. 혹시 잘못된 것이 있다면 댓글 남겨주시면 감사하겠습니다.

ECS란 무엇인가?

ECS는 Amazon에서 제공하는 '컨테이너 오케스트레이션 툴'입니다. 비슷한 툴로서는 KubernetesDockerSwarm이 있습니다. 이 글을 읽으시는 분들은 ECS에 대해서 적어도 생각하기 때문에 자세한 설명은 생략하겠습니다.

왜 ECS 사용을 고려했는지

기존에는 AWS에서 T3.Samll스펙의 EC2 한대의 서버에서 Docker Compose를 이용하여 사용하고 있었습니다. 해당 Docker-Compose는 (1) Django 기반의 메인 앱, (2) Celery Worker, 그리고 이 둘의 통신을 위한 (3) RabbitMQ 브로커, (4) 소켓을 위한 Sanic 기반의 앱, 마지막으로 사용자 요청을 받아서 적절한 앱에 요청을 분배해 줄 수 있는 (5) Nginx 하나로 구성되어 있었습니다. '작은 서버 한대에 왜 이렇게 많은 앱들이 들어가 있나'라고 생각하실 수도 있지만, 스타트업이기 때문에 비용을 절약해야 하는 상황이었고 심지어 Django 앱과 Sanic 앱은 도커 컴포즈의 scale 옵션을 사용하여 각 3개, 2개로 스케일링하여 사용하고 있었음에도 일평균 활성 사용자 수 500~700명 정도는 충분히 감당하였습니다. 물론, 레이디스 서버는 별개로 두어 어느 정도 서버의 무리를 줄여주긴 했습니다.

문제는 일평균 활성 사용자 수가 1000명이 넘어가면서 발생했습니다. 오후 2시경이 되면 사용자들이 급격하게 많아지면서 기존 서버가 느려지기 시작해서 사용하기 불가능할 정도가 되었습니다. 서버를 껐다 켜면 정상적으로 돌아왔지만 언제까지나 그럴 수는 없는 노릇이었기 때문에 ECS 도입을 고려했습니다. Kubernetes는 굉장히 어렵다고 익히 들었기 때문에 서버 운영 경험이 많지 않은 저로서는 고려 대상이 아니었고, Docker Swarm은 기능이 빈약하다는 평을 들어서 고려하지 않았습니다.

학습과정

  • 우선 닥치는 대로 검색해가면 공부했습니다. AWS 공식 문서를 비롯해서 여러 블로그와 유튜브 등을 봤습니다.

  • 사전 지식이 별로 없는 상태에서 문서들을 보니 (특히 AWS 공식 문서) 용어부터 이해가 되지 않았습니다.

  • AWS VPC를 공부하게 됩니다. 이를 통해 VPC, 서브넷, 인터넷 게이트웨이, 보안 그룹 등을 완전히 이해합니다.

  • Fargate에 대해서 알게 됩니다. 사용량에 대해서만 비용을 지불하면 되고 굉장히 쉽고 유동적으로 스케일링할 수 있는 것이 매력적으로 다가옵니다.

  • ECS + Fargate가 매우 매우 매우 비싸다는 것을 깨닫습니다. 비용을 직접 계산해보니 같은 자원에 대해 4~5배는 더 나왔습니다. 서버의 규모가 크고 서버의 자원 활용량이 일정하지 않아 노는 자원이 많이 발생한 경우나 DevOps 관련 인력을 구하기가 어려우며, 이에 대한 비용을 줄이고 싶은 경우가 아니면 비용 절약이 불가능합니다. 사실상 초기 스타트업에게는 도입이 쉽지 않을 것 같습니다.

  • 대안으로 ECS + EC2를 적용하기로 결심하고 이것저것 공부합니다.

  • 하나의 서비스를 띄울 때는 잘 되었는데, 여러 서비스를 띄우고 해당 서비스들을 서로 연결하기가 너무 어려웠습니다. 여러 서비스들을 하나의 태스크에 넣는다면 bridge 네트워크 모드를 통해서 각 컨테이너들을 찾아서 통신할 수 있지만, 그럴 경우에는 연결대상이 각 태스크에만 한정되고 스케일링이나 로드밸런싱이 적절히 되지 않습니다. 그리고 미래를 생각했을 때도 지양해야 할 패턴이라고 판단했습니다.

  • 하지만 여기서 또 문제가 발생합니다. EC2에서 awsvpc모드를 이용한 서비스 디스커버리는 각 서비스에 ENI 주소가 할당되고 이를 기반으로 해당 서비스를 찾는 방식인데, 각 EC2 인스턴스는 ENI의 개수가 제한되어 있습니다. T3.Small의 경우 ENI가 2개로 제한되어 있습니다. 심지어 1개는 EC2 인스턴스에 해당하기 때문에 한 개의 인스턴스에 추가적으로 하나의 서비스밖에 못 만든다는 말입니다. AWS에서 ECS를 위해 추가적으로 ENI를 가질 수 있는 ENI Trunking을 지원해 주지만, 이 또한 일부 인스턴스 타입에만 지원됩니다.

마무리

결론적으로 ECS 도입은 현 상황에서 맞지 않는다는 결론에 도달하고, 우선적으로 사용이 간편한 Docker Swarm을 사용하기로 했습니다. Docker Swarm에서도 기본적인 스케일링이나, 다른 도커 이미지를 통해 Monitoring을 할 수 있기 때문에 DevOps에 대해 여력이 안되는 스타트업들에게는 굉장히 좋은 옵션일 것 같습니다. 나중에 규모가 커지면 Kubernetes를 도입하거나, ECS나 EKS + Fargate를 도입하면 좋을 것 같습니다. 역시, 모든 상황에 다 좋은 기술은 없습니다. 현재 개발규모나 상황, 맥락에 따라 적절한 기술을 선택하는 것이 중요하다는 것을 또 한 번 배웠습니다. 감사합니다 :)

혹시 작성 내용에 틀린 게 있다면, 코멘트 달아주시면 감사하겠습니다.

반응형