Loading
2022. 5. 8. 01:55 - lazykuna

AWS를 이용하여 클라우드 아키텍처 구성하기

어쩌다 보니 AWS를 적극적으로 사용하는 회사에서 일을 하게 되었는데, 단기속성을 위해서 14가지 AWS 구축 패턴에 대한 책도 읽어가며 열심히 공부했습니다. 처음에는 “왜 굳이 이런 것까지 써가며 운영을 하지? 오버헤드 크지 않나?”라는 생각이 들었는데, 공부하다보니 다 이렇게 하는 이유가 있더라고요.

그동안 배운 것들을 적당히 정리할 겸, AWS를 이용해서 만든 서버리스 아키텍쳐의 모습과 그 이유에 대해 기록으로 남깁니다.

AWS란?

Amazon Web Service: 아마존에서 제공하는 여러 클라우드 서비스를 일컫는 말입니다.

시스템을 구매하고 유지보수, 인프라 구성하는 모든 비용 없이 인스턴스만을 제공함으로서 저렴한 비용과 환경 구축의 편리함을 내세우는 이점이 있습니다.

TMI) 다만 개인이 쓰기엔 솔직히 좀 비싸고, Too much한 요소가 많은 것은 확실합니다. 분산 시스템을 기반으로 한 Scalability나 단일 실패점이 없는 설계, 리전을 감안한 엣지 컴퓨팅 같은거나 복제 등은 보통 엔터프라이즈를 위한 요소니깐...

아무튼 AWS에서는 시스템을 구축하기에 이용할 수 있는 정말 많은 “AWS 서비스”들을 제공하고 있으며, 각각은 다른 특성들을 가지고 있습니다. 이것들을 어떻게 적절하게 활용할 수 있는지 간단하게 적어놓습니다.

Before Start: 어떤 아키텍쳐를 가진 서비스인가?

역시나 기업/엔터프라이즈 급의 서비스가 좋은 예시가 될 것 같습니다. 해당 서비스가 가져야 할 특징은

  • 높은 안정성(가용성)
    장애 발생시에도 장애가 발생한 인스턴스 이외의 다른 인스턴스로 포워딩시켜 작동하도록 해야 합니다.
  • 빨라야 함
  • 스케일 가능
    높은 리퀘스트가 들어오면 자동으로 스케일링이 이루어 질 수 있도록 해야 합니다.
  • 적은 병목 / 단일 실패점 지양
    일부 서비스의 실패나 병목으로 인해 전체 서비스가 지연되거나 하는 일이 없어야 합니다
  • 유지보수 및 관리까지 용이하면 더 좋습니다.

정도로, 이러한 논리가 DB, 리소스, 그리고 도메인 로직까지 모두에 거쳐서 적용되어야 합니다.

마침 Implementing Microservices on AWS 에서 좋은 예시도를 많이 가지고 있어서, 그 중 일부를 가져왔습니다.

가장 큰 단위에서의 아키텍쳐 구상도입니다. 몇 가지 빠져있는 부분이 있는데,

  • 도메인 네임서버 : Route53
    • Internet 에서 DNS 요청이 오면 이것을 CloudFront에 쏴주는 역할을 하게 됩니다. (두 개 사이에 있어야 함)
  • Persistent storage (RDB/NoSQL/S3 등)
    • 일단은 EC2(도메인 로직)에 묶여 있는 것으로 디자인 되었습니다.
    • 그리고 Static resource의 경우, EC2에서 리턴하도록 하는 것보다는 S3에서 리턴하도록 하는 것이 가능하다면 좋습니다. (비용 측면)
  • 로깅 (CloudWatch)
    • 기본적으로 가용성 확인에 용이하고, 또 아주 고급 기능까지 지원하는 건 아니지만 아카이빙 수준의 용도로서는 또 얘만큼 쓰기 편한게 없습니다.

Persistent storage와 같은 경우는 아래와 같이 도메인 로직이 들어가 있는 EC2/Lambda에 붙어서 아래처럼 표현해 줄 수 있을 것입니다.

그리고 MicroArchitecture의 경우 마이크로서비스 사이에서의 통신을 위해서 gRPC를 이용할수도 있고, 신뢰성이 필요한 경우 SQS를 사용할 수도 있습니다.

큰 틀은 이렇고, 이제 각각 쓰인 요소들에 대해서 간략하게 알아보겠습니다.

Amazon Route 53

이건 그냥 흔하디 흔한 DNS nameserver 서비스인데, 물론 단일 구성이 아니라 클러스터로 구성되어 있어 failover에 강하다는 이점이 있습니다. 그리고 AWS 서비스들과의 쉬운 연동도 은근한 장점. 생태계를 인질삼아서 장사하는 건가!

CloudFlare 쓰면 개인 용도 수준으로는 공짜로 커버되어서 좋긴 합니다

 

(추가) 그리고 장애시 백업 사이트에 동적으로 라우팅하는 기능도 있어 availability에 도움이 될 수 있습니다.

Amazon CloudFront (CDN)

CDN은 정적 리소스 “캐시" 역할을 수행합니다. Static resource를 보다 빠르고 저렴하게 공급해주는 역할을 해 주기 때문에, 요즘의 웹 서비스 설계에서는 필수요소로 자리잡고 있습니다.

물론 동적 컨텐츠의 경우나, CDN 내에 없는 리소스의 경우에는 뒷단에서 결과를 가져와야 합니다.

Amazon S3

S3는 정적 데이터를 저장하는 역할을 합니다. 그런데, 잘 생각해보면 정적 데이터는 2가지 부류가 있습니다.

일반적으로는 웹 리소스와 같이 비교적 접근 빈도가 잦은 경우입니다. 이 경우 액세스 속도가 비교적 빠른 편입니다. 이러한 특성 상, CDN에서 데이터를 가져 오지 못할 경우, S3에서 데이터를 가져오도록 할 수 있습니다. 왜냐하면 S3가 정적 데이터를 제공하는 방법 중에서 가장 저렴하고 속도도 나쁘지 않은 편이기 때문입니다.

그리고 장기 저장이 필요한 데이터가 있을 수 있는데, 이런 경우를 위해 S3 Glacier 이 따로 존재합니다. 액세스 시간이 기하급수적으로 증가할 수 있어 일반적인 용도로는 적합하지 않으나 오래 묵혀야 하는 데이터들에게는 그렇게 중요한 요소는 아니니까 또 충분히 매력적일 수 있겠죠.

Amazon API Gateway

이제 본격적인 동적 데이터를 서빙할 차례입니다. 보통 프론트엔드 이외의 도메인 작업은 API를 통해 처리하게 되는데, 여기서는 API Gateway가 이러한 역할을 하게 됩니다.

그런데 굳이 API Gateway가 무엇을 하길래 필요한 걸까요? 그냥 EC2가 요청 바로 받아버리면 되는 것 아닐까요? API Gateway가 하는 일을 살펴보면 아래와 같습니다.

  • 인증 기능 제공
    은근히 큰 요소 중 하나입니다. 다양한 서비스들에 대해서 모두 통합된 인증 방식을 가지고 있도록 하는 것도 일인데, API Gateway가 제공해 주는 기능으로 이를 해결해 줄 수 있다는 건 큰 장점입니다.
  • 라우팅, 로드밸런싱, 안정성
    언제나 그렇듯 아마존이 제공하는 서비스 답게 scalable 하고 안정적입니다. 서비스는 죽을 지언정 API Gateway는 안 죽습니다. 그리고 기본적으로 라우팅 기능이 있기 때문에, API의 endpoint가 다른 서비스들로 라우팅 되어야 하는 경우 이를 직접 구현할 필요가 없다는 이점도 있습니다.
    • 덤으로 어느 정도의 통계 지표 자료도 제공해줍니다. 문제 발생시 원인을 찾기 위한 스타팅 포인트로도 약간의 도움이 될 수 있을지도
  • 아마존 서비스들과의 높은 호환성
    Lambda 쓰면 API Gateway를 쓰는 건 거의 필연적입니다 (!) 아니면 서비스를 밖으로 꺼낼수가 없음... 이거 완전 강매
  • 서비스 디스커버리
    라우팅 기능으로 인해 자연스레 생기는 강점입니다. 각각의 마이크로서비스가 다른 서비스들의 IP 주소를 알 필요 없이, API Gateway에 리퀘스트를 넣으면 알아서 해당 서비스로 연결해줍니다.

Amazon EC2

컴퓨터 인스턴스 임대 서비스입니다. 서버 렉 설치하고 운영체제 깔고 인프라 연결하고 그거 관리할 사람 뽑고 할 수고를 줄여주고, 고장날 때 부품 갈아야 하는 수고, 그리고 서버 스펙이 실수요에 맞지 않아서 낭패를 보는 일을 없애주기 때문에 그것만으로도 충분한 가치가 있는 서비스입니다.

다만, 근래에는 서버리스 플랫폼들이 급부상하면서 그 빛이 많이 바래긴 했죠. 인스턴스에 제품이 돌아가기 위해서는 또 추가 세팅을 해줘야 하는데, 서버리스는 그럴 필요가 없으니까요.

그런데 Micro급 서버 쓸거면 여전히 그냥 라즈베리로 홈 서버 쓰는게 훨씬 낫지 않나 싶습니다. 쓸데없이 비싸 🤔...

Amazon EBS

EC2 인스턴스에 연결되는 저장소입니다. 굳이 이런식으로 저장소와 인스턴스를 따로 분리한 것 또한 확장성 및 유연성의 일환이죠. 덕분에 저장한 데이터 그대로 인스턴스를 업그레이드 한다거나 하는 방식도 가능합니다. 기존 On-premise 방식에서는 상상하기 어렵거나, 큰 비용이 드는 일이었음을 생각하면 꽤 흥미롭습니다.

Amazon EKS(ECS)

무려 AWS에서 제공하는 Kuberenetes 서비스입니다. 사용자는 Container 이미지만 올려주면 나머지는 EKS가 알아서 다 해줍니다. K8S 서버들은 물론 알아서 스케일링 되고 안정성 또한 보장되고요.

  • ECS는 마찬가지로 컨테이너 구동 서비스인데 Kubernetes 보다 더 아마존 시스템에 최적화되어 있다는 특징이 있는 정도입니다.
  • 물론 Pod들을 돌릴 EC2들은 별매해야 합니다. 공짜로 해주는 법이 없지 😅

Amazon Lambda

최근 밀고 있는 Serverless 아키텍쳐의 최전선에 위치한 서비스입니다. 이건 EKS처럼 이미지를 만들어서 넣을 필요도 없이 정말 코드만 넣으면 된다니, 정말 멋지지 않나요! 심지어 간단한 수준이지만 모니터링 기능, 자체 테스트 기능 등 또한 제공해줍니다.

그리고 EC2 대비 의외의 장점이 Lambda는 정말로 “코드를 쓴 만큼만" 비용을 부담하면 된다는 점입니다. 따라서 주기적인 배치성 Job 같은 경우라면 Lambda로 구동하면 훨씬 비용 절감 측면에서도 좋은 결과를 볼 수 있습니다.

Amazon RDS

아마존에서 제공하는 RDB 서비스입니다. 물론 EC2 인스턴스에 RDB(Mysql 등) 깔고 써도 되지만, 스케일링 하기도 불편한데, 굳이 RDS가 다 해주는 걸 직접 할 필요가 없겠죠?

그리고 failover에 대비해서 필요시 replication 또한 지원해주고 있습니다. 힘들여 세팅하지 않고도 이런 것들을 쉽게 설정이 가능하다는 점이 AWS 서비스들의 장점이라는 생각이 다시금 듭니다.

Amazon Aurora

RDB 기반인데, 이쪽은 MySQL과 같은 전통적인 DB를 그대로 쓰는 것이 아니고 AWS가 클라우드 환경에 알맞게 재설계를 한 RDB로서 고성능이 필요할 때 사용을 고려해 볼 수 있습니다.

물론 Aurora가 만능은 아닙니다! RDB는 충분히 빠르지 않기 때문에 기본적으로 가능하면 NoSQL로 해결이 가능한지를 고려해 보아야 하고, 그 다음으로 RDB를 부득이하게 써야 한다면 충분한 튜닝이 되었는지 또한 잘 고려가 되어야 합니다.

Amazon DynamoDB

AWS에서 제공하는 NoSQL이라고 보면 됩니다. 대충 MongoDB를 scalability+sharding 세팅을 기본으로 해서 서비스 해주는 식이라고 생각하면 됩니다. 개발자는 그냥 가져다 쓰기만 하면 됩니다.

Amazon CloudWatch

서비스들에서 발생하는 로그를 저장하고, 이를 이후에 검색하고, 서비스 각각을 모니터링까지 하며 필요하다면 알람도 보내주고, 자동 복구까지도 지원하는 서비스입니다. 서비스 Availability를 유지하는 데 있어서 사실상 필수적입니다.

그리고 클라우드워치는 내부적으로 로그를 S3에 저장합니다. 덕분에 매일 몇십, 몇백GB 생성되는 로그도 문제 없이 저장이 가능하며, 이들에 대한 검색 속도도 상당히 빠른 편입니다.

이외에도...

확실히 AWS에서 제공해 주는 서비스들은 하나같이 플랫폼 구성 및 안정성에 시간 들일 필요가 없게 해준다는 게 제일 큰 매력이라는 생각이 듭니다.

물론 위에서 소개한 것 이외에도 많은 서비스들이 있습니다. Redis와 유사한 ElastiCache, EC2 스케일링에 쓰이는 ELB, 심지어는 머신러닝 관련 서비스들 등... 나머지들도 비슷하게 직접 On-premise로 구성했던 내용들을 AWS가 직접 서비스 해주는 식의 성격을 가지고 있어서, 적절하게 가져다 쓰면 원하는 그림을 충분히 만들 수 있을 거라고 생각됩니다.

그리고, 결국 AWS의 각 서비스 성격을 아는 것이 제일 중요합니다. 예를 들어 Storage만 해도 S3, S3 Glacier, EBS, EFS가 있는데 비슷해 보이지만 내부 구현이나 성격이 몹시 다릅니다. 또 DB의 경우 종류가 DynamoDB, RDS(Aurora), ElastiCache 3 가지가 있는데 마찬가지로 각각의 성격이 아주 다릅니다. Consistency의 중요성과 TPS(throughput이나 latency)의 스케일에 따라서 어느 것을 골라서 어디에 쓸지 정하는 것이 결국은 중요하고, AWS는 그것들을 구성하는 데 있어 수고를 덜어줄 뿐이니까요.

또 Lambda 같은 서비스들의 특성을 잘 살려서, On-premise 환경일지라도 클라우드를 적절히 활용하면 가격 측면에서도 더 유리할 수도 있겠네요.

Q: AWS 서비스를 로컬에서 테스트 할 수는 없을까?

하지만 이러한 훌륭한 플랫폼도 테스트에서는 단점이 생깁니다. 모든 것을 AWS 의존하기 때문에 기본적인 테스트마저도 AWS를 요구하기 때문입니다. AWS api 자체를 mocking 하는 것도 하나의 대안이 될 수 있으나,

다행히도 아마존에서는 이에 대한 대안으로 Localstack 이미지를 제공하고 있습니다. 이를 통해 로컬에서 AWS의 다양한 서비스 (DynamoDB, CloudWatch, S3, SNS, SQS ...)를 테스트 해 볼 수 있다는 점이 있습니다. 다만 기능(functionality) 측에서만 호환된다 뿐이지, 동일하지는 않다는 점을 염두에 두어야 합니다. 스케일링 그런 건 없어요 ㅎㅎ

참고

댓글을 입력하세요