gony-dev 님의 블로그

Section 21. AWS 서버리스: Lambda - 2 본문

AWS

Section 21. AWS 서버리스: Lambda - 2

minarinamu 2024. 11. 5. 01:44

Lambda Layers

람다 레이어는 두 가지 특징을 가질 수 있다.

 

1. Custom Runtimes

  • 원하는 언어로 커스터마이징하여 런타임을 설정할 수 있다.

2. Externalize Dependencies to re-use them

  • 라이브러리를 재사용하기 위해 종속성을 외부화할 수 있다.

람다 레이어를 통해 함수를 훨씬 빠르게 배포할 수 있고 종속성이 있을 때마다 매번 다시 패키징할 필요가 없다.

또한 계층이 외부화되어 있으므로 다른 함수나 어플리케이션에서 다른 함수를 만들어 동일한 계층을 참조할 수 있다.

 

주의! 람다 계층의 데이터는 수정할 수 없다.


Lambda File Systems Mounting

  • 람다 함수는 VPC 내에서 작동할 경우, EFS 파일 시스템에 액세스할 수 있다.
  • 그러기 위해서는 초기화하는 동안 로컬 디렉토리에서 EFS 파일 시스템을 마운트하도록 람다를 설정해야 한다.
  • 그리고 EFS 액세스 포인트 기능을 사용해야만 한다.
  • EFS 액세스 포인트는 각각의 람다 인스턴스가 EFS 파일 시스템에 한 번 이상 연결된다는 단점이 있다. 이는 연결 제한에 도달할 수 있으므로 주의해야 한다.

Lambda Stroage Options

아래는 람다에 대한 여러 스토리지 옵션들이다.


Lambda Concurrency and Throttling

  • 람다 함수 실행에 대한 동시성은 1000개까지 가능하다.
    • 작은 규모에는 적은 람다 함수 실행이 되겠지만, 큰 규모의 이벤트에는 람다 함수가 최대 1000개까지 동시에 실행되어 전부 같은 작업을 수행하게 된다.
  • 우리는 이를 잘 조절하기 위해 "예약된 동시성"을 사용할 수 있다.
    • 예약된 동시성을 통해 정해진 개수 만큼만 실행하도록 제한을 둘 수 있다!
    • 만일 동시적 제한을 초과하는 각각의 호출이 있다면 스로틀을 트리거하게 된다.
  • 스로틀에는 2가지 유형이 있는데,
    1. 동기적 호출 | 조절이 발생할 때 ThrottleError 429를 반환한다.
    2. 비동기적 호출 | 조절 발생 시, 자동으로 재시도한 후 DLQ로 이동한다.

1. Lambda Concurrency Issue

  • 상황을 부여해 보이겠다.
  • 첫 번째 어플리케이션에는 다수의 사용자들이 사용을 하고, 두 번째 어플리케이션은 소수의 사용자들이 사용을 한다. 그리고 또 하나의 세 번째 어플리케이션은 SDK와 CLI를 이용해서 람다 함수를 호출한다.
  • 첫 번째 어플리케이션에서 많은 사용자가 요청을 하면 로드 밸런서가 무수히 많은 람다 함수를 호출하여 최대 1000개까지 동시 실행이 일어난다. 하지만 이때 두 번째와 세 번째의 어플리케이션은 동시성 제한으로 인해 스로틀을 겪게 된다.
  • 이와 같이 함수 실행은 다른 함수까지 조절 대상이 되기 때문에 동시성을 설정할 필요가 있다.

 

2. Concurrency and Asychronous Invocations

  • 만일 람다 함수가 모든 이벤트를 처리하기에 충분한 동시성을 가지고 있지 않다면, 추가적인 요청이 조절된다.
  • 스로틀 오류 429와 500 시리즈에 대해 람다는 대기열에 이벤트를 반환하고, 최대 6시간까지 함수를 재실행하려고 시도한다.
  • 이때 재시도 간격은 지수 백오프 방식으로 증가하며, 최소 1초에서 5분까지 람다 함수를 재시도할 수 있다.

3. Cold Starts & Provisioned Concurrency

  • "Cold Start"는 새로운 람다 함수 인스턴스를 생성할 때에 코드가 로드되어야 하며 핸들러 외부에서 이 코드가 실행되어야 함을 의미한다.(실행할 때 초기화 한다는 의미)
    • 이때 초기화 작업의 용량이 많다면 시간이 오래 걸릴 수 있다.
    • 새 인스턴스로 수행하게 되는 첫 번째 요청은 다른 인스턴스보다 지연 시간이 길기에 사용자에게 영향을 줄 수 있다.(느리니까)
  • 이때 필요한 것이 "Provisioned Concurrency"이다.
    • 함수가 호출되기도 전에 동시성을 할당해 놓는 작업이다.
    • 그렇게 되면 Cold Start는 절대 일어나지 않고 모든 호출은 낮은 지연 시간을 갖게 된다.
  • VPC에서는 람다 함수를 실행할 때마다 긴 시간이 걸렸으나 이를 통해 확연히 시간이 줄어들었음을 확인할 수 있다!

Lambda and CloudFormation

CloudFormation을 활용하여 람다 함수를 업로드 하는 데에는 2가지 방법이 있다.

  1. Inline
    • 람다 코드를 인라인으로 CloudFormation 템플릿에 정의한다.
    • 단순하지만 인라인 함수와 같이 함수 종속성을 포함시킬 수는 없다.
  2. Through S3
    • S3에 람다 zip 파일을 저장해야만 한다.
    • CloudFormation 코드에 S3 zip 위치를 참조하도록 해야한다.
    • 만일 S3에 코드를 업데이트하였지만 CloudFormation 템플릿에 S3 버킷, S3 키나 S3ObjcetVersion을 업데이트하지 않았다면 함수를 업데이트 하지 않을 것이다.(그래서 버저닝을 추천!!)
  3. Through S3 Multiple accounts


Lambda Container Images

    • ECR에서 10GB까지 컨테이너 이미지를 람다 함수에 배포할 수 있다.
    • 그래서 복잡하고 큰 종속성을 컨테이너에 패키징하여 베이스 이미지에 올릴 수가 있다.
    • 베이스 이미지로는 파이썬, 자바 등의 다양한 언어로 사용할 수 있으며, 람다 런타임 API를 구현하기만 한다면 직접 람다 베이스 이미지를 만들 수 있다.

  • 람다 함수를 도커 이미지로 빌드하기 위해서는 아래의 코드를 순서대로 입력하면 된다.

 

❗️컨테이너 이미지를 최적화시키는 방법들

  1. AWS에서 제공된 베이스 이미지를 사용하자
  2. 멀티 스테이징 빌드를 사용하자.
  3. 안정적인 것부터 자주 변경되는 계층까지 다양한 계층에 이미지를 빌드하자.
  4. 계층 규모가 큰 함수에는 리포지토리를 하나만 생성하자.
  5. 최대 10GB에 달하는 큰 람다 함수를 업로드하려는 경우에 람다에 코드를 그대로 푸시하는 대신 아주 큰 컨테이너 이미지를 만들어 람다 함수의 기반으로 사용하자!

Lambda Version & Alias

지금까지 우리는 람다 함수를 사용할 때마다 "$LATEST"를 사용해왔다.
이는 코드 수정이 가능했기 때문에 사용했는데, 이제 우리는 람다 함수를 게시하고 버전을 생성할 수 있다.
버전은 변경이 불가능하며, 하나의 버전으로 고정된다.
각 버전은 고유 ARN을 가지며, 코드와 설정으로 이루어져 있다.

 

❓최종 사용자에게 안정적인 엔드 포인트를 제공하는 방법

그 방법은 람다 별칭을 사용하는 것이다.

  • 별칭은 변경이 가능한 특징이 있고, 람다 함수 버전의 포인터 역할을 한다.
  • 별칭은 자신의 고유한 ARN을 가지지만, 별칭은 다른 별칭을 참조할 수 없다.


Lambda & CodeDeploy

  • CodeDeploy를 사용하면 람다 별칭에 트래픽 이동을 자동화할 수 있다.
  • CodeDeploy 전략
    1. Linear | 트래픽이 N분마다 100%까지 늘어난다.
    2. Canary | X%를 시도한 후 100%가 된다.
    3. AllAtOnce | 즉시 100%가 된다.


Lambda Function URL

  • 람다 함수 URL은 람다 함수를 위해 HTTP(S) 엔드포인트로만 노출되도록 한다.
  • 함수를 사용하면 람다 함수에 절대 바뀌지 않는 고유한 URL 엔드포인트가 주이진다.
  • 함수 URL은 퍼블릭 인터넷으로만 액세스할 수 있어서, 프라이빗으로 액세스하고 싶다면 이 방법을 권장하지 않는다.
  • 모든 함수 별칭이나 최신 함수 버전에도 적용할 수 있지만 함수 버전을 특정하여 적용할 수는 없다.
  • 만일 스로틀링이 필요하다면, 람다의 예약된 동시성을 사용하여 람다 함수 실행량을 조절할 수 있다.

Lambda - Function URL Security

  • URL 보안의 경우..
    1. 리소스 기반 정책이 람다 함수에 연결되며 어떤 계정이나 특정 CIDR, IAM 보안 주체가 액세사할 수 있는지 나타낼 수 있다.
    2. CORS는 다른 도메인에서 람다 함수 URL을 호출할 시 CORS 보안을 설정해야 한다.
    3. AuthType NONE은 인증되지 않은 퍼블릭한 액세스를 허용한다.
      • 리소스 기반 정책에 따라 함수에 요청이 허용될지 여부가 결정된다.
    4. AuthType AWS_IAM은 IAM이 인증 및 인가된 요청에 사용되는 것이다.
      • 이것은 보안 주체 자격 증명 기반 정책과 리소스 기반 정책 모두를 평가한다.
      • 같은 계정 내에 있다면 자격 증명 정책이나 리소스 기반 정책 둘 중 하나로 API 호출을 허용하면 된다.
      • 계정 간 교차한다면 양쪽 모두가 API 호출을 허용해야 한다.

CORS를 통한 람다 함수 URL 사용


Lambda Limits to Know

❗️시험에서 출제할 가능성 높음❗️

1. per region

  • Execution 제한
    • 메모리 할당은 128MB에서 10GB까지이며 1MB씩 증가한다.
    • 최대 실행 시간은 900초(=15분)
    • 환경 변수는 최대 4KB
    • /tmp 내의 용량은 512MB
    • 동시 실행은 1000개까지이다.
  • Deployment
    • 람다 함수 배포 용량은 50MB
    • 압축하지 않았을 때의 용량은 250MB이다.
    • 그보다 큰 용량은 /tmp 디렉토리를 이행할 것!
    • 환경 변수는 똑같이 4KB가 최대이다.

Lambda Best Practices

  • 함수 핸들러 밖에서 많은 작업을 수행해야 한다.
    • 데이터베이스를 외부에서 연결한다던가, 종속성과 데이터셋을 함수 핸들러 외부에서 가지고 오는 작업 등등
  • 모든 것에 대해 환경 변수를 사용해야 한다.
    • 데이터베이스 연결, S3 버킷 등등은 값을 KMS을 사용하여 암호화해야 한다.
  • 배포 패키지 크기를 런타임에 맞게 최소화해야 한다.
    • 필요하다면 함수를 종료해도 된다.
    • 람다의 한계를 파악해야 함을 유의하자.
  • 재귀적인 코드를 피해야 한다.
    • 그렇지 않으면 람다 함수는 비용을 대단히 많이 치르게 될 수 있다