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







