Skip to content
Latchkey

コンテナとは何か? 完全な VM なしの分離

コンテナは分離されたプロセスです。アプリと依存関係が、ホストのカーネルを共有しつつ、独自のファイルシステム、ネットワーク、リソース制限を持ちます。

コンテナは、コードと必要なものすべてを 1 つのポータブルな単位にまとめることで、「自分のマシンでは動く」問題を解決します。仮想マシンとは異なり、コンテナはオペレーティングシステム全体を持ち運ぶわけではありません - ホストのカーネルを借り、必要な部分だけを分離します。そのため、コンテナは小さく、起動が速く、CI が依存する使い捨て環境に最適です。

分離が実際に意味するもの

Linux では、コンテナはカーネルがネームスペース(ファイルシステム、プロセスツリー、ネットワーク、ユーザーの独自のビュー)と cgroups(CPU、メモリ、I/O の制限)を使って囲い込んだ、ただの通常のプロセスにすぎません。内部では、そのプロセスはマシンを独占していると思い込んでいますが、外部から見れば数ある中の 1 つのプロセスです。

コンテナ vs 仮想マシン

VM はハードウェアを仮想化し、独自のカーネルを持つ完全なゲスト OS を実行するため、重く、起動には数秒から数分かかります。コンテナはホストのカーネルを共有するため、軽量でミリ秒単位で起動します。トレードオフは次のとおりです。VM はより強い分離を提供し、コンテナは高い集約度と速度を提供します。

コンテナの中身

  • アプリケーションのバイナリ、または解釈実行されるコード。
  • リンクするランタイムとシステムライブラリ。
  • image に焼き込まれた設定ファイルと環境のデフォルト値。
  • それ以外は何もなし - カーネルはなく、理想的には不要なシェルやパッケージマネージャーもありません。

なぜ CI はコンテナを好むのか

すべての CI job は、クリーンで同一の環境を求めます。コンテナはまさにそれを提供します。同じ image が、ラップトップでも、runner でも、本番環境でも同じように動作します。build は再現可能になり、ある job が次の job を汚染する状態を残すことはできません。

手短な例

docker run --rm -it python:3.12 python -c "print(1+1)" を実行すると、Python の image を pull し、コンテナを起動し、2 を出力し、コンテナを削除します - すべてホストの Python に触れることなく行われます。--rm フラグはこれを一時的なものにし、まさに CI が望む性質を実現します。

CI におけるコンテナ

CI プロバイダーは各 job を新しいコンテナまたは VM で実行し、その後に破棄します。そのため、pipeline は毎回クリーンな状態で始まります。それらの container image の build はコールドな runner では遅くなることがあります。マネージド runner(Latchkey など)は、温まったレイヤー cache で image の build を高速化し、一時的な registry の不調を自動的にリトライします。

重要なポイント

  • コンテナはホストのカーネルを共有する分離されたプロセスであり、ミニ VM ではありません。
  • ネームスペースが分離を提供し、cgroups がリソース制限を提供します。
  • コンテナは起動が速く再現性があり、それが CI がコンテナに依存する理由です。

関連ガイド