現在開催中のre:InventでAWS Lambdaがコンテナのサポートをするという発表がありましたね。
というわけでちょっと試してみました。
素材はここにあげてあります。
流れとしては、
- 普通にファンクション書く
- Dockerfile作る
- イメージをビルドする
- イメージをECRにプッシュする
- Lambdaファンクションを作るときにECR上のイメージを指定する
という感じです。3,4のコマンド実行例はReadmeに記載しています。
イメージに関してはRuntime APIを実装する必要があるんですが、現在Lambdaがサポートしている各言語向けには既に用意されていてリリースされています。例えばNode.jsであればnpm install aws-lambda-ric
でインストールできます。
加えて、これを組み込み済のベースイメージが既に用意されているのでこれを使うのが楽かもです。僕が試したサンプルも用意されているベースイメージを使ってます。きっとLambdaがサポートしていない言語の場合はカスタムランタイムを作るのと同じような感じでやればいいんじゃないかと思うんだけど確証はない。
サンプルではaxiosを使ってGoogleのトップページをリクエストしてその結果を出力しているだけです。超絶雑なコード。
"use strict"; const axios = require("axios"); exports.lambdaHandler = async (event, context, callback) => { const url = "https://google.com/"; const res = await axios.get(url).then((res) => callback(null, { statusCode: res.status, body: res.data, headers: { "Content-Type": "text/html", }, }) ); };
axiosはpackage.json
に書いておいてイメージをビルドする際にnpm install
してます。ま、自前のコンテナイメージを用意できる利点はこのあたりにあるのかもしれない。
Dockerファイルはこんな感じ。
FROM amazon/aws-lambda-nodejs:12 COPY app.js package*.json ./ RUN npm install CMD [ "app.lambdaHandler" ]
Runtime Interface Emulaterなるものもあるので自前でがっつりイメージ作る人は使うといいのかもしれない。
Lambdaファンクションの作成はこんな感じで。
コンテナイメージを使う場合の選択が増えてるのでそれを選択して、先程ECRにプッシュしたイメージを指定するだけです。
作成してから、実行できるようになるまで少し時間がかかるようでその間はテスト実行のボタンが無効になってました。準備完了したらボタンが押せるように。というわけでテスト実行もできます。
組み込みのコードエディタは当然のことながら使えませんでした。ま、コンテナイメージだしあたりまえよね。それ以外は普通のファンクションと同じ。ちなみに同じくre:InventでLambdaの課金単位がこれまでの100ms単位から1ms単位へと粒度が細かくなりました。
という感じですが、Dockerイメージがサポートされるからといって何でも自由にできるというよりは、あくまでもLambdaの実行モデルであるファンクションモデルはそのままにランタイムの自由度が増したって感じですね。
必要な人にはとってもいいエンハンスだと思いますが、過度な期待は禁物です。
追記:
これローカルでも簡単に実行できるのでローカルテストしたい場合にはいいかもですね。ローカル実行するには作ったイメージをdocker run
でローカルで起動した上でLambdaのAPIをlocalhostに対して実行するだけです。
docker run -p 3000:8080 lambda-container-support-sample:latest
こんな感じでローカルで起動して別ターミナルから以下のようにAPIをリクエストするだけです。
curl -XPOST "http://localhost:3000/2015-03-31/functions/function/invocations" -d '{}'