Lambda는 AWS의 서버리스 서비스 중 핵심이고 알파이자 오메가입니다. 그럼에도 불구하고 컨테이너 이미지 지원이 공식적으로 지원된 건 2020년 겨울 무렵부터 입니다. 설명서도 자세하게 나와있지만 실전에서 사용하는 데에는 제약이 많았습니다. 본격적으로 들어가기 전에 Lambda와 docker의 관계를 정리할 필요가 있습니다.
1. 임의의 기본 이미지는 Lambda와 호환되지 않는다. Lambda와 호환하려면 Lambda 런타임 API를 구현해야 한다.
- https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/runtimes-api.html 문서를 참조해서 직접 구현해야 하는데 너무 복잡하고 예제가 없는 설명서는 구현 할 의욕조차 사라지게 합니다.
2. 그래서 AWS는 모든 Lambda 런타임(Python, Node.js, Java,. NET, Go, Ruby)에 대해 기본 이미지를 제공한다.
- 하지만 이 기본 이미지는 Amazon linux의 환경이라는 것을 알아야 합니다. 패키지는 RedHat 계열인 yum 밖에 사용을 못하며 apt-get을 사용하기 위한 ubuntu, 용량을 줄이기 위한 alpine 모두 사용할 수 없습니다.
3. 그러니 Ubuntu나 Alpine같은 자체 환경을 만들기 위해서는 Lambda 런타임과 호환이 가능하게 해주는
pip의 awslambdaric를 사용해야 한다.
- https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images-create.html 문서 하단의 대체 기본 이미지에서 이미지 생성 부분을 참고해 dockerfile을 제작해야 합니다.
여기서 진행하는 실습은 AWS에서 제공하는 기본 이미지가 아니라 , 새로운 환경(Alpine, Ubuntu 등)이 필요할 때 세팅하는 방법입니다. 기존 Amazon linux 환경에서 잘 돌아간다면 굳이 이 방법을 사용할 필요가 없습니다.
다음과 같이 dockerfile을 구성합니다.
FROM public.ecr.aws/lambda/python:3.8 as lambda-image
# 사용할 환경 : 우분투
FROM ubuntu:latest
# 작업 디렉토리 설정
RUN mkdir /var/task
WORKDIR /var/task
# labmda 런타임 이미지 복사
COPY lambda.py /var/task/
COPY --from=lambda-image /var/runtime /var/runtime
# python 및 빌드 종속성 설치
RUN apt update && apt install -y libgl1-mesa-glx libglib2.0-0
RUN apt install python3 -y --no-install-recommends
RUN apt install python3-pip -y --no-install-recommends
RUN pip3 install awslambdaric
RUN pip3 install boto3
# 선택 packages 설치
RUN apt install lame -y
RUN pip install requests midi2audio
# Lambda Runtime Interface Emulator를 추가하고 보다 간단한 로컬 실행을 위해 ENTRYPOINT에서 스크립트 사용
COPY ./entry_script.sh /entry_script.sh
ADD aws-lambda-rie /usr/local/bin/aws-lambda-rie
RUN chmod 755 /entry_script.sh
RUN chmod 755 /usr/local/bin/aws-lambda-rie
ENTRYPOINT [ "/entry_script.sh" ]
CMD [ "lambda.handler" ]
공식 docs와는 조금 다른 방법을 사용합니다. AWS에서 제공하는 기본 이미지를 작업 환경에 COPY 하는 방식으로 런타임 환경을 구성합니다. 마지막 lambda rie 부분은 로컬 환경에서의 실행 확인 부분입니다.
아래의 entry.sh 스크립트를 작성하여 ENTRYPOINT로 사용합니다. 파이썬용 lambda rie를 실행합니다. 로컬에서 실행하는 경우 Runtime 클라이언트는 lambda rie에 의해 래핑 됩니다.
#!/bin/sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
exec /usr/local/bin/aws-lambda-rie /usr/bin/python3 -m awslambdaric $1
else
exec /usr/bin/python3 -m awslambdaric $1
fi
다음과 같은 명령으로 테스트 케이스 결과를 확인할 수 있습니다. curl 명령어 부분은 다른 터미널에서 실행시켜야 합니다.
docker build -t hello-world .
docker run -p 9000:8080 hello-world
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
테스트가 성공했다면 ECR에 이미지를 배포하고 lambda를 생성해 사용하면 됩니다.
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com
aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
docker tag hello-world:latest 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/hello-world:latest
docker push 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/hello-world:latest
위의 명령어는 예시로, ECS-ECR 로 들어가면 푸시 명령 보기 에 더 자세한 명령어가 있으니 그걸 참조하면 됩니다.
lambda에 컨테이너 이미지를 올릴 땐 ECR에 등록된 이미지를 사용하게 됩니다. 이 과정은 생략합니다.
자세한 코드는 깃허브에 올려두었으니 참고하시길 바랍니다.
https://github.com/newdeal123/lambda-ubuntu
'🐳AWS' 카테고리의 다른 글
AWS 엔지니어들은 Lambda를 어떻게 구현했을까 (1) : Firecracker 제작기 (7) | 2022.11.10 |
---|---|
Notion API 활용하기 - (3) AWS Lambda와 Notion API 연동하기 (0) | 2022.06.07 |
[AWS] Step Function으로 Lambda 워크플로 자동화하기 (0) | 2021.09.08 |
[AWS] lambda에서 chrome-selenium 크롤링 환경 설정하기 (2) | 2021.08.26 |
[AWS][테라폼] 🐬 테라폼으로 AWS EC2 인스턴스 생성,삭제하기 (0) | 2021.06.19 |