Amazon Web Services ブログ
AWS Lambda の新機能 – コンテナイメージのサポート
AWS Lambda では、サーバーについて気にすることなくコードをアップロードして実行できます。多くのお客様に Lambda のこの仕組みをご活用いただいていますが、開発ワークフローのためにコンテナツールに投資した場合は、Lambda でのアプリケーションの構築に同じアプローチを使用することが難しくなります。
この問題に対応するため、Lambda 関数を最大 10 GB のコンテナイメージとしてパッケージ化し、デプロイできるようになりました。これにより、機械学習やデータ集約型のワークロードなど、大きな依存関係に頼る大規模なワークロードを簡単に構築してデプロイできます。ZIP アーカイブとしてパッケージ化された関数と同様に、コンテナイメージとしてデプロイされた関数は、同様の操作のシンプルさ、自動スケーリング、高可用性、多数のサービスとのネイティブ統合による恩恵を受けます。
当社では。サポートされているすべての Lambda ランタイム (Python、Node.js、Java、.NET、Go、Ruby) のベースイメージを提供しているため、コードと依存関係を簡単に追加することができます。Amazon Linux ベースのカスタムランタイム用のベースイメージも用意しており、これを拡張して Lambda ランタイム API を実装する独自のランタイムを含めることができます。
Alpine や Debian Linux をベースにしたイメージなど、独自のベースイメージを任意で Lambda にデプロイできます。Lambda を操作するには、これらのイメージに Lambda ランタイム API を実装する必要があります。独自のベースイメージの構築を容易にするため、当社ではサポートされているすべてのランタイムにランタイム API を実装する Lambda Runtime Interface Clients をリリースしています。これらの実装は、ネイティブのパッケージマネージャーを介して利用できるため、イメージ内で簡単に取得でき、オープンソースライセンスを使用してコミュニティと共有されます。
また、Lambda Runtime Interface Emulator をオープンソースとしてリリースします。これにより、コンテナイメージのローカルテストを実行して、Lambda にデプロイした際に実行されることを確認することができます。Lambda Runtime Interface Emulator は、AWS が提供するすべてのベースイメージに含まれており、任意のイメージでも使用できます。
コンテナイメージは、Lambda Extensions API を使用して、モニタリング、セキュリティ、その他のツールを Lambda 実行環境に統合することもできます。
コンテナイメージをデプロイするには、Amazon Elastic Amazon Elastic Container Registry のリポジトリから 1 つを選択します。これが実際にどのように機能するか、いくつか例を見てみましょう。最初に、AWS が提供する Node.js のイメージを使用し、次に Python のカスタムイメージを構築します。
AWS が提供するベースイメージを Node.js で使用する
以下に、PDFKit モジュールを使用して PDF ファイルを生成するシンプルな Node.js Lambda 関数のコード (app.js
) を示します。呼び出されるたびに、faker.js モジュールによって生成されたランダムデータを含む新しいメールが作成されます。関数の出力は、Amazon API Gateway の構文を使用して PDF ファイルを返します。
npm
を使用してパッケージを初期化し、必要な 3 つの依存関係を package.json
ファイルに追加します。このようにして、package-lock.json
ファイルも作成します。より予測可能な結果を得るために、それをコンテナイメージに追加します。
ここで、nodejs12.x
ランタイム用に AWS が提供するベースイメージから開始し、Lambda 関数のコンテナイメージを作成する Dockerfile
を作成します。
Dockerfile は、ソースコード (app.js
) と、パッケージと依存関係を記述するファイル (package.json
および package-lock.json
) をベースイメージに追加します。次に、npm
を実行して依存関係をインストールします。CMD
を関数ハンドラーに設定しましたが、これは後で Lambda 関数を設定する際にパラメータオーバーライドとして実行することもできます。
Docker CLI を使用して、ランダムな文字
のコンテナイメージをローカルに構築します。
これが機能しているかどうかを確認するには、Lambda Runtime Interface Emulator を使用して、コンテナイメージをローカルで起動します。
ここで、cURL を使用して関数の呼び出しをテストします。ここでは、空の JSON ペイロードを渡します。
エラーがある場合は、ローカルで修正できます。うまくいったら、次のステップに進みます。
コンテナイメージをアップロードするには、アカウントに新しい ECR リポジトリを作成し、ローカルイメージにタグを付けて ECR にプッシュします。コンテナイメージのソフトウェアの脆弱性を特定しやすくするために、ECR イメージスキャンを有効にします。
ここで、AWS マネジメントコンソールを使用して関数の作成を完了します。更新によりコンテナイメージのサポートが追加された、AWS サーバーレスアプリケーションモデルを使用することもできます。
Lambda コンソールで、[Create function (関数の作成)] をクリックします。[Container image (コンテナイメージ)] を選択して関数に名前を付け、[Browse images (イメージの参照)] を選択して ECR リポジトリ内の正しいイメージを探します。
リポジトリを選択したら、アップロードした latest
イメージを使用します。イメージを選択すると、Lambda はそれを基盤となるイメージのダイジェスト (下の画像のタグの右側) に変換しています。docker images --digests
コマンドを使用して、イメージのダイジェストをローカルで確認することができます。このように、latest
タグが新しいタグに渡された場合でも、関数は同じイメージを使用するため、意図しないデプロイから保護されます。関数コードで使用するイメージを更新できます。その間にタグが別のイメージに再割り当てされた場合でも、関数設定の更新が使用されるイメージに影響することはありません。
オプションで、コンテナイメージの値の一部をオーバーライドすることができます。今回はこれを行っていませんが、このようにして、たとえば CMD
値の関数ハンドラーをオーバーライドすることで、さまざまな関数に使用できるイメージを作成できます。
他のすべてのオプションをデフォルトにしたまま、[Create function (関数の作成)] を選択します。
関数のコードを作成または更新するとき、Lambda プラットフォームは新しいコンテナイメージと更新されたコンテナイメージを最適化し、呼び出しを受信できるように準備します。この最適化には、イメージのサイズに応じて数秒から数分かかります。その後、関数を呼び出す準備が整います。コンソールで機能をテストします。
機能しています! それでは、トリガーとして API Gateway を追加しましょう。[Add Trigger (トリガーを追加)] を選択し、HTTP API を使用して API Gateway を追加します。わかりやすくするために、API の認証は開いたままにしておきます。
ここで、API エンドポイントを数回クリックして、ランダムなメールをいくつかダウンロードします。
思った通りに機能しています! faker.js モジュールからのランダムデータを使用して生成される PDF ファイルを、いくつか次に示します。
Python のカスタムイメージを構築する
会社のガイドラインに従ったり、サポートされていないランタイムのバージョンを使用したりするために、カスタムコンテナイメージを使用する必要があることがあります。
ここでは、Python 3.9 を使用するイメージを作成します。関数のコード (app.py
) は非常にシンプルです。ただ挨拶して、使用している Python のバージョンを伝えるだけです。
前に述べたとおり、サポートされるすべてのランタイムで (Runtime API を実装する) Lambda Runtime Interface Clients のオープンソース実装を共有しています。この場合、Alpine Linux に基づく Python イメージから始めます。次に、Python 向けの Lambda Runtime Interface Client (リンクを近日公開) をイメージに追加します。Dockerfile
は次のとおりです。
今回の Dockerfile はより明瞭で、複数ステージでの構築に関する Docker のベストプラクティスに従って、3 つのステージで最終イメージを構築します。この 3 段階のアプローチを使用して、独自のカスタムイメージを作成できます。
- ステージ 1 では、ランタイム (この場合はPython 3.9) と、ステージ 2 で依存関係をコンパイルしてリンクさせるために使用する GCC によってベースイメージを構築しています。
- ステージ 2 では、Lambda Runtime Interface Client をインストールし、関数と依存関係を構築します。
- ステージ 3 では、ステージ 1 で作成したベースイメージにステージ 2 からの出力を追加するための最終イメージを作成します。ここでは Lambda Runtime Interface Emulator も追加していますが、これはオプションです。以下を参照してください。
以下の entry.sh
スクリプトを作成して、ENTRYPOINT
として使用します。Python 向けの Lambda Runtime Interface Client を実行します。実行がローカルの場合、Runtime Interface Client は Lambda Runtime Interface Emulator によってラップされます。
これで、Lambda Runtime Interface Emulator を使用して、関数とコンテナイメージが正しく機能しているかどうかをローカルで確認できるようになりました。
コンテナイメージに Lambda Runtime Interface Emulator を含まない
カスタムコンテナイメージへの Lambda Runtime Interface Emulator の追加はオプションです。これを含めない場合は、次の手順に従ってローカルマシンに Lambda Runtime Interface Emulator をインストールし、ローカルでテストできます。
- Dockerfile のステージ 3 で、Lambda Runtime Interface Emulator (
aws-lambda-rie
) とentry.sh
スクリプトをコピーするコマンドを削除します。この場合、entry.sh
スクリプトは必要ありません。 - この
ENTRYPOINT
を使用して、Lambda Runtime Interface Client をデフォルトで起動させます。
ENTRYPOINT [ "/usr/local/bin/python", “-m”, “awslambdaric” ]
- これらのコマンドを実行して、ローカルマシンに Lambda Runtime Interface Emulator をインストールします (例:
~/.aws-lambda-rie
)。
Lambda Runtime Interface Emulator がローカルマシンにインストールされている場合は、コンテナを起動する際にマウントできます。コンテナをローカルで起動するコマンドは次のとおりです (Lambda Runtime Interface Emulator が ~/.aws-lambda-rie
にあると仮定しています)。
Python 向けのカスタムイメージのテスト
どちらの方法でも、コンテナがローカルで実行されている場合は、cURL を使用して関数の呼び出しをテストできます。
期待していた通りに出力されています!
"Hello from AWS Lambda using Python3.9.0 (default, Oct 22 2020, 05:03:39) \n[GCC 9.3.0]!"
画像を ECR にプッシュし、前と同じように関数を作成します。コンソールでのテストは次のとおりです。
Alpine に基づくカスタムコンテナイメージは、Lambda で Python 3.9 を実行しています!
このサービスは、今すぐご利用いただけます
現在、Lambda 関数は、米国東部 (バージニア北部)、米国東部 (オハイオ)、米国西部 (オレゴン)、アジアパシフィック (東京)、アジアパシフィック (シンガポール)、欧州 (アイルランド)、欧州 (フランクフルト)、南米 (サンパウロ) で、コンテナイメージを使用して今すぐデプロイできます。他のリージョンでも近いうちにサポートを追加する予定です。コンテナイメージのサポートは ZIP アーカイブに加えて提供されており、ZIP のパッケージ形式を引き続きサポートします。
この機能の使用に追加料金は発生しません。ECR リポジトリと、通常の Lambda の料金のみお支払いいただきます。
AWS Lambda でのコンテナイメージのサポートは、コンソール、AWS コマンドラインインターフェイス (CLI)、AWS SDK、AWS サーバーレスアプリケーションモデル、および AWS パートナーが提供するソリューション (Aqua Security、Datadog、Epsagon、HashiCorp Terraform、Honeycomb、Lumigo、Pulumi、Stackery、Sumo Logic、Thundra など) で使用できます。
この新機能によって新しいシナリオが開かれたことで、開発パイプラインとの統合が簡素化され、カスタムイメージや、お好きなプログラミングプラットフォームを使用してサーバーレスアプリケーションを構築することが容易になりました。
詳細を確認し、AWS Lambda でコンテナイメージの使用を開始してください。
— Danilo