서버리스란?
- 서버리스(Serverless)는 개발자가 서버를 관리할 필요 없이 코드를 배포할 수 있는 개념
- 서버가 없는 것이 아니라, 서버를 관리하거나 프로비저닝할 필요가 없는 것을 의미
- FaaS(Function as a Service): 서버리스의 초기 형태는 FaaS로, 함수만을 배포하고 실행하는 방식
- AWS Lambda가 서버리스의 선구자로 등장했으며, 이제는 데이터베이스, 메시징, 스토리지 등도 서버리스로 관리할 수 있다.
AWS에서의 서버리스 아키텍처 예시
- 정적 콘텐츠 제공: 사용자는 웹사이트에서 정적 콘텐츠를 S3 버킷에서 전달받는다.
- 사용자 인증: 로그인은 Cognito를 통해 이루어지며, 이 서비스는 사용자 신원 정보를 관리한다.
- API 요청 처리: 사용자는 API Gateway를 통해 REST API 요청을 수행하고, 이는 Lambda 함수를 호출하여 데이터를 처리한다.
- 데이터 저장 및 검색: Lambda 함수는 데이터베이스인 DynamoDB에 데이터를 저장하거나 검색한다.
AWS의 서버리스 서비스들
- AWS Lambda: 이벤트에 따라 코드를 실행하는 서버리스 컴퓨팅 서비스
- DynamoDB: 서버 관리가 필요 없는 NoSQL 데이터베이스
- Amazon S3: 정적 파일을 저장하고 제공하는 서버리스 스토리지 서비스
- API Gateway: API 요청을 처리하는 서버리스 서비스
- Cognito: 사용자 인증 및 권한 관리를 제공하는 서버리스 서비스
- SNS & SQS: 메시지 전송 및 큐 관리 서비스
- Kinesis Data Firehose: 데이터 스트리밍 서비스
- Aurora Serverless: 서버리스 관계형 데이터베이스 서비스
- Step Functions: 서버리스 워크플로우 관리 서비스
- Fargate: 서버를 프로비저닝하지 않고 도커 컨테이너를 실행하는 서버리스 컴퓨팅 서비스
AWS Lambda와 Amazon EC2 비교
- Amazon EC2
- 클라우드에서 가상 서버를 제공
- RAM과 CPU에 의해 리소스가 제한되며, 계속 실행됨
- 스케일링 시 서버 추가 및 제거 필요 (자동화 X)
- AWS Lambda
- 서버 관리 없이 함수 단위로 실행
- 짧은 실행 시간 (최대 15분)
- 온디맨드로 실행 (필요할 때만 실행)
- 자동 스케일링이 지원됨 (동시 처리를 자동으로 처리)
AWS Lambda의 장점
- 간단한 가격 책정
- 요청 수와 컴퓨팅 시간에 따라 요금이 부과됨
- 프리 티어: 1백만 개의 요청과 400,000GB의 컴퓨팅 시간을 무료로 제공
- AWS 서비스와의 통합성이 뛰어나며, 다양한 프로그래밍 언어와 통합 가능
- CloudWatch를 통해 손쉽게 모니터링 가능
- 함수당 최대 10GB의 RAM을 제공
- RAM을 늘리면 CPU와 네트워크 성능도 함께 증가
AWS Lambda 지원 언어
- 지원 언어
- Node.js (JavaScript)
- Python
- Java
- C# (.NET Core), Powershell
- Ruby
- 커스텀 런타임 API (Rust, Golang 등)
- 람다 컨테이너 이미지를 사용할 경우 람다 런타임 API를 구현해야 하며, ECS나 Fargate에서는 임의의 도커 이미지를 실행할 수 있다.
AWS Lambda 통합
- 주요 통합 서비스
- API Gateway: REST API 생성을 통해 Lambda 호출
- Kinesis: 데이터를 변환할 때 Lambda를 이용
- DynamoDB: 트리거 설정 시 Lambda 작동
- S3: 파일 업로드 시 Lambda가 작동
- CloudFront: Lambda@edge를 통해 통합
- CloudWatch Events, SNS, SQS, Cognito와도 통합 가능
서버리스 썸네일 생성 예시
- S3 버킷에 새 이미지가 업로드되면, Lambda 함수가 트리거된다.
- Lambda 함수는 썸네일을 생성한 후 다시 S3 버킷에 저장하고, 그 이미지의 메타 데이터를 DynamoDB에 기록한다.
서버리스 CRON 작업 예시
CRON 작업을 서버리스 환경에서 설정하는 방법
AWS Lambda 가격 책정 예시
Lambdam는 사용한 만큼만 지불하는 구조 (매우 저렴한 편)
- 호출당 요금
- 첫 1백만 개의 요청은 무료, 이후에는 백만 개당 20센트 과금
- 시간당 요금
- 컴퓨팅 시간은 1ms 단위로 청구되며, 월 400,000GB-초의 컴퓨팅 시간을 무료로 제공
- RAM 크기에 따라 실행 시간 계산 방식이 달라짐
Lambda – Synchronous Invocations (동기식 호출)
동기식 호출의 핵심 개념 : 호출이 이루어지면 결과를 바로 반환받는다 !!
- 동기식 호출은 아래 서비스에서 이루어짐
- CLI
- SDK
- API Gateway
- Application Load Balancer
- 요청 후 바로 결과가 반환된다.
- 이를 통해 클라이언트는 즉시 응답을 받지만, 오류 처리는 클라이언트 측에서 직접 해야 한다.
- 예를 들어, 실패 시 재시도(retry), 지수 백오프(exponential backoff) 전략을 사용할 수 있다.
SDK 또는 CLI에서 invoke를 통해 Lambda 함수를 호출하고, 함수가 실행된 후 바로 응답이 반환된다.
클라이언트가 API Gateway를 통해 Lambda 함수를 호출하는 예시API Gateway가 Lambda 함수에게 요청을 프록시하고, 응답이 API Gateway를 거쳐 클라이언트에게 반환된다. (API Gateway가 중간에서 요청과 응답을 전달하는 역할을 수행)
Lambda – Synchronous Invocations – Services (동기식 호출을 사용하는 서비스들)
- 사용자 호출(User Invoked)
- Elastic Load Balancing (Application Load Balancer): 사용자가 로드 밸런서를 통해 Lambda를 동기식으로 호출.
- API Gateway: 사용자 요청을 받아 Lambda 함수를 호출하는 게이트웨이 역할을
- Amazon CloudFront (Lambda@Edge): 콘텐츠 배포를 위한 엣지 컴퓨팅 서비스로, Lambda를 호출해 특정 작업을 처리
- Amazon S3 Batch: 대규모 S3 작업을 처리할 때 Lambda를 호출
- 서비스 호출(Service Invoked)
- Amazon Cognito: 사용자 인증 및 권한 관리를 위한 서비스로 Lambda 함수를 호출한다.
- AWS Step Functions: 워크플로우 관리 서비스로, 여러 Lambda 함수를 동기적으로 호출해 복잡한 작업을 처리한다.
- 기타 서비스
- Amazon Lex: 자연어 처리(NLP)를 위한 Lambda 호출
- Amazon Alexa: 음성 서비스로 Lambda 호출
- Amazon Kinesis Data Firehose: 실시간 데이터 스트리밍 서비스로 Lambda 호출
특히 API Gateway, Application Load Balancer, CloudFront 등은 자주 사용되는 동기식 호출 방법
ALB와 Lambda 통합
Lambda 함수를 ALB와 통합하여 HTTP/HTTPS 엔드포인트에서 사용할 수 있는 방법
- HTTP/HTTPS 엔드포인트로 Lambda 함수를 노출하려면 ALB 또는 API Gateway를 사용할 수 있다.
- ALB는 Lambda 함수가 Target Group에 등록되어 있을 때만 해당 함수를 호출할 수 있다.
- 클라이언트가 HTTP/HTTPS 요청을 보내면, ALB가 해당 요청을 Lambda 함수에 동기식으로 전달하고, 응답을 다시 클라이언트에 전달한다.
<ALB 흐름>
- 클라이언트는 HTTP/HTTPS 요청을 ALB에 보낸다.
- ALB는 대상 그룹에 등록된 Lambda 함수를 동기식으로 호출한다.
- Lambda 함수는 응답을 ALB로 보내고, ALB가 다시 클라이언트에 응답을 반환한다.
ALB to Lambda: HTTP to JSON
ALB가 클라이언트의 HTTP 요청을 Lambda 함수에 전달할 때, JSON 문서로 변환하는 방식
- HTTP 요청은 JSON 형식으로 변환되어 Lambda 함수에 전달된다.
- Lambda 함수로 전달되는 정보
- ELB 정보: 어떤 ELB에서 호출이 발생했는지 나타냄
- HTTP 메서드 및 경로: GET 요청 및 요청 경로 정보
- 쿼리 문자열 매개변수: 쿼리 스트링에 포함된 매개변수는 Key/Value 쌍으로 변환
- 헤더: 요청의 헤더는 역시 Key/Value 쌍으로 포함됨
- 바디: POST 또는 PUT 요청에서 바디의 내용은 isBase64Encoded 값으로 처리됨
<HTTP에서 JSON으로 변환>
- 클라이언트가 HTTP 요청을 보내면, ALB는 이를 JSON 형식으로 변환하여 Lambda 함수에 전달한다.
Lambda to ALB Conversions: JSON to HTTP
- Lambda 함수의 응답은 JSON 형식으로 이루어지며, ALB는 이를 HTTP 형식으로 변환하여 클라이언트에게 전달한다.
- Lambda 함수의 응답에 포함되는 정보
- 상태 코드 및 설명: HTTP 응답 코드(예: 200 OK)
- 헤더: 응답의 헤더는 Key/Value 쌍으로 포함됨
- 바디: 응답 본문과 isBase64Encoded 여부 플래그 포함
<JSON에서 HTTP로 변환>
ALB는 이를 HTTP 응답으로 변환하여 클라이언트에게 전달한다.
ALB Multi-Header Values
- ALB는 다중 헤더 값을 지원한다.
- 다중 헤더 값 : 하나의 헤더나 쿼리 문자열이 여러 값을 가질 수 있는 경우를 의미
- 다중 값이 있는 HTTP 헤더나 쿼리 문자열 매개변수는 Lambda 함수에서 배열로 변환된다.
- 클라이언트가 name=foo와 name=bar처럼 동일한 이름의 여러 값을 가진 쿼리 스트링을 보내면, ALB는 이를 JSON 배열로 변환하여 Lambda 함수로 전달한다.
- 이때 queryStringParameters는 배열 형태로 ["foo", "bar"]가 된다.
Lambda – Asynchronous Invocations (비동기식 호출)
- S3, SNS, CloudWatch Events와 같은 서비스에서 이벤트 대기열에 이벤트가 저장된다.
- Lambda 함수는 비동기식 호출 시 3번의 재시도를 자동으로 수행
- 첫 번째 시도는 바로 수행
- 두 번째 시도는 1분 후에, 세 번째 시도는 2분 후에 실행됨
- 멱등성(Idempotency): Lambda 함수는 동일한 이벤트가 여러 번 재시도될 수 있으므로, 결과가 같도록 설계되어야 한다.
- DLQ(Dead-letter Queue): 재시도가 모두 실패했을 경우, Lambda 함수는 DLQ(SNS 또는 SQS)로 실패한 이벤트를 전달할 수 있다.
- 비동기식 호출은 결과를 기다리지 않고 처리할 수 있기 때문에, 병렬 처리가 필요한 경우 속도를 높일 수 있다.
<S3 이벤트 흐름>
- S3 버킷에서 새 파일이 업로드되면, 이벤트가 Lambda 서비스의 이벤트 대기열로 전달된다.
- Lambda 함수는 대기열을 읽고 이벤트를 처리하며, 문제가 생기면 재시도를 수행한다.
- 실패한 이벤트는 DLQ(SQS 또는 SNS)로 전달되어, 나중에 다시 처리할 수 있다.
Lambda – Asynchronous Invocations – Services (비동기식 호출을 사용하는 서비스들)
- 주요 서비스
- Amazon S3: S3 버킷에서 이벤트가 발생할 때 Lambda 함수를 호출한다.
- SNS: 알림을 받고 Lambda 함수를 호출한다.
- CloudWatch Events/EventBridge: AWS 인프라의 이벤트에 대응하여 Lambda 함수를 호출한다.
- 기타 서비스
- AWS CodeCommit: 새 브랜치, 태그, 푸시 이벤트가 있을 때 Lambda 함수를 호출한다.
- AWS CodePipeline: 파이프라인 중간에 Lambda 함수를 호출하여 특정 작업을 수행한다.
- CloudWatch Logs: 로그 처리에 Lambda 함수를 사용한다.
- SES (Simple Email Service): 이메일 전송 시 Lambda 함수를 트리거한다.
- CloudFormation, Config, IoT, IoT Events도 Lambda와 연동된다.
비동기식 호출은 결과를 기다리지 않고 병렬로 작업을 처리해야 할 때 매우 유용하며, 자동 재시도 및 DLQ 설정을 통해 신뢰성을 높일 수 있습니다.
CloudWatch Events 및 EventBridge와 Lambda 통합
CRON 또는 Rate EventBridge 규칙
- 일정 주기마다 Lambda 함수를 트리거할 수 있다.
- 정기적인 작업을 자동화할 수 있다.
CodePipeline EventBridge 규칙
- CodePipeline의 상태 변화를 감지해 Lambda 함수를 트리거할 수 있다.
- CodePipeline의 상태 변화에 따라 자동화된 작업을 수행할 때 유용 !!
CRON/Rate 규칙은 특정 시간 간격으로 Lambda 함수를 자동 실행
CodePipeline 규칙은 파이프라인의 상태 변화에 따라 Lambda 함수를 호출
이 두 가지 방법은 Lambda와 AWS의 이벤트 기반 아키텍처를 통합하여 작업을 자동화할 때 유용
Lambda – Event Source Mapping
이벤트 소스 매핑
- Lambda 함수가 Kinesis, SQS, DynamoDB 스트림 등의 소스에서 이벤트를 폴링(polling)하여 처리하는 방식
- Kinesis Data Streams, SQS, DynamoDB Streams와 Lambda 함수가 통합될 때 이벤트 소스 매핑이 생성된다.
- 이벤트는 Lambda 함수가 폴링을 통해 가져오며, 동기식으로 호출된다.
- 이벤트 소스 매핑은 배치로 데이터를 받아오고, 해당 배치를 Lambda 함수가 처리한다.
<Kinesis 흐름>
Kinesis에서 데이터를 폴링하고, 데이터 배치를 이벤트 소스 매핑이 가져온 후 Lambda 함수가 이를 동기적으로 호출하여 처리한다.
Streams & Lambda (Kinesis & DynamoDB)
- 각 스트림 샤드에 대해 반복자(iterator)가 생성되어 아이템이 순차적으로 처리된다.
- 처리된 아이템은 스트림에서 제거되지 않으므로 다른 소비자도 같은 아이템을 읽을 수 있다.
- 트래픽이 적을 때는 배치 윈도우(batch window)를 사용하여 처리 전 레코드를 축적한다.
- 샤드당 최대 10개의 배치를 병렬로 처리할 수 있으며, 각 파티션 키에 대한 순서 처리가 보장된다.
<스트림 처리 흐름>
하나의 샤드가 여러 배치로 나뉘어져 병렬로 처리될 수 있으며, 각 파티션 키는 순서대로 처리
Streams & Lambda – Error Handling
- 기본적으로 Lambda 함수가 오류를 반환하면, 해당 배치 전체가 재처리된다.
- 순차 처리를 보장하기 위해, 오류가 발생한 샤드의 처리가 중단되고 오류가 해결될 때까지 대기한다.
- 이벤트 소스 매핑을 통해 가능한 옵션
- 오래된 이벤트 폐기
- 재시도 횟수 제한
- 오류 발생 시 배치 분할
- 폐기된 이벤트는 별도의 목적지(destination)로 전달될 수 있음
Lambda – Event Source Mapping (SQS & SQS FIFO)
- Lambda는 SQS 대기열을 Long Polling 방식으로 폴링한다.
- 배치 크기(1-10 메시지)를 설정할 수 있다.
- 대기열의 가시성 시간 초과를 Lambda 함수의 시간 초과보다 6배로 설정하는 것을 권장
- DLQ(Dead-letter Queue)는 SQS 대기열에서 설정해야 하며, 이는 비동기 호출에서만 적용된다.
<SQS 흐름>
- SQS 대기열에서 이벤트를 폴링하고, 배치로 Lambda 함수가 호출된다.
- DLQ는 SQS 대기열 측에서 설정된다.
Queues & Lambda
- FIFO 대기열에서는 메시지 그룹 단위로 순차 처리가 지원된다.
- 표준 대기열에서는 순차 처리가 보장되지 않으며, Lambda는 대기열의 모든 메시지를 빠르게 처리한다.
- 오류 발생 시 배치는 다른 그룹에서 개별적으로 재처리될 수 있다.
- Lambda는 성공적으로 처리된 아이템을 대기열에서 삭제한다.
- 대기열을 구성하여 처리되지 않은 메시지를 Dead-letter Queue(DLQ)로 보낼 수 있다.
- 표준 대기열에서는 순차 처리가 불가능하지만, Lambda의 빠른 스케일링으로 다량의 메시지를 처리할 수 있다.
Lambda Event Mapper Scaling
- Kinesis Data Streams & DynamoDB Streams
- 각 스트림 샤드당 하나의 Lambda 호출이 이루어지며, 병렬 처리를 사용하면 샤드당 최대 10개의 배치를 동시에 처리할 수 있다
- SQS 표준
- Lambda는 분당 최대 60개의 인스턴스를 추가하여 스케일 up
- 동시에 최대 1,000개의 배치를 처리할 수 있다.
- SQS FIFO
- GroupID가 같은 메시지는 반드시 순서대로 처리된다.
- Lambda 함수는 활성 메시지 그룹의 수만큼 스케일 up
Lambda는 SQS 표준 대기열에서 매우 빠르게 확장되며, FIFO 대기열에서는 순서 처리가 보장됨.
Lambda – Event and Context Objects
- Event Object
- 이벤트 객체는 JSON 형식으로 되어 있으며, 람다 함수가 처리해야 하는 데이터를 포함한다.
- 이벤트 객체를 통해 이벤트 소스와 리전 정보를 출력할 수 있다.
- Lambda 런타임은 이 이벤트를 파이썬의 경우 dict 객체로 변환하여 함수에 전달한다.
- Context Object
- 컨텍스트 객체는 함수 실행과 관련된 메타데이터를 제공한다.
- 예: AWS 요청 ID, 함수 이름, 메모리 한도, 로그 그룹 및 스트림 이름 등이 포함된다.
- 람다 런타임은 이 컨텍스트 객체를 함수에 자동으로 전달하여, 함수가 실행 중인 환경에 대한 정보를 제공받을 수 있다.
Lambda – Access Event & Context Objects using Python
- 핸들러 함수에서 event와 context를 파라미터로 받는다.
- event는 JSON 데이터를 담고 있으며, event.source, event.region과 같은 정보가 포함된다.
- context는 함수 실행 환경에 대한 정보를 제공하며, context.aws_request_id, context.function_name 등을 사용하여 출력할 수 있다.
Lambda – Destinations
- 비동기식 호출의 성공 또는 실패에 대한 결과를 목적지로 전송할 수 있다.
- 목적지는 Amazon SQS, Amazon SNS, Lambda, EventBridge와 같은 서비스가 될 수 있다.
- 성공한 경우에는 성공 목적지로, 실패한 경우에는 실패 목적지로 이벤트가 전송된다.
- DLQ(Dead-letter Queue) 대신 목적지 기능 사용이 권장!!!!
- DLQ는 실패한 이벤트만 SQS나 SNS로 보낼 수 있지만, 목적지는 성공 및 실패한 이벤트 모두를 처리할 수 있다.
- 따라서 목적지는 DLQ보다 유연하며 다양한 사용 사례에 맞게 확장됨.
- 이벤트 소스 매핑에서도 폐기된 이벤트 배치를 처리하는 목적지를 설정할 수 있다.
- 이 경우, 처리되지 못한 이벤트를 SQS나 SNS로 전송할 수 있다.
- 비동기식 호출
- Lambda 함수가 호출된 후, 성공 또는 실패한 이벤트가 각각 성공 목적지나 실패 목적지로 전달된다.
- 이벤트 소스 매핑
- Kinesis 스트림이나 SQS에서 실패한 이벤트 배치는 실패한 이벤트 목적지로 전송된다.
Lambda Execution Role (IAM Role)
- Lambda 함수는 IAM 역할을 통해 다른 AWS 서비스나 리소스에 액세스할 수 있는 권한을 받는다.
- 관리형 정책 예시
- AWSLambdaBasicExecutionRole: CloudWatch에 로그를 업로드.
- AWSLambdaKinesisExecutionRole: Kinesis에서 읽기.
- AWSLambdaDynamoDBExecutionRole: DynamoDB 스트림에서 읽기.
- AWSLambdaSQSQueueExecutionRole: SQS에서 읽기.
- AWSLambdaVPCAccessExecutionRole: VPC 내에서 Lambda 함수 배포.
- AWSXRayDaemonWriteAccess: X-Ray에 추적 데이터 업로드.
- 이벤트 소스 매핑을 통해 Lambda 함수가 데이터를 읽을 때, Lambda는 해당 작업을 수행할 권한이 있어야 하므로 IAM 실행 역할이 필요하다.
- 베스트 프랙티스: Lambda 함수마다 하나의 Lambda 실행 역할을 생성하는 것이 가장 좋다. 이는 권한 관리와 보안을 더욱 명확하게 유지하는 데 도움을 준다.
Lambda Resource-Based Policies
리소스 기반 정책을 사용하면 다른 계정이나 AWS 서비스가 Lambda 리소스에 액세스할 수 있도록 권한을 부여할 수 있다.
- 리소스 기반 정책은 S3 버킷 정책과 유사한 방식으로 작동하며, 다른 계정이나 AWS 서비스가 Lambda 리소스에 접근할 수 있는 권한을 부여한다.
- IAM 주체가 Lambda 함수에 접근할 수 있는 두 가지 방법
- IAM 정책이 주체에게 Lambda 접근 권한을 부여하는 경우.
- 리소스 기반 정책이 주체에게 접근을 허용하는 경우.
- Amazon S3 같은 AWS 서비스가 Lambda 함수를 호출할 때, 리소스 기반 정책이 해당 서비스에 대한 접근을 허용한다.
- IAM 정책은 사용자의 권한을 부여하고, 리소스 기반 정책은 서비스 간 액세스를 부여하는 데 사용됩니다. 두 가지 정책이 상호 보완적으로 사용될 수 있다.
Lambda Environment Variables
환경 변수는 코드 수정 없이 함수의 동작을 변경할 수 있는 유연한 방법을 제공한다.
- 환경 변수는 키/값 쌍으로, 문자열 형태로 저장된다.
- Lambda 함수의 동작을 변경할 때 코드를 수정할 필요 없이 환경 변수를 통해 동작을 조정할 수 있다.
- 환경 변수는 코드 내에서 사용할 수 있으며, Lambda 서비스 자체도 시스템 환경 변수를 추가로 제공한다.
- 환경 변수는 비밀 값을 저장하는 데 유용하며, 이를 KS(Key Management Service)를 사용해 암호화할 수 있다.
- 비밀 값은 Lambda 서비스 키나 사용자 지정 CMK(Customer Master Key)로 암호화될 수 있다.
- Lambda 함수에서 중요한 설정이나 비밀 정보를 관리할 때, 환경 변수를 사용하면 쉽게 관리할 수 있다.
- 특히, 비밀 정보를 다루는 경우에는 KMS로 암호화하여 보안성을 유지할 수 있다.
'AWS' 카테고리의 다른 글
AWS Section 22-1. AWS 서버리스 : DynamoDB (0) | 2024.11.04 |
---|---|
AWS Section 21-2. AWS 서버리스: Lambda (2) | 2024.11.04 |
AWS Section 19-2. AWS 통합 및 메시징 : SQS, SNS 및 Kinesis (1) | 2024.11.04 |
AWS Section 19-1. AWS 통합 및 메시징 : SQS, SNS 및 Kinesis (0) | 2024.11.04 |
AWS Section 18. CloudFormation (2) | 2024.11.04 |