Serverless [email protected] 살펴보기에 이어서... serverless 도구 살펴보기 2탄...

목차

  1. Zappa
  2. 관심갖게된 계기
  3. 특징
  4. 실습
  5. 유용한 문서

1. Zappa↩︎

python을 위한 serverless 도구. 현재는 aws 기반에서만 작동합니다.

2. 관심갖게된 계기↩︎

2.1 aws 기반의 serverless 서비스만 경험하면서 생각한것이다.

2.2 라이브러리(패키지)는 function을 올리는(배포하는) 시점에 클라우드가 설치해줘야한다고 생각했다.

2.2.1 실제로 google cloud function은 그렇게 하고있는것 같다.

declare them in the package.json file, and Cloud Functions will download them for you when you deploy.

현재 node만 지원하는데 python을 지원하게되면 requirements.txt, ruby를 지원하게되면 Gemfile.lock을 이용하여 의존성부분을 해결하지 않을까...?

2.2.2 google cloud function 처럼 의존성 관련 파일(ex. package.json)을 직접 참조하여 하지 않더라도, 업로드한 function이 실행되는 환경에서 작동하는 native module이 필요한 라이브러리를 사용 할 수 있게 해줘야한다고 생각했다. 그나마 현재까지는 이 방법이 제일 쉬운것 같다.

2.3 관련 도구들이 이제 막 1.0을 찍기 시작하고, 아직도 성숙해야할 부분이 많은 상태이기도하고, 내가 rails나 django 류의 프로젝트의 디렉터리 구조라던지 공통으로 사용되어야할 함수들이 위치해야할 곳이 best practice나 관습으로 정해져있는 framework에 익숙하다보니, 어플리케이션의 구조를 스스로 잡아야하는 것에 적지 않은 스트레스를 받고 있었다.

3. 특징↩︎

3.1. 의존성이 있는 패키지를 꽤(?) 알아서 처리해줌.

3.1.1. 2.2에서는 클라우드가 의존성을 해결해줘야한다고 생각했지만 zappa를 접하고, 클라우드가 안해주면 프레임웍이 해줘도 상관 없을꺼 같다. 결국 내가 원하는건 의존성 있는 패키지를 내가 신경쓰지 않는것이기때문에...

3.1.2. 그렇다면 어떻게 구현을 했나?

3.1.2.1. virtualenv를 사용하여 VIRTUAL_ENV 환경변수에 저장된 현재 venv의 디렉터리를 가져오고 하위의 site-packages 디렉터리를 참조하여 zipping함.

3.1.2.2 native module이 필요한 패키지는 lambda-package(requirements.txt in zappa, pypi)를 통해서 precompiled된 패키지가 zipping시에 들어가게된다.

3.1.2.3 결국 정리해보면 pure python 패키지는 zappa deploy 명령을 실행하는 개발환경의 site-packages를, native module가 필요한 패키지는 lambda-package 를 통해서 받아지고 zipping 된다. zappa가 requirements.txt를 참조하는건 아니다.(requirements.txt에 추가하지 않고 패키지를 설치한 상태로 deploy를 해보면 artifact에 해당 패키지가 포함되어 있다. zappa 코드상으로도 그렇게 구현되어있다.)

3.2 django와 flask를 지원한다.(?)

3.2.1 django와 flask를 지원하지만 약간 애매하다.

3.2.2 위 두가지 프레임워크를 지원한다고하면, 장고에선 urls.py에 정의된대로 적절히 배포되고, flask를 지원한다고 하면 @app.route를 몽땅 다 찾아서 적절히 배포되는 걸 상상했다.

3.2.3 그게 아니라 django 혹은 flask 프로젝트를 통채로 올리고, lambda에서 실행하는 구조

4. 실습↩︎

$ mkdir zappa_demo
$ cd zappa_demo
$ virtualenv env
$ source env/bin/active
$ pip install zappa flask bcrypt
$ zappa init
$ cat > your_module.py
from flask import Flask  
app = Flask(__name__)  
import bcrypt  
from flask import jsonify

@app.route('/')
def index():  
    return jsonify(bcrypt.hashpw("demo".encode('utf-8'), bcrypt.gensalt()))

@app.route('/json')
def json():  
    return jsonify({'a':1})

if __name__ == '__main__':  
    app.run()
^C
$ zappa deploy dev

5. 유용한 문서↩︎