이번엔 Compute Engine을 결정하자. 우리가 구현한 서버를 실행할 위치를 결정하는 것이다. 아래 3가지에 대해 의사결정이 필요하다.
오늘 하게 될 이야기는 AWS와 배경지식이 부족하면 조금 어려울 수도 있다. 읽다가 어렵다면 이고잉님의 AWS 강의로 흐름을 선회해도 좋을 것 같다. 컨테이너, dockerize, nginx, IAM 등등 이해되지 않는 부분이 있을 수 있을텐데, 큼지막한 흐름이 대충 이해가 된다면 머리아프게 다 이해하려 하지 말고 그냥 다음 내용으로 넘어가도 괜찮다. 이 컨텐츠는 텀을 길게 두고 두세번 정도 읽는 게 좋다고 생각한다. 일단 쭉 읽어보기 바란다.
필자는 초등학교 고학년(2012년) 때 마인크래프트 서버를 운영했었다. 내가 쓰던 데스크탑의 IPv4 주소에 oa.to 도메인을 묶어 두고, craftbukkit으로 서버를 직접 돌리는 방식이었다. 서버를 돌리기 위해 24시간동안 계속 컴퓨터를 켜두는 건 컴퓨터의 수명에 문제가 있지 않을까 걱정도 되고, 부모님 눈치도 보였기에 서버를 켜고 끄는 시간을 정해 공지해 두었었다. 3년만에 당시 운영하던 카페에 들어가보니, 켜지는 시간은 오전 8시 10분이었고 꺼지는 시간은 오후 11시였다. 등교하기 전에 켜두고, 잠들기 전에 껐나보다.
아무튼 결국 서비스 사용자의 트래픽을 처리하기 위해선 24시간 쉬지 않고 돌아가는 컴퓨팅 파워가 필요하다. 그게 PC던, 서버용 하드웨어를 구입해 구축한 홈서버던, 임대료를 지불해 호스팅받은 서버던, 클라우드 서비스던 말이다. 뭘 쓰던 '당장 되게 만드는 것'에는 문제가 없을 테지만, 여러 질문을 던져보며 가장 좋은 방향으로 의사결정 해보자. 백엔드 조직에 휴먼 리소스가 그리 많지 않은 상황이니, 되도록이면 서버의 컴퓨팅 자원같은 잡다한 부분을 직접 운영하는 일을 최대한 적게 만드려고 한다. 개발자는 어플리케이션 코드를 제공하기만 하면 되도록 말이다.
클라우드 플랫폼을 선택하겠다. 그 이유는,
SLA(Service-Level Aggrement, 서비스 수준 협약서)
를 통해 인프라의 가동 시간을 보장받는다. 부득이하게 SLA에 명시된 만큼의 서비스 수준을 보장받지 못한다면, 페이백이나 크레딧 등을 통해 돈으로 보상받을 수 있다. 백엔드 조직이 서버를 직접 운영한다고 치면, 클라우드 플랫폼 만큼의 높은 가동 시간을 보장할 수 없을 것이라고 판단했다.클라우드 플랫폼이 얼마나 편하며 비용 걱정이 줄어드는지는 한 번 써보면 알 것이다. 몇몇은 '클라우드에 너무 의존하지 말라'고들 하지만, 필자는 라우터 세팅같이 짜치는 일에 돈과 인생을 낭비하고 싶지 않다. 클라우드 컴퓨팅에 대해 조금 더 알고 싶다면 AWS의 '클라우드 컴퓨팅이란?' 문서를 읽어보자.
AWS(Amazon Web Service)
를 선택하겠다. 그 이유는,
Lambda를 선택하고, 추후에 ECS+Fargate로 마이그레이션을 진행하겠다. 그 이유는,
auto scaling
도 기본으로 제공받는다. 우리는 컴퓨팅 파워를 직접 운영할 필요 없이, 코드를 제공하기만 하면 된다. 트래픽이 적고, 얼마나 늘어날지 예측 불가능한 현재 배경에 가장 알맞다.ECS+Fargate
를 선택했다. 그 이유는 아래에서 설명한다.여기에 더해 terraform같은 Infrastructure as Code(IaC) 도구나,** EKS(Elastic Kubernetes Service)를 통해 kubernetes 인프라를 직접 운영하는 간지나는 모습도 욕심은 나지만 조직 상황을 감안해서 보류했다. kubernetes 등으로 컨테이너 클러스터의 orchestration을 직접 수행하는 것은 **비즈니스적 요구사항에 매우 유연하게 대응할 수 있겠지만, 조직이 크지 않은 상황에서 클러스터 자체 운영은 자칫하면 IaC와 kubernetes에 익숙하지 않은 현재 조직에게 휴먼 리소스의 낭비가 될 수 있으므로 ECS의 도움을 받으려 한다.
Amazon Lambda는 '호출 기반으로 코드를 실행해주는 서비스'라고 요약할 수 있다. 호출을 수행하는 주체, 즉 event source는 대표적으로 CloudWatch
, API Gateway
가 있는데, 그 예를 들면,
우리는 API Gateway를 사용하는 후자의 방식을 사용할테고, AWS Lambda를 이용해서 HTTP API 만들기라는 outsider님의 포스트를 천천히 읽어보면 대충 무슨 말인지 알 것이다.
위에 링크해 두었던 글을 읽어 보았다면, 우리는 Lambda에 코드를 배포하기 위해 아래의 과정을 거쳐야 한다는 것도 깨달았을 것이다.
물론 이걸 손으로 직접 클릭해가며 하진 않을테고 CLI에서 커맨드를 입력하는 방식을 사용하게 될텐데, 그렇게 생각하더라도 여간 귀찮은 일이 아닐 수 없다. update
같은 커맨드를 입력하면 알아서 패키징하고, S3에 올리고, lambda를 세팅하고, API Gateway를 세팅해주는 도구가 있다면 매우 편할 것이다. Python 판에서는 zappa라는 서버리스 배포 헬퍼 라이브러리와 AWS에서 개발하고 있는 서버리스 프레임워크인 chalice가 높은 인지도를 가지고 있는데, 이미 조직이 Flask와 Sanic을 통해 웹 어플리케이션을 개발하는 것에 익숙한 상태라서 배포에 대해 도움을 받을 수만 있으면 되고, zappa가 서버리스 배포에 부족함이 없으므로 굳이 러닝커브를 감수할 필요가 없다고 생각했다. 우리는 서버리스 어플리케이션 배포를 위해 zappa
를 사용할 것이다.
먼저 zappa는 AWS 리소스에 대한 접근 권한이 필요하므로, 권한을 부여해 주어야 한다. AWS 콘솔에 로그인하고(계정이 없으면 만들자.), IAM
이라는 서비스의 콘솔에 들어가 zappa를 위한 IAM 사용자를 만들자. 본인 계정의 AWS 콘솔에 접근할 수 있는 권한을 가진 또 다른 하위 사용자를 만드는 것이다. AWS 계정의 IAM 사용자 생성 가이드를 보며 따라하면 된다. 주의해야 할 것은,
프로그래밍 방식 액세스(또는 Programmatic access)
를 선택하자.AdministratorAccess
를 부여하도록 하자. 필요한 권한만 연결하고, 그룹을 만드는 것이 여러모로 좋지만, 이건 따로 챕터를 진행할 것이다.사용자를 생성하고 나면 Access Key ID
와 Secret Access Key
를 제공받을 수 있을텐데, CLI 터미널(cmd, terminal 등)을 켜고 아래의 순서에 따라 설정을 진행하자. AWS CLI 구성 가이드와 동일한 내용이다.
pip install awscli
커맨드를 실행해 AWS CLI 툴을 설치하자. 일부러 pipenv 대신 pip를 사용했다.aws configure
커맨드를 실행한 후 Access Key ID와 Secret Access Key를 붙여넣자. Default region name에는 원하는 지역을 AWS region 규칙에 따라 입력하자. 나는 서울 region을 사용할 것이므로, ap-northeast-2
를 입력했다.pipenv install zappa
커맨드로 의존성 목록에 zappa를 추가함과 함께 패키지를 본인의 가상 환경에 설치하고 프로젝트 루트 디렉토리에서 zappa init
커맨드를 입력해 zappa 설정을 초기화하자. environment, bucket name같은 것들은 적당히 잘 입력하거나 default로 설정되도록 그냥 엔터만 누르면 되고, 'Where is your app's function?'에 대한 답만 잘 입력하자. app 객체가 있는 경로를 입력하면 되는데, 현재 Hello World 서버 기준으론 run.py
모듈에 객체 이름이 app
이므로 run.app
이라 입력할 것이다. 필자의 경우 pipenv install 시 Python 3.7.1 버전으로 초기화되었는데, zappa가 Python 2.7과 3.6만을 지원해서 pipenv install --python 3.6
커맨드로 pipenv를 다시 초기화하고 진행했다. 성공하면 zappa_settings.json
이라는 파일이 새로 생길 것이다. pipenv install zappa, zappa init 직후의 스냅샷
이제 배포 준비가 완료되었지만, 문제는 Sanic 어플리케이션을 zappa로 업로드하는 과정에 오류가 많다는 것이다. zappa에서는 마이크로 프레임워크로 Flask를 공식 지원하고 있고, Sanic은 Flask-like하게 만들어져 있으므로 Hello World 서버를 Flask 기반으로 변경하자. Pipfile에도 반영하고, 코드에도 반영해야 한다. 변경 직후의 스냅샷
이제 정말 배포만 남았다. zappa deploy
를 입력하고 조금 기다리면 https://abc.execute-api.us-east-1.amazonaws.com/...
같은 형태의 URL이 콘솔에 보여질 것이다.
$ zappa deploy
Calling deploy for stage dev..
Downloading and installing dependencies..
...
Packaging project as zip.
Uploading blog-sampleapp-dev-1547890064.zip (9.9MiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 10.4M/10.4M [00:00<00:00, 21.9MB/s]
Scheduling..
Scheduled blog-sampleapp-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading blog-sampleapp-dev-template-1547890072.json (1.6KiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 1.66K/1.66K [00:00<00:00, 60.0KB/s]
Waiting for stack blog-sampleapp-dev to create (this can take a bit)..
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:12<00:00, 4.31s/res]
Deploying API Gateway..
Deployment complete!: https://jv84woiwmc.execute-api.ap-northeast-2.amazonaws.com/dev
그대로 복사해서 브라우저로 접속해 봤을 때, 'Hello World'가 뜨면 성공이다. 사람들이 그렇게나 말하던 서버리스 어플리케이션을 배포한 것이다.
이번 주제는 배포 자동화다. 원래 CI(Continuous Integration)와 CD(Continuous Deployment)같은 것들을 이야기해보려 했으나, 배포 자동화라는 용어가 덜 추상적이고 더 명시적이라 용어 선택을 선회했다. 도입 이유 배포 자동화 배포라는 과정은 불필요한 반복 작업이다. 우리가 만들고 있는 웹 어플리케이션의 경...
이번엔 서비스 운영을 위한 메인 데이터베이스를 결정하고, AWS 클라우드 위에서 해당 데이터베이스 엔진을 사용하는 인스턴스를 하나 띄워보자. 가상 컴퓨팅 환경 하나 단위를 AWS에서는 인스턴스라고 부른다. 도입 이유 데이터베이스 데이터베이스는 엑셀을 떠올리면 된다. 데이터베이스의 가장 중요한 특성은 구조화된 데이터를 관리한다는 점이다. 'I...
이번엔 Compute Engine을 결정하자. 우리가 구현한 서버를 실행할 위치를 결정하는 것이다. 아래 3가지에 대해 의사결정이 필요하다. * 어떤 컴퓨팅 파워를 이용할 것인지(출처) * 만약 외부 서비스를 이용하기로 했다면, 어떤 서비스를 사용할 것인지 * 해당 서비스에서 제공하는 컴퓨팅 엔진들 중 어떤 것을 사용할 것인지 등 오늘 하게 ...
이번엔 의존성 관리 도구를 결정하자. pip, npm, yarn, gem, maven, gradle 등과 같은 의존성 관리/빌드 도구를 써본 적 없다면 이해하기 어려울 수 있으니 의존성 관리 도구(Dependency Manager)라는 글을 읽어보자. 프로젝트 한두번 하면서 의존성 관리를 해 본 경험이 있다면 더욱 좋다. 도입 이유 의존성 관...
문서화도 다 끝났으니 로직을 코드에 옮기기만 하면 된다. 그러나 아직 어떤 언어를 쓸지/의존성을 어떻게 관리할지/어떤 데이터베이스를 어디서 운영할지와 같은 것들이 정해지지 않아서 바로 개발에 착수하기는 어렵다. 이번에는 어플리케이션 기술스택(프로그래밍 언어와 프레임워크)을 결정하고, /에 GET 요청 시 'Hello World'를 text/plain으로 반...
안녕하세요 올려주시는 글 잘 읽고 있습니다!
저는 서버리스 프레임워크들에 대해 관심이 많기도 하고
PlanB 님께서 어떤 기술의 도입에 대한 의사결정의 근거를 잘 정리해 주시니
궁금한 마음에 여쭤봅니다
Python Serverless 프레임워크 중에는
인지도 면에서는 Serverless Framework 도 널리 알려져있고
chalice 는 aws 에서 개발한 오픈소스 프레임워크인데
zappa 만이 거의 유일 하다고 판단하신 이유가 있을까요...?
(두 가지 다 편하게 잘 사용했던 경험이 있어서요. 저는 현재 Serverless Framework 를 사용 중입니다)
혹시 다른 것도 사용해 보셨으면 어떤 면에서 zappa 가 좋았는지 알려주시면
큰 도움이 될 것 같습니당
감사합니다.