Dockerを支える技術①「コンテナ仮想化」
ここまで、Dockerの「軽さ」と「使いやすさ」を紹介しました。では、そんなDockerは、どのような技術を使って実現されているものなのでしょうか。
Dockerは、主に2つの要素技術から成り立っています。1つはコンテナ仮想化の技術、もう1つはUnion File Systemです。
最初に、コンテナ仮想化について説明しましょう。コンテナ仮想化は、OSを通して使用できるコンピュータリソースをコンテナごとに隔離して、ホストOS上で直接動作するプロセスや他のコンテナから独立した空間を作り出し、リソースを分割、分配、制限する技術です。
「コンテナ」自体は新しい技術ではありません。OSのカーネルが持つ機能を利用しています。
コンテナ仮想化を実現するために主に使用されているカーネルの機能が、namespace(名前空間)とcgroupです。
namespace
namespaceは、ユーザープロセスが動作する空間を分離する機能です。分離された空間は、それぞれが独立した名前空間を持っています。
Dockerでは、カーネルが持つ次のnamespaceの機能を使用しています。名前空間はコンテナの起動時に作成され、各コンテナは独自の名前空間を持つようになります。
- PID Namespace(プロセステーブルの分離)
- Net namespace(ネットワーク設定の分離)
- UTS namespace (ホスト名の分離)
- IPC namespace(プロセス間通信の分離)
- Mount namespace(ファイルシステムの分離)
- User namespace(ユーザーの分離)
これらのうち、本記事ではPID namespaceとNet namespaceについて説明します。
PID namespace
プロセステーブルの分離を行う機能で、kernel 2.6.24で実装されています。隔離された空間の中では、それぞれが独自のプロセスIDを持つことができます。したがって、同じホスト上であっても、異なるコンテナにおいては同じプロセスIDを使用できます。
一方で、コンテナ外の名前空間のプロセスIDを知ることはないため、他のコンテナ内のプロセスやホストのプロセスに対し、プロセスID(PID)を指定してシステムコールを実行することはできない仕組みになっています。
ただし、各コンテナのプロセスIDは、ホストOSから見えるプロセスIDとしてマッピングされているため、ホスト内からコンテナ内のプロセスに対し、システムコールを実行することが可能です。
Net namespace
ネットワーク空間を分離する機能で、kernel 2.6.24で実装されています。PID namespaceと同じく、隔離された空間の中では、それぞれが独自のプロセスIDを持つことができるため、loopback addressや、eth0など、各コンテナで共通の名前が付与されています。
ポート番号も各コンテナ間で独立しているため、同じポートを利用してもポートがバッティングすることはありません。
cgroups(control groups)
コンテナ仮想化を実現するもう一つの機能が、cgroupsです。cgroupsはプロセスをグループ化し、グループ内に存在するプロセスに対して共通の管理を行うカーネルの機能です。ホストOSが持つCPUやメモリなどのリソースに対して、グループごとに制限をかけることが可能です。
Dockerでは、コンテナの起動時にリソースのグループを作成して、グループごとにリソースの使用制限をかけています。
cgroupは、cgroupファイルシステム(以下、cgroupfs)という仮想的なファイルシステムを使って操作します。
cgroupファイルシステムは、カーネルのパラメータの値の閲覧、変更時に操作を行う際に、/proc以下のファイルを扱うのと同じような仕組みです。/sys/fs/cgroup以下にマウントされており、次の図のような構造になっています。
cgroupファイルシステムの構造
- /sys/fs/cgroup以下では、メモリやCPUといったサブシステムごとにリソースが管理されています。
- 各サブシステムの下には「Docker」というディレクトリが作成されており、1つのグループとして管理されています。
- Dockerディレクトリの下には、さらに各コンテナのリソースを管理するグループが作成されています。
- 各グループのディレクトリの下には、コンテナ内のプロセス群のリソースを制御するファイルが作成されています。
例えば、「CPUリソースの制限を行うCPUサブシステム内にある“cpu.shares”というファイル」の中をcatコマンドで出力してみると、CPUを全体のどれくらい割り当てるかという値(次の図では1024)を確認できます。