← 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