AWS Lambdaのコンテナイメージサポートを試してみる

Tags:

#AWS #Node.js
このエントリーをはてなブックマークに追加

本記事は東京学芸大学 櫨山研究室 Advent Calendar 2020の3日目の記事になります。

はじめに

先日、AWS Re:InventにてAWS Lambdaのコンテナイメージサポートが発表されました。

どうやらDockerイメージをデプロイし、それをLambda関数として実行できるようです。

Lambdaで動作させるためのベースイメージはAWSから提供されており、以下の言語でイメージが公開されているようでした。

また、Lambda Runtime APIを満たす、コンテナイメージを作成することで独自のLambda実行環境を作成することも可能なようです。

また、今回提供されるベースイメージにはLambda Runtime Interface Emulatorという機能が内包されており、ローカル環境でLambdaを実行できるようにもなったようです!

今回はこれらの機能を試していきたいと思います。 コードは以下のリポジトリに置いてあります。 https://github.com/hikaru7719/lambda-container

コンテナイメージのデプロイ

早速、AWSが提供するベースイメージを利用して、Lambda関数を作成していきと思います。 今回はNode.jsでHello World!!!を出力するLambda関数を作成していきます。

index.jsに以下のコードを記述しました。

exports.handler = (event, context) => {
  console.log("Hello World!!!");
};

次に作成するのはDockerfileです。 機能紹介のページにあったサンプルを参考にして、Dokcerfileを作成しました。

FROM amazon/aws-lambda-nodejs:12
COPY . .
RUN npm install
CMD ["index.handler"]

amazon/aws-lambda-nodejs:12がAWSから提供されている公式のベースイメージです。 CMDの部分には${ファイル名}/${関数名}を記述するようです、

これで準備は完了です。 あとはECRにDockerイメージをpushして、そのイメージを元にLambda関数を作成するだけです。

Dockerイメージのpushには以下のコマンドを利用します。 今回は事前にGUIからECRのリポジトリを作成しておきました。

aws ecr get-login-password --region ${region} | docker login --username AWS --password-stdin ${account_id}.dkr.ecr.${region}.amazonaws.com 
docker build -t lambda-container .
docker tag lambda-container:latest ${account_id}.dkr.ecr.${region}.amazonaws.com/${repository_name}:latest
docker push ${account_id}.dkr.ecr.${region}.amazonaws.com/${repository_name}:latest 

これでECRにDockerイメージをpushすることができました。

コンテナイメージからLambda関数を作成する

次はイメージを元にLambda関数を作成していきます。今回はGUIから作成していきます。

コンソールからLambdaのページに行き、関数の作成ボタンを押します。 コンテナイメージという選択肢があるので、それを選択します。

あとは関数名を入れて、コンテナイメージを選択するだけです。 画像を選択というボタンをクリックすると、ECRのリポジトリとイメージのバージョンを選択することができます。

あとはデフォルトのままにして、関数の作成ボタンを押します。 「関数xxxを作成中です。」とメッセージが出てくるので、数秒待ちます。 数秒待つと「関数xxxを正常に作成しました。」とメッセージが出てきます。 これでLambda関数の作成は完了です。

適当にテストを作成し、テストを実行すると、見事にコンテナでデプロイしたLambda関数が動きました!!

CloudWatch Logsにも無事、Hello World!!!が出力されていました。

ローカルでの実行

エミュレーターの機能も試してみたいと思います。レスポンスが返ってくるようにindex.jsを以下のように修正します。

exports.handler = async (event, context) => {
  return {
    statusCode: 200,
    body: "Hello World!!!",
  };
};

この状態で再度ビルドし、実行します。

docker build -t container-image .
docker run -p 9000:8080 container-image

コンテナが起動したら、cURLでエンドポイントを叩きます。

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
{"statusCode":200,"body":"Hello World!!!"}

すると見事レスポンスが返ってきました!!!

ローカル環境でLambdaを実行できるエミュレーター機能はかなり便利そうです。

まとめ

Lambdaのコンテナイメージサポートの機能を試してみました。 DcokerイメージからLambda関数を作成できるというのはもちろん便利でしたが、ローカル環境でLambda関数を実行できるというのも非常に魅力的でした。

AWS CDKのドキュメントを確認したところ、すでにコンテナイメージからLambda関数を作成することが可能なようでした。 次回はこれを試してみたいと思います。

最後までお読みいただきありがとうございました!!

See Also