AWS Lambda를 Docker로 구축하기

김철기·2022년 2월 22일
6
post-thumbnail

안녕하세요. Gameeye에서 deeplol.gg 서비스를 개발 중인 김철기입니다.
클라우드 서버 인프라 구축, 백엔드 개발, 딥러닝 모델 연구를 담당하고 있습니다.

AWS Lambda는 단순 코드뿐 아니라 Docker Image로 실행시킬 수 있습니다. 해당 포스팅은 Lambda를 Docker로 구축하는 방법을 가이드합니다.

AWS Lambda의 이해

AWS Lambda는 Amazon Web Services의 일부로 Amazon에서 제공하는 이벤트 중심의 서버리스 컴퓨팅 플랫폼입니다. 이벤트에 대한 응답으로 코드를 실행하고 해당 코드에 필요한 컴퓨팅 리소스를 자동으로 관리하는 컴퓨팅 서비스입니다.

Docker의 이해

도커는 리눅스의 응용 프로그램들을 프로세스 격리 기술들을 사용해 컨테이너로 실행하고 관리하는 오픈 소스 프로젝트입니다. 도커 웹 페이지의 기능을 인용하면 다음과 같습니다: “도커 컨테이너는 일종의 소프트웨어를 소프트웨어의 실행에 필요한 모든 것을 포함하는 완전한 파일 시스템 안에 감싼다.”

Lambda를 Docker로 구축할 때의 장점

Lambda를 Docker로 구축할 때의 장점은 크게 2가지 입니다.

  1. 서비스에 필요한 리소스 용량이 커져도 구축 가능하다.

    • Lambda의 기본 제한 용량은 250MB입니다. 이는 tensorflow와 같은 고용량 라이브러리르 포함하는 경우 문제를 발생시킵니다.
    • Docker를 이용하면 최대 10GB의 컨테이너 이미지까지 배포할 수 있어 해당 문제점을 극복할 수 있습니다.
  2. 이미지 단위로 관리가 용이하다

    • Docker가 가지고 있는 일반적인 장점입니다.
    • github로 소스의 버전을 관리하듯 Docker Image로 서비스를 버전관리 할 수 있습니다.

Docker 설치 및 코드 구현

  • 도커 설치
    로컬 PC 또는 EC2에 Docker를 설치합니다.

apt가 repository를 사용할 수 있도록 패키지를 설치

sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

Docker의 공식 GPG키 추가

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

apt source list에 repository 추가

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

apt를 update하고 Docker 설치

sudo apt-get update
sudo apt-get install docker-ce

python3.8 환경에서 git 코드를 불러와 handler를 실행하는 file을 작성합니다.

FROM amazon/aws-lambda-python:3.8

RUN /var/lang/bin/python3.8 -m pip install --upgrade pip

RUN yum install git -y

RUN git clone https://github.com/kimcheolgi/Lambda_Docker.git

RUN pip install -r Lambda_Docker/requirements.txt

RUN cp Lambda_Docker/lambda_function.py /var/task/

CMD ["lambda_function.handler"]
  • lambda_function.py 작성
    client 파라미터를 받아 Hello, client를 반환하는 예제 코드로 handler를 작성합니다.
import json

def handler(event, context):
    body = event["body-json"]
    client = body["client"]
    result = f"Hello, {client}"

    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }

Docker Image 생성 및 업로드

  • Docker Image 빌드
docker build -t ironkey-docker-with-docker .
  • AWS Configure 설정
    AWS Application에 접근하기 위해 AWS Configure를 설정합니다.
aws configure

자신의 Access Key와 Secret Access Key를 입력

AWS Access Key ID [None]:
AWS Secret Access Key [None]: 
Default region name [None]:
Default output format [None]:
  • ECR(Elastic Container Registry) 환경 설정
    ECR에 Docker Image를 업로드 할 수 있도록 환경을 설정합니다.
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
echo "export ACCOUNT_ID=${ACCOUNT_ID}" | tee -a ~/.bash_profile

AWS Console에서 레포지토리 생성

생성된 리포지토리의 URI 저장

  • Docker Image Tagging
    다시 터미널로 돌아와 빌드한 Image에 리포지토리 URI를 태깅해줍니다.
docker tag "이미지명" $ACCOUNT_ID.dkr.ecr."리전명".amazonaws.com/"리포지토리 이름"
  • ECR에 Image Push
    Docker client를 인증하여 사용하도록 로그인하고 Image를 Push합니다.
aws ecr get-login-password --region "리전명" | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr."리전명".amazonaws.com
docker push $ACCOUNT_ID.dkr.ecr."리전명".amazonaws.com/"리포지토리 이름"

Lambda 함수 생성

  • AWS Console에서 함수 생성
    컨테이너 이미지를 선택 후 Push한 이미지를 선택하여 함수를 생성합니다.

Lambda 함수 테스트

  • 테스트 이벤트 생성
    테스트 이벤트를 적절하게 작성한 뒤 변경 사항 저장을 눌러 저장합니다.

  • 테스트 이벤트 실행
    테스트 버튼을 눌러 테스트 이벤트를 실행합니다.

작성한 코드에 맞게 "Hello, LAMBDA"가 출력되는 것을 확인할 수 있습니다.

정리

Docker Image를 이용해 AWS Lambda 함수를 구축하는 내용을 다뤄봤습니다. 까다로울 수 있는 딥러닝 모델 서빙 API도 해당 포스팅을 참고하면 쉽게 구축할 수 있습니다. 기회가 된다면 딥러닝 모델을 서빙하는 예제도 다뤄보겠습니다. 해당 포스팅이 도움이 되었으면 좋겠네요. 감사합니다.

+주의사항
Image가 커질 경우 Lambda 함수 최초 실행시 실행시간이 오래걸릴 수 있습니다. 또 지속적으로 lambda를 사용하지 않는 경우 최초 실행처럼 실행시간이 오래걸리는 경우가 발생할 수 있습니다. Lambda가 최초 실행되면 일정기간 메모리에 Image를 올려놓는 것 같은데 일정기간이 지나면 지워져 다시 빌드하는 시간이 소요되는 것으로 추측됩니다. 정확한 원인을 찾으면 추가하겠습니다.

profile
Deepveloper, deeplol.gg, fleaman.shop

2개의 댓글

comment-user-thumbnail
2022년 11월 2일

멋지네요! 잘 돌아가네요! 감사합니다!

1개의 답글