コネヒト開発者ブログ

コネヒト開発者ブログ

Lambdaのコンテナサポートに関する考察

こんにちは。インフラエンジニアの永井(shnagai)です。

AWS re:Invent今年も大豊作ですごいですね。まだ全部は追えてないんですが、良さそうなものがあればサービスに取り入れていこうと思いわくわくしています。

この記事はコネヒト Advent Calendar 2020 - Qiita 3日目の記事です。

今回は、試してみてる方は結構いそうなので、ざっとLambdaのコンテナサポートを触ってみた感じの所感を中心に書いていきます。

うれしいポイント

  • 今想像してる一番うれしいポイントは、lambdaがサポートしてる数多のAWSインテグレーションをトリガに好きな処理が動かせるところ(lambdaRuntimeAPIの存在を知りそう甘くないことを理解した)
  • ローカルの開発がやりやすくなるなー
    • SAMとか使って出来るけど。個人的にはlambdaの管理は煩雑
    • dockerで検証出来た方が楽
  • lambdaの設定とアプリケーションコード(コンテナ)を分離して管理出来るようになるので、コード化しやすいなとか

vs 既存のLambda

  • Lambdaの一番かゆいところは、チーム開発しようとするとデプロイフローがやや面倒という点があると思っている(AWS SAMとかをうまく使っていけば出来なくはないが、チーム全員で回すにはやや複雑と感じている)

pros

  • 今回、アプリケーションコードをDockerコンテナ内に閉じ込めることで、既存の開発フローに乗せてLambdaを開発出来るようになる未来が見えた
  • ハンドラがDockerのCMD句に置き換わるので、共通のイメージで開発して、Function毎にCMD句だけ上書きすることで管理コストが大幅に下げれそうな気がしている

cons

  • しいて言うなら、Lambdaのメリットにマネコン上からコード閲覧出来たりサクッと変えてお試しみたいなのが出来るのがあると思うが、それは出来ない(手軽さは少し落ちるかなというところ)

vs Fargate

  • サーバレスでコンテナを動かせると考えると、Fargateの代替になりえるなと考えるのは当然の流れだと思う

pros:

  • AWSのインテグレーションを簡単に使えるというLambdaの強みを享受
    • 例えば、下のサンプルでやったSQSトリガのワーカーの仕組みなんかは、Fargateでやる場合は、ポーリングの処理を書かないといけないがそれが不要になるのはうれしい
  • Fargateでコンテナ動かすには、ECSなりEKSのオーケストレーターも必要なわけなので、スポットで単発の処理動かしたいみたいな時はLambdaはより簡単で良い

cons:

  • LambdaRuntimeAPIをコンテナ側で実装しなければいけないので、どんなイメージでも動くわけではない。
    • AWSである程度の言語については、すでに用意されてはいる
    • インターフェースを統一しなきゃいけないのはそれはそうだな
    • 既存のアプリケーションの一部をLambda+コンテナで動かすのはちょっとハードルあるなというのが正直な印象ではある

ちょっとイメージと違ったところ

これは触ってみて感じたことなので、実は違う可能性もある。

  • コンテナイメージは都度pullではなく、イメージ設定時に固定されそう
    • 同一タグでECR更新して、起動時に最新のイメージ取得みたいな構成は出来なさそう(何回か試したけど、lambdaを更新した時にイメージがずっと使われてそうだった)
    • 「新しいイメージをデプロイ」する時にpullしてるように見える
    • 起動速度維持するために、キャッシュしてるのかなと想像
    • コンテナビルドとLambdaの更新をセットでやらないとダメそう

で試してみる

今回は、SQSをイベントソースとして、SQSキューが入ったら中身を出力するという簡単な内容(疑似的なワーカー)

こちらのチュートリアルをベースに実行

docs.aws.amazon.com

コードはこちら

github.com

コンテナの準備

$ docker build -t [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:test .

## 手元で動作確認
$ docker run --rm [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:test

hogehoge

## ECRへのpush(ログイン込)
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com && docker push [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:test


Lambdaの設定

作成(コンテナイメージを選ぶ)

f:id:nagais:20201203100953p:plain

  • 手元にあった適当なpython動くコンテナで最初試したけど、それをただ実行させるとかは出来ないみたい(lambdaRuntimeAPIが必要で、呼び出しI/FもLambdaにそる)

f:id:nagais:20201203100356p:plain

  • IAM Roleとして AWSLambdaSQSQueueExecutionRole を追加するのを忘れずに。

SQSの準備

aws-cliでサッと作る

$ aws sqs create-queue --queue-name lambda-test
{
    "QueueUrl": "https://ap-northeast-1.queue.amazonaws.com/[アカウントID]/lambda-test"
}

先程作ったLambdaのイベントソースに上記のSQSを登録

テスト

$ aws sqs send-message --queue-url https://ap-northeast-1.queue.amazonaws.com/[アカウントID]/lambda-test --message-body "lambda-containerのテスト"

無事に動いた。

f:id:nagais:20201203100305p:plain

クラメソさんの記事が概要理解するのにめちゃ役立ちました!!

dev.classmethod.jp