Serverless Operations, inc

>_cd /blog/id_mg55x-8pn79

title

AWS Lambda がコンテナベース関数で SnapStart をサポートしたのでやってみた

2026年9月、AWS Lambda に「コンテナイメージ関数の SnapStart 対応」という待望のアップデートが加わりました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/07/aws-lambda-snapstart-container/

Lambda がここ数年で対応した「コンテナ対応」と「コールドスタート対策(SnapStart)」が組み合わさったアップデートになっています。

Lambda がコンテナをサポートした時期と背景

AWS Lambda がコンテナイメージ(OCI イメージ)をサポートしたのは、2020年12月、re:Invent 2020 での発表です。それ以前の Lambda は、コードを ZIP アーカイブとしてパッケージする方式が基本でした。

ZIP 方式には、当時いくつかの制約と使いづらさがありました。

  • サイズの上限が小さい: ZIP パッケージは、アップロード時で 50MB(圧縮)、展開後で 250MB という上限がありました。機械学習モデルや大きな依存ライブラリを含む処理には手狭でした。
  • 既存のコンテナ資産を活かせない: 多くの開発チームはすでに Docker ベースのビルドや CI/CD、社内の共通ベースイメージといった「コンテナのエコシステム」に投資していました。しかし ZIP 方式では、その資産やワークフローをそのまま Lambda に持ち込めませんでした。
  • ランタイムごとに勝手が違う: ZIP 方式はランタイムごとに独特なディレクトリ構成を強いる場面があり、ローカルでの再現やテストがしづらいという声もありました。

こうした背景から、コンテナイメージ対応が導入されました。ポイントは次のとおりです。

  • 最大 10GB のイメージサイズ: ZIP の 250MB から大きく拡張され、機械学習やデータ集約型のワークロードのように、大きな依存関係を含む処理も扱いやすくなりました。
  • 使い慣れたコンテナツールをそのまま利用: Dockerfile でイメージをビルドし、Amazon ECR に push して Lambda 関数のコードソースとして指定する、という一般的なコンテナ開発の流れに乗せられます。
  • ローカルでの開発・テストのしやすさ: 同じ発表で、任意のイメージを Lambda Runtime API に対応させる Runtime Interface Client(RIC)と、ローカルで Lambda の挙動を模擬する Runtime Interface Emulator(RIE)が導入され、「ローカルで動いたものがそのまま Lambda で動く」体験が可能となりました。

SnapStart の発表

Lambda はリクエストがあったときに実行環境を用意しますが、待機中の「温かい(ウォーム)」環境が無い場合、環境を新規に立ち上げる必要があります。このとき発生するのがコールドスタートです。

コールドスタートの中でも大きな割合を占めるのが、関数の初期化時間です。コードの読み込み、ランタイムの起動、依存ライブラリの初期化などがここに含まれます。とくに Java の JVM 起動やクラスロード、あるいは大きな依存関係を持つアプリケーションでは、初期化に数秒かかることも珍しくありません。レイテンシに敏感な対話型 API などでは、これがそのままユーザー体験の悪化につながります。

従来はこれを避けるために、プロビジョンド同時実行数で環境を事前に確保したり、定期的に関数を呼び出してウォーム状態を維持する(ウォームアップ)といった、追加コストや作りこみを要する対策が取られてきました。Java関数の場合GraalVMを使ってJava関数をネイティブ実行ファイルへ変換するテクニックなどが使われていました。

SnapStart は、この初期化コストの解決策として登場した機能です。考え方は以下の様にシンプルです。

  1. デプロイ時に一度だけ初期化する: 関数のバージョンを発行するタイミングで、初期化まで済ませた実行環境の状態を用意します。
  2. スナップショットを取得してキャッシュする: その初期化済みのメモリ・ディスク状態をスナップショットとして保存します。
  3. 呼び出し時はスナップショットから復元する: 実際のリクエストでは、ゼロから初期化するのではなく、キャッシュ済みのスナップショットを復元して再開します。

これにより、毎回の初期化を省略でき、起動時間を数秒からサブ秒(1秒未満)レベルまで短縮できます。

2022年11月(re:Invent 2022)にまず Java(Corretto 11) 向けに SnapStart が発表されました。Java 関数の起動を最大10倍高速化でき、追加料金なしで利用できることが大きな特徴でした。その後、2024年11月(re:Invent 2024)Python と .NET にも対応が拡大しました。

SnapStart を使う場合、いくつかの注意点があります。

  • バージョン発行が前提: SnapStart は発行済みの関数バージョン(およびそれを指すエイリアス)でのみ利用でき、$LATEST では使えません。
  • 一意性(uniqueness)への配慮: 1つのスナップショットが複数の実行環境で使い回されるため、初期化時に生成した「環境ごとに一意であるべき状態」(DB コネクション、乱数シード、一時的な識別子など)がそのまま共有されてしまう恐れがあります。これに対応するため、スナップショット取得前(before-snapshot)や復元後(after-restore)に処理を差し込むランタイムフックが用意されています。接続の張り直しや乱数の再シードは、この後者で行う必要があります。
  • 一部機能とは併用不可: プロビジョンド同時実行数、Amazon EFS、512MB を超える一時ストレージ(ephemeral storage)とは併用ができません。

今回のアップデート ― コンテナイメージ × SnapStart

2026年9月2日、AWS は コンテナイメージとしてパッケージされた Lambda 関数でも SnapStart を利用できるようになったことを発表しました。

これまで SnapStart は、マネージドランタイム(Java・Python・.NET)で ZIP パッケージを使う場合が対象で、コンテナイメージには適用できず、「SnapStart を使いたいなら ZIP にする」という選択を迫られる場面がありました。今回のアップデートで、その制約が解消されます。

コンテナイメージは組織のコンテナ標準に合わせやすく、最大 10GB の依存関係をまとめられる一方で、イメージが大きくなるほど、レイヤーのダウンロードやランタイム・アプリケーションコードの初期化に時間がかかり、起動に数秒を要することがありました。SnapStart はまさにこの初期化コストを肩代わりする仕組みなので、大きなコンテナイメージほど恩恵が大きいと言えます。機械学習の推論や対話型 API のような、レイテンシに敏感なワークロードでの効果が期待されます。

SnapStart 対応ランタイムの AWS ベースイメージはJava 11+ / Python 3.12+ / .NET 8+に対応していますが、カスタムベースイメージを使うことで従来SnapSnartには対応していなかった、Node.js、Ruby なども新しくSnapSnartに対応させることができるようになります。

さっそくやってみる

ではまず基本形となるSnapStart 対応ランタイムの AWS ベースイメージを使ってPythonベースのコンテナイメージを用いたSnapStartをやってみます。

まず3つのファイルを作成します。

import sys
def handler(event, context):
    return 'Hello from AWS Lambda using Python' + sys.version + '!'
boto3
FROM public.ecr.aws/lambda/python:3.12

COPY requirements.txt ${LAMBDA_TASK_ROOT}
RUN pip install -r requirements.txt

COPY lambda_function.py ${LAMBDA_TASK_ROOT}

CMD [ "lambda_function.handler" ]

ではLambda用Dockerイメージをビルドします。

docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .

次にECRでイメージレジストリを作成し、上記で作成したイメージをPushしておきます。

# 認証
aws ecr get-login-password --region ap-northeast-1 \
  | docker login --username AWS --password-stdin 917561075114.dkr.ecr.ap-northeast-1.amazonaws.com

# リポジトリ作成(関数と同じリージョンに)
aws ecr create-repository --repository-name hello-world --region ap-northeast-1 \
  --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

# タグ付け & プッシュ
docker tag docker-image:test 917561075114.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world:latest
docker push 917561075114.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world:latest

917561075114 はAWSアカウントIDです。みなさんの環境ごとに置き換えてください。

次にLambda関数用IAMロールを作成します。

cat > trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "lambda.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
aws iam create-role \
  --role-name lambda-ex \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy \
  --role-name lambda-ex \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

ではECRイメージをもとにLambda関数を SnapStart付きで作ります。

aws lambda create-function \
  --function-name hello-world \
  --package-type Image \
  --code ImageUri=917561075114.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world:latest \
  --role arn:aws:iam::917561075114:role/lambda-ex \
  --snap-start ApplyOn=PublishedVersions \
  --region ap-northeast-1

数分待ってバージョンを発行します。SnapStartではバージョンが必須で Latest では指定が行えません。

aws lambda publish-version --function-name hello-world --region ap-northeast-1

では発行済バージョンを実行します。さらに数分待ってバージョンが発行された以下を実行します。

aws lambda invoke --function-name hello-world:1 --region ap-northeast-1 response.json
cat response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "1"
}
"Hello from AWS Lambda using Python3.12.14 (main, Sep  3 2026, 02:51:04) [GCC 11.5.0 20240719 (Red Hat 11.5.0-5)]!"

発行済の関数は以下で確認できます。

aws lambda get-function-configuration \
  --function-name hello-world:1 --region ap-northeast-1 \
  --query 'SnapStart'
{
    "ApplyOn": "PublishedVersions",
    "OptimizationStatus": "On"
}

OptimizationStatusOnとなっています。これがSnapStartが有効化されていることを意味しています。

Written by
編集部

亀田 治伸

Kameda Harunobu

  • Facebook->
  • X->
  • GitHub->

Share

Facebook->X->
Back
to list
<-