Dev Study
AWSサービスの内部原理 コース

16. Lambdaは小さな仮想マシンで動く — Firecrackerと多層隔離

「サーバーレス」の裏側で関数がどこで・どう隔離されて動くのかを、Worker→microVM→カーネル機構→運用ポリシーの4層で図解します。

① 関数はどこで動く? — Worker上のmicroVM

WorkerEC2ベースのホスト = 物理サーバー1台
Firecrackerで数千個を高密度に搭載
microVM
microVM
microVM …
数千個が同居
1対1で対応
実行環境execution environment

関数コードはEC2ベースのホスト「Worker」の上で動き、実行環境1つはFirecrackerのmicroVM 1つと必ず1対1で対応する。「実行環境1つ=microVM1つ」と覚える。

② Firecrackerが軽い理由 — デバイスを最小限に絞る

ふつうの仮想マシンOS・デバイスを丸ごとエミュレート
起動 数十秒 / 1ホストに数百個も載らない
Firecracker microVM仮想NIC・ブロックデバイス・タイマー程度だけ
起動 約125ms / 1Workerに数千個

ふつうのVMはOSやデバイスを丸ごとエミュレートするので重い。Firecrackerはデバイスを最小限に絞ることで、起動約125ミリ秒・1Workerに数千個という密度を実現した。

③ なぜコンテナではなくVMか — カーネルの壁を1枚挟む

コンテナnamespace + cgroupで隔離
ホストのLinuxカーネル1つを全員で共有
仮想マシン(Lambdaの選択)KVM + Firecracker
実行環境ごとに独立したゲストカーネル
マルチテナントでの帰結
脆弱性1つが全テナントに波及
ハードウェアレベルの境界で遮断
  • KVM = Linuxカーネルに組み込まれたハイパーバイザ。CPUの仮想化支援機能でゲストに独立カーネルを与える
  • マルチテナント環境では他人のコードが同じ物理サーバー上で走る、が前提

コンテナはホストのカーネル1つを全員で共有するため、カーネルの脆弱性1つが全テナントに波及しうる。LambdaはKVM上のFirecrackerで実行環境ごとに独立カーネルを与え、この最悪ケースを塞ぐ。

④ jailerの多層防御 — VMの壁の内側にもう一枚

攻撃者がゲストカーネルを突破最悪ケースを想定
それでも jailer が阻む
chrootFSの根を付け替え
namespacePID・ネットワーク分離
権限降格実行ユーザーを格下げ
seccomp-bpfシステムコールを制限
到達できない
ホストのLinuxカーネルdefense in depth で守られる
  • jailerはcgroupsによる資源制限も行う
  • Workerホスト間・実行環境間のネットワーク遮断にはiptablesやルーティングテーブルも使われるが、これはjailerではなくLambdaがWorkerレベルで足す別レイヤー

万一ゲストカーネルを突破する攻撃があっても、microVMのプロセス自体がjailerで閉じ込められているため、ホストのカーネルには触れられない。部品はすべて既習のLinuxカーネル隔離機構だ。

⑤ 共有ポリシー — 1つの実行環境は誰とも交わらない

実行環境 = microVM 1つ
常に専用
単一アカウントアカウント間で共有しない
単一関数関数間でも共有しない
同時1リクエスト並行処理は環境を分ける
使い終わったら
別の実行環境に作り直さない古くなればWorkerごと入れ替え
  • warm(解凍)状態での再利用はある。ただし同じ関数・同じアカウントの範囲内だけ
  • だからメモリや /tmp の残データが別テナントに見えることがない

1つの実行環境は常に単一アカウント・単一関数専用で、同時に1リクエストしか処理しない。microVMは別の実行環境として作り直されないため、前の呼び出しの残データが他テナントに漏れることは原理的に起きない。

⑥ 全体像 — 隔離の4層とテナント分離モード

Worker物理サーバー
その上に
KVMによるmicroVMVMの壁
その内側で
jailernamespace / cgroup / seccomp / chroot
さらに
運用ポリシー1環境1リクエスト・microVM再利用なし
  • さらに明示的に分けたいときはテナント分離モード: 新規作成時に --tenancy-config '{"TenantIsolationMode": "PER_TENANT"}' を指定(既存関数には後付け不可)
  • 呼び出し時は invoke に --tenant-id を付けると、同一関数内でもテナントIDごとに実行環境が分かれる

Lambdaの隔離は「物理→VMの壁→カーネル機構の多層防御→運用ポリシー」の積み重ね。サーバーレスの裏側は、仮想化とカーネル隔離という基礎が幾重にも折り重なった構造だ。

サンプルコード(フレームワーク環境が必要なため表示のみ)

# テナント分離モードを有効にして関数を新規作成(既存関数には後付け不可)
aws lambda create-function \
    --function-name image-analysis \
    --runtime nodejs24.x \
    --zip-file fileb://image-analysis-function.zip \
    --handler image-analysis-function.handler \
    --role arn:aws:iam::123456789012:role/execution-role \
    --tenancy-config '{"TenantIsolationMode": "PER_TENANT"}'

# 呼び出し時にテナントを指定(テナントごとに実行環境が分かれる)
aws lambda invoke \
    --function-name image-analysis \
    --tenant-id blue \
    response.json
公式ドキュメントで詳しく ↗