Serverless
Lambda
개요
Serverless란 FaaS(Function as a Service)이다. 서버가 없다는 의미가 아니라 서버를 관리하거나 프로비저닝할 필요가 없다는 의미이다. 코드를 배포하기만 하면 된다.
AWS Lambda는 서버를 관리할 필요가 없는 가상 함수이다.
최대 15분까지의 짧은 실행 시간을 가진 애플리케이션만 실행 가능하다.
스케일링이 자동화되어 있다. 더 많은 Lambda 함수, 발생 횟수, 동시성을 필요로 한다면 AWS가 자동으로 더 많은 Lambda 함수를 제공해준다.
CloudWatch와 통합하여 Lambda 함수를 모니터링할 수 있다.
함수당 더 많은 리소스를 프로비저닝하고 싶다면 함수당 최대 10기가바이트의 RAM을 프로비저닝할 수 있다. 함수의 RAM을 늘리면 CPU와 네트워크의 품질과 성능도 향상된다. 더 빠르게 함수를 실행하고 비용도 절약할 수 있도록 메모리를 오버프로비저닝할 수 있다.
JavaScript를 위한 Node.js, Python, Java, C#, PowerShell, Ruby와 같은 다양한 언어를 실행할 수 있다. 그리고 커뮤니티에서 유지되는 커스텀 런타임 API를 통해 공식 지원되지 않는 언어도 사용할 수 있다.
컨테이너와 통합
Lambda 함수 내부에서 컨테이너를 사용하려면 Lambda 런타임 API라고 불리는 것을 구현해야 한다. 하지만, 컨테이너 이미지를 실행할 때에는 Lambda보다는 EKS나 Fargate에서 실행하는 것이 권장된다.
Lambda 함수 자체를 컨테이너 이미지로 패키징하고 배포할 수도 있다.
다른 서비스와의 통합
API 게이트웨이는 Rest API를 생성하고, 내부적으로 Lambda 함수를 호출할 수 있다.
Kinesis는 Lambda를 사용하여 실시간으로 데이터 변환을 수행할 수 있다.
DynamoDB, S3에서 이벤트가 발생할 때 Lambda 함수를 트리거할 수 있다.
CloudFront과 통합하여 엣지 로케이션에서 Lambda를 사용할 수 있다.
이외에도 다양한 AWS 서비스와 연동될 수 있다.
비용
수요에 따라 실행되어, Lambda를 사용하지 않을 때는 비용이 청구되지 않는다.
일정 주기마다 크론 잡을 수행시키고 싶을 때 EC2 인스턴스를 대여해 실행시키는 것 보다, 매 시간마다 CloudWatch 이벤트 규칙이나 EventBridge 규칙을 트리거시켜 Lambda 함수가 실행되도록 하는 것이 비용 측면에서 효율적이다.
Lambda의 가격은 호출 횟수와 컴퓨팅 시간에 따라 비용이 결정된다.
100만 건의 Lambda 요청과 400,000GB 초의 컴퓨팅 시간에 대해서는 무료이다.
호출 횟수가 100만 건이 넘어가면, 추가 100만 건의 요청당 $0.20가 과금된다.
400,000GB 초의 컴퓨팅 시간이란, Lambda 함수에 1GB의 RAM이 있다면 400,000초 동안 수행됨을 의미한다. 1GB의 1/8인 128MB의 RAM이 있다면 3,200,000초 동안 수행됨을 의미한다.
컴퓨팅 시간이 400,000GB 초가 넘어가면 600,000GB 초당 $1이 과금된다.
제한 사항
제한 사항은 리전마다 적용된다.
실행 한도
실행 시 메모리 할당량은 128MB에서 10GB 사이여야 한다. 메모리는 MB 단위로 지정할 수 있다. 메모리가 증가하면 더 많은 vCPU가 필요하다.
최대 실행 시간은 900초, 즉 15분이다. 타임아웃을 설정해 예상보다 오래 실행되어 비용이 부과되는 것을 막을 수 있다.
환경변수는 최대 4KB 차지할 수 있다.
Lambda 함수를 생성할 때 큰 파일을 사용해야 하면
/tmp
폴더를 사용하면 된다. 크기는 최대 10GB이다.Lambda 함수는 최대 1,000개까지 동시 실행이 가능하며 요청 시 증가할 수 있지만 미리 예약해 두는 것이 좋다.
배포 한도
압축 시 최대 크기는 50MB, 압축하지 않았을 때는 250MB이다. 이 용량을 넘는 파일의 경우 /tmp 공간을 사용해야 한다.
배포 시에도 환경변수의 한도는 4KB이다.
예를 들어 30GB의 RAM과 30분의 실행 시간이 필요하고 3GB의 큰 파일을 있을 때는, Lambda 함수가 적합하지 않다.
SnapStart
Lambda 함수의 성능을 높이기 위한 무료 기능이다.
Java 11 이상에서 실행되는 Lambda 함수들을 추가 비용 없이 성능을 최대 10배 높여준다.
Snap Start가 비활성화되어있으면, Lambda 함수가 호출되었을 때 Java 코드가 먼저 초기화된 후에 호출되고 종료된다. Snap Start가 활성화되어있으면 함수가 미리 초기화된 상태에서 호출된다.
SnapStart를 사용하면 새로운 Lambda 버전을 발행할 때 Lambda가 함수를 초기화한다. 메모리와 초기화된 함수의 디스크 상태의 스냅샷이 생성된 후 캐싱된다. 이를 통해 Lambda 함수가 호출되면 초기화된 상태에서 빠르게 수행된다.
Edge Location
보통은 함수와 애플리케이션을 특정 리전에서 배포하지만 CloudFront를 사용할 때는 엣지 로케이션에 콘텐츠를 배포한다.
엣지 함수
애플리케이션에 도달하기 전 엣지 로케이션에서 로직을 실행할 수 있다. CloudFront 배포에 연동된다.
사용자 근처에서 실행되어 지연 시간을 최소화할 수 있다.
엣지 함수로 CloudFront 함수, Lambda@Edge 타입을 제공한다.
엣지 함수를 사용하면 전역으로 배포되어 서버를 관리할 필요가 없다.
사용한 만큼만 비용을 지불하며, 서버리스이다.
다음과 같은 경우 등에 사용 가능하다.
웹사이트 보안과 프라이버시 용도
엣지에서의 동적 웹 애플리케이션
검색 엔진 최적화(SEO)
오리진 및 데이터 센터 간 지능형 경로
엣지에서의 봇 완화
엣지에서의 실시간 이미지 변환
A/B 테스트
사용자 인증 및 권한 부여
사용자 우선순위 지정
사용자 추적 및 분석
CloudFront 함수
CloudFront에 클라이언트가 요청을 보내는 것을 뷰어 요청이라고 칭한다. CloudFront가 오리진 서버에 요청을 전송하는 것을 오리진 요청이라고 한다. 서버는 CloudFront에 오리진 응답을 보내고, CloudFront가 클라이언트에게 뷰어 응답을 전송한다.
CloudFront 함수는 JavaScript로 작성된 경량 함수로 뷰어 요청과 응답을 수정할 수 있다.
확장성이 높고 지연 시간에 민감한 CDN을 커스터마이즈할 때 사용된다.
시작 시간은 1밀리초 미만이며, 초당 백만 개의 요청을 처리한다.
CloudFront가 뷰어로부터 요청을 받았을 때 요청을 수정할 수 있고, CloudFront가 뷰어에게 응답을 보내기 전에 응답을 수정할 수 있다.
CloudFront의 네이티브 기능으로, 모든 코드가 CloudFront에서 직접 관리된다.
사용 사례
요청 속성을 변환해 캐시 키를 정규화할 수 있다.
요청이나 응답에 HTTP 헤더를 삽입, 수정, 삭제하도록 헤더를 조작하고 URL을 다시 쓰거나 리디렉션할 수 있다.
요청을 허용 또는 거부하기 위해 JWT를 생성하거나 검증하는 요청 인증 및 권한 부여 작업을 수행할 수 있다.
Lambda@Edge
Node.js나 Python으로 작성하며 초당 수천 개의 요청을 처리할 수 있다.
모든 CloudFront 요청 및 응답을 변경할 수 있다. CloudFront는 뷰어 요청/응답만 수정할 수 있는 반면 Loambda@Edge는 뷰어, 오리진 요청/응답 모두 변경 가능하다.
CloudFront가 오리진 요청을 전송하기 전에 수정할 수 있다.
CloudFront가 오리진에서 응답을 받은 후에 오리진 응답을 수정할 수 있다.
CloudFront를 배포하는 us-east-1 리전에만 작성하면, CloudFront에 의해 다른 리전으로 복제된다.
실행에 5~10초가 소요된다.
네트워크 액세스를 통해 외부 서비스에서 데이터를 처리할 수 있어 대규모 데이터 통합을 수행할 수 있다.
파일 시스템이나 HTTP 요청 본문에도 바로 접근할 수 있다.
VPC
일반적으로 Lambda 함수는 VPC 외부에서 실행된다. 하지만 VPC에서 Lambda 함수를 시작할 수도 있다.
VPC ID를 정의해야 하며, Lambda 함수를 시작하려는 서브넷을 지정하고 보안 그룹을 추가해야 한다. 그러면Lambda가 서브넷에 ENI를 생성해 VPC에서 실행되는 Amazon RDS 등의 서비스에 접근할 수 있게 된다.
RDS 프록시
프라이빗 서브넷에 있는 RDS 데이터베이스를 Lambda 함수로 직접 접근하면, Lambda 함수가 스케일링될 때 마다 연결이 새로 생기고 사라지므로 RDS 데이터베이스의 부하가 증가해 타임아웃 등 문제가 발생할 수 있다.
이를 해결하기 위해 프록시를 이용해 RDS 데이터베이스 인스턴스 연결의 수를 줄일 수 있다. Lambda 함수는 RDS 프록시에 연결되고 RDS 프록시가 RDS DB 인스턴스로 연결되므로 아키텍처상의 문제가 해결된다.
데이터베이스 연결의 풀링과 공유를 통해 확장성을 향상시킨다.
장애가 발생할 경우 장애 조치 시간을 66%까지 줄여 가용성을 향상시키고 연결을 보존한다.
RDS 프록시 수준에서 IAM 인증을 강제하여 보안을 높일 수 있고, 자격 증명은 Secrets Manager에 저장된다.
퍼블릭 액세스가 불가능하므로 Lambda 함수를 VPC에서 실행시켜야 한다.
RDS
데이터베이스 인스턴스 안에서 람다 함수를 호출하여 데이터베이스 안에서 일어나는 데이터 이벤트를 처리할 수 있다.
RDS for PostgreSQL과 Aurora MySQL에서 지원된다.
예를 들어 사용자가 이벤트 데이터를 테이블에 삽입하면 RDS가 람다 함수를 호출하도록 설정할 수 있다.
데이터베이스에 접속한 후 설정해야 한다. AWS 콘솔에서 설정하지 않는다.
RDS 데이터베이스 인스턴스로부터 람다 함수로 들어오는 인바운드 트래픽을 반드시 허용해야 한다. 람다가 퍼블릭 인터넷에 있는 경우에도 허용되어야 한다. 람다 호출 시 NAT 게이트웨이 또는 VPC 엔드포인트 등을 사용할 수 있다.
데이터베이스 인스턴스는 람다 함수를 호출할 수 있는 적절한 IAM 정책을 갖고 있어야 한다.
데이터베이스 인스턴스, 데이터베이스 스냅샷, 파라미터 그룹, 보안 그룹, 프록시, 커스텀 엔진 버전에 관한 이벤트를 구독할 수 있다. 하지만 데이터베이스 안의 데이터에 관한 정보는 받지 못한다.
이벤트가 발생하면 전달 시간이 최대 5분이 걸릴 수 있다. (Near real-time)
이벤트를 SNS에 전송하거나 EventBridge에서 가로채도록 할 수 있다.
API Gateway
개요
AWS의 서버리스 서비스로 REST API를 생성할 수 있어, 클라이언트가 퍼블릭 액세스할 수 있다.
API Gateway에 클라이언트가 직접 소통하며 다양한 작업을 할 수 있고, Lambda 함수에 보내는 요청을 프록시 처리할 수 있다.
Lambda 함수와 통합하여 인프라 관리를 하지 않고 완전한 서버리스 환경을 구축할 수 있다.
웹소켓 프로토콜, API 버저닝, 환경 분리 (dev/prod/...) 등을 지원한다.
인증과 인가 기능을 지원한다.
API 키를 생성할 수 있고, API Gateway에 클라이언트 요청이 과도하게 들어올 때 요청을 스로틀링할 수 있다.
Swagger나 Open API 3.0과 같은 공통 표준을 사용하여 빠르게 API를 정의할 수 있다.
API Gateway 수준에서 요청과 응답을 변형하거나 유효성을 검사해 올바른 호출이 실행되게 할 수 있다.
SDK나 API 스펙을 생성할 수 있다.
API 응답을 캐시할 수 있다.
통합
Lambda 함수
Lambda 함수를 지연 호출할 수 있다.
클라이언트가 Lambda 함수를 지연 호출(Invoke)하게 하려면 클라이언트에게 IAM 권한이 있어야 한다. 또한, 클라이언트와 Lambda 함수 사이에 ALB를 배치하면 Lambda 함수가 HTTP 엔드포인트에 노출된다.
Lambda 함수에서 제공하는 REST API로 노출시키는 가장 일반적인 방식이다.
최대 29초를 기다리며, 호출 이후 이 이상의 시간이 지난 경우 타임아웃이 발생한다.
HTTP
온프레미스 혹은 ALB의 백엔드 HTTP 엔드포인트를 노출시킬 수 있다.
rate limit 기능, 캐싱, 사용자 인증, API 키 등의 기능을 추가하는 것이 목적이다. 예를 들어 토큰 버킷 알고리즘을 사용하여 API에 대한 요청을 스로틀링할 수 있다.
AWS 서비스
AWS API를 노출시킬 수 있다.
단계 함수 워크플로우를 시작하거나 직접 SQS에 메시지를 게시할 수 있다.
인증, 퍼블릭 배포, 속도 제한을 추가하는 것이 목적이다.
엔드포인트 유형
엣지 최적화
전 세계 누구나 API Gateway에 접근할 수 있도록 모든 요청이 CloudFront 엣지 로케이션을 통해 라우팅된다.
API Gateway는 생성된 리전 한 곳에 위치하지만, 모든 CloudFront 엣지 로케이션에서 접근 가능하다.
리전 배포
모든 사용자는 API Gateway를 생성한 리전과 같은 리전에 있어야 한다.
자체적으로 CloudFront로 배포를 생성할 수 있다. 엣지 최적화 배포와 동일한 결과를 내며, 캐싱 전략과 CloudFront 설정에 더 많은 권한을 가질 수 있다.
프라이빗 배포
프라이빗 API Gateway는 VPC 내에서만 ENI 등의 VPC 엔드포인트를 통해 접근 가능하다.
리소스 정책을 통해 API Gateway에 대한 접근 정책을 정의한다.
보안
IAM 역할
API Gateway의 API에 액세스할 때 IAM 역할을 사용하도록 한다.
EC2 인스턴스 등에서 접근할 때 사용할 수 있다.
Amazon Cognito
모바일 애플리케이션이나 웹 애플리케이션의 외부 사용자에 대한 보안 조치를 수행할 수 있다.
Custom Authorizer
커스텀 보안 로직을 작성할 수 있다.
HTTPS
사용자 지정 도메인 이름을 AWS Certificate Manager와 통합할 수 있다.
엣지 최적화 엔드포인트를 사용할 경우 인증서는 us-east-1에 있어야 한다.
리전 엔드포인트를 사용할 경우 인증서는 API Gateway 단계와 동일한 리전에 있어야 한다.
Route 53에 CNAME이나 A-별칭 레코드를 설정해 도메인 및 API Gateway를 가리키도록 해야 한다.
Step Functions
서버리스 워크플로를 시각적으로 구성할 수 있는 기능
주로 람다 함수를 오케스트레이션 하는 데 활용한다.
함수들을 그래프로 만들어 단계별로 해당 단계의 결과에 따라 다음으로 수행하는 작업이 뭔지 정의한다.
시퀀싱, 병행 실행, 조건 설정, 타임아웃, 에러 처리 등의 기능을 제공한다.
EC2, ECS, 온프레미스 서버, API 게이트웨이, SQS 큐 등 다양한 AWS 서비스를 워크플로에 통합시킬 수 있다.
워크플로에 사람이 개입해서 승인을 해야만 진행되는 단계를 설정할 수 있다.
주문 처리, 데이터 처리, 웹 애플리케이션 등 구성하기 복잡한 워크플로를 시각적으로 구성하려고 할 때 사용한다.
Amazon Cognito
사용자에게 웹 및 모바일 앱과 상호 작용할 수 있는 자격 증명을 부여한다. 이 사용자들은 일반적으로 AWS 계정 외부에 있다. 따라서, 모르는 사용자들에게 자격 증명을 부여해 사용자를 인식(Cognito)한다.
IAM은 AWS 내부 사용자를 대상으로 하기 때문에 cognito와 다르다.
'수백 명의 사용자', '모바일 사용자', 'SAML을 통한 인증' 처리를 위해 사용된다.
Cognito 사용자 풀
웹 및 모바일 앱을 대상으로 하는 서버리스 사용자 데이터베이스
사용자 이름 또는 이메일, 비밀번호의 조합으로 간단한 회원가입, 로그인 절차를 정의할 수 있다.
비밀번호 재설정 기능이 있고 이메일 및 전화번호 검증 및 멀티팩터 인증이 가능하다.
Facebook이나 Google 등 소셜 로그인도 가능하다.
API Gateway, ALB와 통합 가능하다.
예를 들어 사용자가 Cognito 사용자 풀에 접속해서 토큰을 받고, 검증을 위해 토큰을 API Gateway에 전달하여 인증에 성공하면, 사용자 자격 증명으로 변환되어 백엔드의 Lambda 함수로 전달된다.
혹은 Cognito 사용자 풀을 애플리케이션 로드 밸런서 위에 배치하여 유효한 사용자인 경우에만 사용자 자격 증명을 헤더에 담아 백엔드로 요청을 전달할 수 있다.
Congnito Identity(자격 증명) 풀
앱에 등록된 사용자에게 임시 AWS 자격 증명을 제공해서 일부 AWS 리소스에 직접 액세스할 수 있도록 한다.
자격 증명에 적용되는 IAM 정책은 Cognito 자격 증명 풀 서비스에 미리 정의되어 있다.
게스트 사용자나 특정 역할이 정의되지 않은 인증된 사용자에게 적용하기 위해 기본 IAM 역할을 정의할 수도 있다.
user_id를 기반으로 사용자 정의하여 세분화된 제어를 할 수 있다.
Cognito 사용자 풀과 통합 가능하다.
웹이나 모바일 애플리케이션에서 S3 버킷 또는 DynamoDB 테이블에 직접 접근해야 하는 경우, Cognito Identity 풀에 먼저 접근해 로그인 및 검증 후 임시 AWS Credentials를 받으면 직접 접근이 가능해진다.
DynamoDB에 행 단위로 보안을 설정할 수 있다. DynamoDB의 LeadingKeys가 Cognito 자격 증명 사용자 ID와 같아야 한다는 조건 등을 정의하여 접근 권한을 얻은 아이템에만 접근하도록 만들 수 있다.
Last updated