コンテナイメージを全部受け取る前に実行する方法: AWS SOCI を読み解く
(medium.com/@mintplo)コンテナイメージを「全部受け取る前に実行」できるようにする AWS SOCI(Seekable OCI)の内部動作を、HTTP Range Request / FUSE / zTOC(インデックス)の観点から解説した記事です。
導入の背景(Slacker 論文から得られたインサイト)
- Slacker: Fast Distribution with Lazy Docker Containers(USENIX FAST ’16)は、コンテナの「cold start」がなぜ遅いのかをまず計測
- HelloBench というベンチマークを作成し、57 個のコンテナワークロードについて「デプロイ開始 → 意味のある作業(サービス準備)が可能」になるまでの時間を測定
- 観察 1)起動時間の大部分は「イメージ/パッケージの pull + コピー」に使われる
- pulling packages(パッケージ/イメージデータのコピー)がコンテナ起動時間の 76% を占める
- 観察 2)しかし起動直後に実際に読むデータは全体のごく一部
- pull/コピーされたデータのうち平均 6.4% だけが「コンテナが意味のある作業を始める前」に実際に read される
- 観察 3)イメージには思った以上に「共有/重複」が多い
- イメージ単位の gzip 圧縮よりも、イメージ間で共通ブロックを見つける単純な block-level dedup のほうが、より高い圧縮効果を示したと報告
- 結論(問題意識): 「すべてをダウンロードしてから実行」する方式は無駄が大きく、
起動に必要なものだけを先に取得して(優先実行)、残りは必要になった時に取得する(lazy)方式が有効でありうる - これらの観察をもとに Slacker という Docker storage driver を設計
- すべての Docker worker/registry が中央ストレージを共有し、バックエンドストレージの snapshot/clone を使ってファイルシステムのプロビジョニングコストを削減
- コンテナデータは「必要な時」に lazily fetch し、その結果 push/pull および開発/デプロイサイクルを大幅に短縮したと報告
SOCI Snapshotter(AWS)
- SOCI snapshotter README でも、Slacker(FAST ’16)の「76% vs 6.4%」という観察を、レイジーローディングが有効である根拠として直接引用
- Slacker が「Docker driver + 特定ストレージ(サーバー)機能」に強く依存するアプローチだったのに対し、
SOCI は OCI エコシステムで使うため、これを「レジストリ(ECR など)での lazy loading」へ一般化した形 - SOCI はコンテナ実行時にイメージ全体を受け取るのではなく、
別途インデックス(zTOC / Index Manifest)でファイル位置/スパン情報を確保したうえで必要な断片だけを先に取得し(on-demand)、起動を前倒しし、
残りはバックグラウンドで継続的に prefetch するハイブリッド戦略を取る
SOCI の主要構成要素
- HTTP Range Request: レジストリ(ECR)から必要なバイト範囲だけを 206 Partial Content で取得
- zTOC: ファイルオフセット/メタデータ + 圧縮チェックポイント(zInfo)により「途中から」展開可能にする
- FUSE: レイヤーをファイルシステムのようにマウントして open/read をフックし、必要な span(デフォルト 4MB)を on-demand で fetch
動作フロー(ECS Fargate 基準)
- インデックス(manifest)確認 → zTOC ダウンロード → FUSE マウント → コンテナ実行
- ファイルアクセス時には該当 span だけを Range Request で即座にダウンロード/展開して返却
- 同時にイメージ全体はバックグラウンドで継続的にダウンロードする「ハイブリッド」戦略
制約/トレードオフ
- インデックス/マウントのオーバーヘッドにより、小さなイメージ(例: 250MB 未満)では不利になる可能性
- 効果はイメージサイズよりも「初期のファイルアクセスパターン」に敏感
- span サイズ(リクエスト数 vs 不要なダウンロード)の調整余地や、LOD(Load Order Document)のような改善方向にも言及
まだコメントはありません。