【re:Invent】AWS Lambda コンテナ試して見た


AWS Lambda Container Support が発表されました。最大 10GB のサイズのコンテナイメージがデポロイできます。現時点サポートされている、全てのランタイム(Python、Node.js、Java、.NET、Go、Ruby)のベースイメージを提供します。

全体像

従来は Lambda コンソールからソース編集かアップロードできますが、コンテナイメージ使う場合、一旦 Amazon ECR に保存し、Lambda コンソールからデポロイを行います。

コンテナイメージ

Amazon ECR (Amazon Elastic Container Registry)

コンテナイメージを AWS に保管しますので、まず ECR 作ります。

aws ecr create-repository \
  --repository-name lambda-repo \
  --region ap-northeast-1

下記結果が返ってきます、repositoryUri をメモしておきましょう。

Output
{
  "repository": {
    "repositoryArn": "arn:aws:ecr:ap-northeast-1:[ACCOUNT_ID]:repository/lambda-repo",
    "registryId": "[ACCOUNT_ID]",
    "repositoryName": "lambda-repo1",
    "repositoryUri": "[ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo",
    "createdAt": "2020-12-04T08:03:18+00:00",
    "imageTagMutability": "MUTABLE",
    "imageScanningConfiguration": {
      "scanOnPush": false
    },
    "encryptionConfiguration": {
      "encryptionType": "AES256"
    }
  }
}

Dockerfile

イメージビルド用の Dockerfileを準備します。テストコードも含めて作ります。
Base image は AWS が提供する amazon/aws-lambda-nodejs:12 を使用します。

Dockerfile
# AWS Docker Image
FROM amazon/aws-lambda-nodejs:12

WORKDIR /usr/local/app

# Port
EXPOSE 8000

# Application
RUN echo $'\n\
  exports.handler = async (event) => { \n\
    const response = { \n\
      statusCode: 200, \n\
      body: JSON.stringify(\'Hello from Lambda!\'), \n\
    }; \n\
    return response; \n\
  }; \n\
  ' > index.js

CMD [ "/usr/local/app/index.handler" ]

最終的に ECR に保存して使うなので、${repositoryUri}:${tag} のフォーマットでタグを付けます。

ACCOUNT_IDは環境に合わせて修正する
# docker build
docker build -t [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo:latest .

# ECR login (Linux)
aws ecr get-login-password | docker login --username AWS --password-stdin [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com

# docker push
docker push [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo:latest

AWS Lambda デポロイ

AWS Lambda のコンソールで [Create Function] をクリックします。 [Container image] を選択し、[Browse images] をクリックします。

先ほど作った ECR Repository から、 latest タグ付けたコンテナイメージを選択し、[Select image] をクリックします。

最後は [Function name] を入れて、他の設定は全部デフォルトのままで、[Create function] をクリックします。

テスト

Lambda コンソールでテストしましょう。想定通りの結果が返ってきました。

パフォーマンス

コンテナイメージ大きいため、やはりコードスタート気になりますね。

イメージサイズ (MB) Lambdaメモリ (MB) コードスタート 正常コール (5回平均)
146.71 128 Duration (11.20 ms)
Billed duration (619 ms)
Duration (7.6ms)
Billed duration (8 ms)
146.71 640 Duration (2.28 ms)
Billed duration (584 ms)
Duration (1.84ms)
Billed duration (2 ms)
146.71 1280 Duration (1.98ms)
Billed duration (459 ms)
Duration (0.95ms)
Billed duration (1 ms)

結果から見ると、メモリを積めば、ある程度改善できます。

おまけに

Lambda コンテナベースイメージの自作方法は、公式ドキュメントに Python のみの記載があります。
日本語の翻訳またなので、英語のみとなります。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images-create.html