2023. 4. 21. 13:04ㆍBACKEND/AWS
AWS Serverless 를 이해하고 Demo Thumbnail 자동 생성 기능을 위해 Lambda와 S3를 구성하는 것이 본 포스팅의 목표입니다.
Serverless
서버가 없다는 것은 아니고 관리할 필요가 없다는 뜻입니다.
서버가 보이지 않거나 서버를 프로비저닝 하지 않습니다.
코드나 함수를 배치하면 됩니다.
원래 서버리스는 FaaS, 즉 Function as a Service를 뜻했지만, 지금의 서버리스는 더 많은 것을 의미합니다
Serverless가 처음 개발된 건 AWS Lambda에서였는데, 현재는 원격 관리되는 데이터베이스, 메시징, 스토리지 등 서버를 프로비저닝 하지 않는 모든 것들을 포함합니다.
AWS의 Serverless 서비스에는 Lambda, DynamoDB Cognito, API Gateway, Amazon S3, SNS와 SQS, Kinesis Data Firehose, Step Function, ECS의 서버리스 기능인 Fargate 등이 있습니다.
Lambda
AWS Lambda는 가상의 함수로, 관리할 서버 없이 코드 프로비저닝으로 함수 실행합니다.
인프라를 프로비저닝하거나 관리하지 않고 코드를 실행합니다.
zip 파일 또는 컨테이너 이미지로 코드를 작성하고 업로드하면 됩니다.
온디맨드로 실행되며, 정의된 Lambda를 사용하지 않으면 람다 함수가 실행되지 않습니다.
더불어, 함수가 실행되는 동안만 비용이 청구됩니다.
또, Lambda는 최대 15분이라는 실행 제한 시간이 있습니다.
AWS Lambda는 스케일링이 자동화되어 있습니다.
만약 람다 함수를 동시에 많이 필요로 하는 경우, AWS가 자동으로 람다 함수를 늘려줍니다.
Benefits
Lambda의 장점은 다양한 형태의 서비스로 확장 가능하며, 가격이 굉장히 저렴하다는 것입니다.
# 서비스 확장
다양한 AWS 서비스와 통합 가능하고, 함수의 코드를 작성할 때 다양한 프로그래밍 언어를 사용할 수 있습니다.
가령 Node.js (JavaScript), Python, Java, C# (.NET Core), Golang, C#, Powershell, Ruby 등을 지원합니다.
Community 에서 지원된 Custom Runtime API (사용자 지정 런타임 API) 가 있는데요.
대표적인 예로 Rust를 사용할 수 있는 이유입니다.
Lambda Container Image (Lambda 컨테이너 이미지)로 컨테이너를 생성할 수 있는데,
이때 컨테이너 이미지 자체가 Lambda의 런타임 API를 구현해야 합니다.
# 저렴한 가격
Lambda의 요금은 호출 횟수, 컴퓨팅 시간, Lambda가 실행된 시간에 따라 과금됩니다.
예시로 Lambda 가격 책정 호출 당 요금을 살펴보겠습니다.
먼저 첫 1,000,000 번의 요청은 무료이며 이후 백만 건의 요청 마다 $0.20 과금 ($0.0000002 per request) 됩니다.
vs. Amazon EC2
간단히 Amazon EC2와 다른점을 비교해보면, 아래와 같습니다.
먼저, EC2는 클라우드의 가상 서버라서 프로비저닝이 필요합니다.
따라서 프로비저닝된 메모리와 CPU 크기가 제한됩니다.
또, EC2는 지속적으로 실행되어야 하기 때문에 관리가 필요합니다.
최적화를 하려면 스케일링을 통해 효율적으로 시작하고 중단하는 것을 관리해야 합니다.
가령, 오토 스케일링 그룹으로 관리하는 예시를 들 수 있습니다.
Lambda Hands-on
Create Thumbnail Images
람다 함수의 대표적인 예시인 썸네일 이미지를 생성하는 데모를 제작합니다.
순서는 크게 아래와 같이 진행됩니다.
1. Create S3 buckets
3. Create the deployment package
5. Test the Lambda function
해당 내용은 AWS Tutorial 을 참고하여 제작했지만, AWS 콘솔에서 설정할 수 있게끔 몇 부분을 수정하여 적용했습니다.
1. Create S3 buckets
먼저, S3 버킷 두 개를 생성합니다.
gngsn-demo-bucket 이름의 버킷을 생성했습니다.
이번에는 Thumbnail로 변경시켜 저장할 버킷 gngsn-demo-bucket-resized 버킷을 추가 생성합니다.
아래와 같이 두 개의 버킷을 생성했습니다.
2. Create the IAM Role
Lambda가 S3에 접근하기 위한 IAM Role을 생성합니다.
먼저, 적절한 IAM Policy를 생성하고, IAM Role 생성 시에 해당 Policy를 적용하겠습니다.
IAM Policy: DemoLambdaS3Policy
IAM Role: demo-lambda-s3-role
2-1. Create the IAM Policy
Create Policy를 선택해서 JSON 편집을 선택한 후, 그림 아래의 삽입한 코드블럭의 Policy JSON를 입력합니다.
JSON 입력했다면 Tag를 선택적으로 선택한 후, 이름 DemoLambdaS3Policy을 지정해 생성합니다.
이 때, 아래 코드의 sourcebucket을 반드시 1. Create S3 Buckets 에서 생성한 두 버킷을 입력해야 합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:CreateLogStream"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::sourcebucket/*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::sourcebucket-resized/*"
}
]
}
2-2. Create the IAM Role
생성한 Policy를 갖는 IAM Role을 생성하기 위해 Create Role을 클릭합니다.
Trusted entity type - AWS Service
Use Case - Lambda
선택 후 페이지가 넘어가면 Add permissions에서 2-1. Create the IAM Policy에서 생성한 DemoLambdaS3Policy를 선택합니다.
마지막으로 이름 'demo-lambda-s3-role' 을 지정한 후 Create Role을 클릭합니다.
성공적으로 Lambda Function이 가질 IAM Role을 생성했습니다.
3. Create the deployment package
이번에는 Lambda Function 이 실행할 로직을 구현해야 하는데, 이를 위해서는 외부 패키지가 필요합니다.
때문에, Lambda function에 적용할 node 실행 파일을 생성 후 zip으로 압축시키겠습니다.
해당 부분은 AWS 공식 문서의 create-function-package 를 참고하여 생성한 프로젝트 입니다.
결론적으로, 아래와 같은 구조를 가진 node 프로젝트가 생성되었고, index.js에서는 이미지를 resize하는 로직을 포함합니다.
lambda-s3
|- index.js
└- node_modules/
└- sharp/
+ ISSUE
위의 링크를 따라한 결과, mac에서 실행되는 sharp 패키지를 가져오기 때문에 Lambda에서 오류가 발생했습니다.
linux에서 실행할 sharp 패키지를 불러오도록 아래와 같이 수정했습니다.
$ npm install --arch=x64 --platform=linux --target=16x sharp
이후, zip 명령어로 해당 파일을 압축합니다.
functoin.zip은 lambda-s3 내의 모든 파일을 압축한 파일로, 해당 파일을 Lambda Function에 적용시킬 예정입니다.
lambda-s3
|- function.zip
|- index.js
└- node_modules/
└- sharp/
4. Create the Lambda function
이제 Lambda Function을 생성하겠습니다.
S3ThumbnailFunction 이름으로 생성합니다.
AWS 공식 문서를 따라하느라, latest 버전이 아닌 Node.js 16.x 버전을 사용했습니다.
Execution role을 Use an existing role로 선택해 2-2. Create the IAM Role 에서 생성한 demo-lambda-s3-role를 선택해야 합니다.
4-1. Upload the Zip File
이번에는 3 에서 생성한 zip 파일을 해당 Lambda Function에 업로드하겠습니다.
위와 같이 업로드 할 수 있습니다.
4-2. Create the Trigger
마지막으로, S3에 변화가 생기면 이를 포착할 Trigger를 생성합니다.
Add Trigger를 선택한 다음, Source를 S3로 선택한 후, 생성했던 Bucket 중 소스 버킷, 즉 원본이 업로드될 버킷을 선택해줍니다.
Recursion Invocation을 확인해 보면 재귀에 주의하라는 문구가 있습니다.
함수가 S3 버킷에 개체를 쓰는 경우, 입력 및 출력을 서로 다른 S3 버킷을 사용하고 있는지 확인하라는 내용입니다.
동일한 버킷에 쓸 경우, 반복 호출이 발생할 위험이 증가하여 람다 사용량이 증가하고 비용이 증가할 수 있기 때문입니다.
입력과 출력 모두에 동일한 S3 버킷을 사용하지 않는 것이 좋으며,
이 구성으로 인해 반복 호출, 람다 사용량 증가 및 비용 증가가 발생할 수 있습니다는 점을 확인하고 트리거 생성을 완료합니다.
위의 설정이 끝나면 주목할 만한 내용이 하나 있습니다.
Trigger의 Source로 선택한 버킷 gngsn-demo-bucket 을 확인해보면, Properties > Event notifications 에 아래와 같은 Event notification이 자동으로 생성된 것을 확인할 수 있습니다.
5. Test the Lambda function
모든 설정이 끝났기 때문에 사진을 업로드해서 제대로 동작하는지 확인합니다.
업로드가 된 이후, 시간이 어느정도 지나면 Lambda Function에서 해당 내용에 대한 정보를 확인할 수 있습니다.
오류가 발생해서 로그가 많이 찍혀 있는 것을 확인할 수 있는데요.
성공한 가장 위의 내용을 확인해보면 아래와 같은 로그 결과를 확인할 수 있습니다.
REPORT RequestId: 1cb418b2-3524-409e-b932-d09e34fa4b6e Duration: 2487.57 ms Billed Duration: 2488 ms Memory Size: 128 MB Max Memory Used: 112 MB Init Duration: 547.75 ms
그리고 잘 업데이트된 파일도 확인할 수 있습니다.
이미지가 실제로 94.0 KB → 5.6 KB 로 감소된 것을 확인할 수 있습니다.
실제로 이미지가 축소되었는지 비교해보겠습니다.
그럼 지금까지 Lambda Function Hands-on을 진행해보았습니다.
감사합니다.
'BACKEND > AWS' 카테고리의 다른 글
AWS로 구성하는 Cloud-native Microservice Architectures (2) | 2023.05.06 |
---|---|
AWS VPC, 제대로 이해하기 2 - NAT GW, VPC Peering (0) | 2023.04.20 |
AWS VPC, 제대로 이해하기 1: Hands-On (2) | 2023.04.18 |
AWS VPC, 제대로 이해하기 1 (0) | 2023.04.17 |
AWS S3, 제대로 이해하기 - Replication & Event Notification (0) | 2023.03.26 |
Backend Software Engineer
𝐒𝐮𝐧 · 𝙂𝙮𝙚𝙤𝙣𝙜𝙨𝙪𝙣 𝙋𝙖𝙧𝙠