コンテナってなんだろう― 「コンテナ」の概要を知る

2020年2月21日(金)
熊田 寛(くまだ かん)

コンテナ誕生までの歴史と
コンテナの成長

前回に引き続き、今回はコンテナが生まれるまでの歴史とコンテナが成長してきた道のりをたどってみたいと思います。

コンテナの歴史は、1979年にchrootが誕生したことから始まります(図1)。chrootとは名前の通り「root(/)ディレクトリ(基準となるディレクトリ)を変える(change)」操作です。

図1:コンテナ技術の進化

操作したディレクトリ(カレントディレクトリ)に、起点となるルートディレクトリが変更されるので、以降はそのディレクトリ配下にしかアクセスできず、外側のディレクトリへはアクセスできなくなります(図2)。chrootには特権を分離してOSを保護する効果があり、主にセキュリティ強化のために用いられています。

このように、まるで外に出られないことからchroot監獄と呼ばれます。

図2:chrootの概念

時は過ぎて、2000年にUnix OSであるFreeBSDがOS仮想化機能FreeBSD Jailを発表します。FreeBSD Jailは、chrootのようにファイルアクセスを制御するのではなく、ホストOSとJailと呼ばれるOS仮想化環境とでファイルシステム、アプリケーションのプロセス、ネットワークを分離できる画期的なものでした。これが、コンテナの原石と言われるものです。

Jailによって利用者ごとに環境を分け、安全性を確保できるようになったことで、いわゆるレンタルサーバやホスティングなどのサービスで用いられるようになりました。

翌年の2001年には、LinuxでもカーネルにLinux-Vserverと呼ばれる機能を追加することでOS仮想化環境を利用できるようになりました。さらに、2004年には商用Unix OSのSolarisでもSolaris Zoneと呼ばれるOS仮想化機能が提供されるようになりました。OS仮想化環境のSnapshot(環境のとある時点を丸ごとコピーしたデータ)取得機能も追加されて、より使いやすいものになりました。

その後に、現在のコンテナの根幹である仕組みが登場します。2006年、Google社によってProcess Containersというプロセスのリソース利用量を制御する機能が発表されました(翌年にはcgroupと改名)。 2008年にはRedhat社が論理的にシステムリソースを分割するNamespaceを発表しましたが、時を同じくして、IBM社がLXC(LinuX Containers)を発表しました。これが、cgroupとNamespaceを組み込んだ最初のLinuxのコンテナエンジンです。Linux上に2つの重要な仕組みが取り込まれたLXCの登場により、以降のコンテナエンジンの形が確立されました。まさに現在のコンテナの原点とも言えるでしょう。

コンテナの構造

コンテナの歴史を振り返ったところで、これまでをおさらいしつつ、コンテナの構造を見ていきます。

前回で、仮想化とは「CPUやメモリなどのハードウェアのリソースをハイパーバイザーというソフトウェアの力で抽象化したもの」と解説しました。この仮想化の仕組みを一般的にハイパーバイザー型仮想化と呼び、仮想化によって作られたサーバを仮想マシンと呼びます。

一方で、コンテナはコンテナエンジンというプロセスを通して、ホストOSの「カーネル」を共有することでCPUやメモリなどのリソースを隔離し、仮想的な空間を作り出します。これをコンテナ型仮想化といいます(カーネルとはOSの最も中核(コア)となる部分)。

ハイパーバイザー型仮想化では、物理サーバにインストールされているOSとは別に、仮想マシン上にも個別にOSをインストールする必要があるため、仮想マシンの起動には物理サーバと同様にOSを起動します。しかし、コンテナでは起動しているホストOSの「カーネル」を共有することでアプリケーションの実行土台を備えることから、コンテナの起動には従来のOSの起動といった工程が必要ないのです(図3)。

図3:仮想化とコンテナの大きな違い

では、そのコンテナがどうやって動いているのか、「構成」「プロセス」「ネットワーク」の3つの観点から、さらに詳しく見ていきましょう。

(A)コンテナの基本構成

コンテナ型仮想化では、その実行基盤としてハードウェアとOSを共有します。コンテナは単一のホストOS上で動作するコンテナエンジン上にプロセスとして存在し、そのエンジンが管理するシステムリソースの範囲内で、複数のコンテナを同時に動作させることができます。

コンテナの中には、ユーザが動作させたい「アプリケーション」と、そのアプリケーションの実行に必要な「ミドルウェア」、そして「ライブラリ」などが含まれます。このライブラリの中にはOSの基本的なコマンドセットやファイルシステムのライブラリなど、OSが提供する機能の一部が含まれています(図4)。

図4:コンテナの基本構成

現在ではさまざまなLinux系OSのコンテナイメージ(ベースイメージなどと呼ばれます)が公開されており、これらを使ってアプリケーションの実行環境を整えることができます。

ここで「あれ? コンテナ型仮想化ではOS起動が要らないっていう話なのに、OSのコンテナイメージは存在するの? それってどういうこと?」と疑問に思った方もいるでしょう。結論から言うと「OSは動作させず、それっぽい動作環境を再現している」のです。これは、コンテナにおけるアプリケーションの起動方法を知ることで理解できるでしょう。

そもそもアプリケーションは、内部でOSの中核であるカーネルの機能を呼び出して動作しています。その代表的な例としてファイルの読み書き(I/O)が挙げられます。このようなカーネルに対する呼び出しをシステムコールといい、カーネルがシステムコールを処理することでアプリケーションを動作させているのです(図5)。実際にはABI(Application Binary Interface)と呼ばれる専用のインターフェース経由でやり取りされます。

図5:コンテナ環境上のアプリケーション動作イメージ

ところで、Linux系と呼ばれるOS群には、RedHat Enterprise Linux(RHEL)やCentOS、Ubuntuなど様々なディストリビューション(各社の配付パッケージ)が存在しますが、基本的に共通のカーネルを使用しています。そのため、アプリケーションの実行に必要なライブラリさえあれば、どのディストリビューションでもアプリケーションを動作できる仕様になっています(図6)。

図6:違う種類のホストOS上でも動くコンテナ

しかしながら、例えばRHELで動作するように作成したアプリケーションをUbuntuで動作させようとする場合、動作環境の違い(ファイルシステムやライブラリなど)により正しく動作しません。この問題を解消するため、OSのコンテナイメージはRHELであればRHEL上でアプリケーションを動作させるために必要な環境を再現します。

ここで注意しておきたいのは、OSのコンテナイメージはあくまでもアプリケーションの動作に必要な環境を「それっぽく」再現しているに過ぎない点です。コンテナの動作に必要なリソースはホストOSからコンテナエンジンを通して間借りしており、コンテナ内のアプリケーションが発行するシステムコールはホストOSで動作しているカーネルが処理します。ハイパーバイザー型仮想化のように個別のOSは存在しないため、コンテナ型仮想化ではLinuxカーネルの互換性に依存します。この点でコンテナ型仮想化はハイパーバイザー型仮想化と異なります。OS固有の機能を含めた動作環境を再現するには、コンテナ型仮想化よりもハイパーバイザー型仮想化を使用する方が良いでしょう。

このように、Linuxにおけるアプリケーション(とその実行環境)を仮想のコンテナとして分離する方式を「Linuxコンテナ」と呼びます。一般にコンテナとは、このLinuxコンテナを指すことが多いです。Linuxコンテナの技術を使用しているコンテナ型仮想化は、そのベースであるLinuxカーネルが持つ高い互換性によって支えられているのです。

(B)コンテナのプロセス

次は、コンテナとプロセスの関係について解説します。

まず、ハイパーバイザー型仮想化における物理サーバと仮想サーバは、それぞれが1つのサーバ環境として位置付けられます。しかし、コンテナ型仮想化におけるコンテナは、ホストOS上からは1つのプロセスとして扱われるという大きな特徴があります(図7)。

図7:ハイパーバイザー型仮想化とコンテナ型仮想化のホストOS上の違い

これは、例えるなら皆さんのパソコン(ホストOS)と、この記事を表示しているブラウザ(プロセス)と同じような関係性と考えてください。

では、コンテナはどのようにしてこれらを実現しているのでしょうか。コンテナはいくつかの要素技術を組み合わせることで実現しています。その中でも代表格ともいえるLinuxカーネル機能のNamespace、Cgroup、Capabilityに焦点を当てて、1つずつ見ていきます。

・Namespace

各プロセスに対してシステムリソースそれぞれをその他のプロセスと分離する役割を担っています。例えば、ユーザIDやホスト名、ネットワークインターフェイスの分離などがあります。この機能によりコンテナAのプロセスとコンテナBのプロセスは隔離されるので、互いに干渉せずにプロセスを稼働できます。

リアルな世界の貨物船のコンテナをイメージすると分かりやすいかもしれません。コンテナには木材や食品など様々な種類の物が詰められています。例え隣り合うコンテナの中に同じ種類の物が入っていても、それぞれがコンテナAの◯◯、コンテナBの◯◯として管理されるということです(図8)。

図8:Namespaceによるプロセス分離のイメージ

・cgroup

プロセスをグループ化し、CPUやメモリなどホストOSの物理的なリソースを分離する役割を担います(図9)。例えば、プロセスが用いるCPUの使用率やメモリの割当、デバイスへのアクセスを制御します。1つの特定のプロセスがCPUやメモリリソースを大量に消費することで、ホストOSや他のプロセスに影響が出るといったリスクをコントロールします。

図9:Cgroupによるリソース分離のイメージ

皆さんもパソコンの作業中に動作が重くなったという経験したことがあると思います。これは特定のプロセスの負荷が高すぎることでホスト(この例ではパソコン)に影響を与えている状況と言えます。cgroupは、コンテナがこのような影響を与えるのを抑制する機能と考えてください。

・Capability

root権限を細かく分けてプロセスやファイルに付与する機能を担います。root権限はスーパーユーザと言われるだけに、システムのほぼ全ての操作が可能となる権限なので、仮にroot権限がそのまま付与されたプロセスに脆弱性があり悪用された場合、システムそのものを他者に乗っ取られてしまう危険性があります。

そのため、Capabilityを用いてプロセスなどに与える権限を最小限に制御することで、仮に実行しているプロセスに脆弱性があったとしてもホストOSやほかのプロセスへの影響範囲をコントロールできます(図10)。

図10:Capabilityによる権限付与のイメージ

コンテナはこれらの要素技術を駆使してプロセスやシステムリソース、権限などを分離し、管理することで1つのプロセスとして実行されるのです。

(C)コンテナのネットワーク

続いて、コンテナとネットワークの関係について解説します。コンテナはどのように通信するのかを紐解く前に、まずは普通の物理サーバの通信方法を見てみましょう。

物理サーバには、物理的なNIC(Network Interface Card)が通信の出入り口として機能します。例えると家の玄関のようなものです。NICに接続したLANケーブルでサーバ同士をつなげば通信自体は実現できますが、膨大な数のサーバを直接つなぐには限界があります。その限界を突破するにはケーブルを集約する集線装置、つまり「スイッチ」が必要になります(図11)。

図11:物理サーバ環境のネットワーク接続イメージ

このことを踏まえた上で、ハイパーバイザー型仮想化における仮想サーバの通信を見てみましょう。前述したように、ハイパーバイザー型仮想化では物理サーバ内に仮想サーバを作り、その上にゲストOSやアプリケーションを構築していきます。

この仮想サーバには仮想NICがあり、IPアドレスやMACアドレスが割り当てられています。仮想サーバから外のネットワークと通信するときは、普通の物理サーバと同様に通信を束ねて管理する「仮想スイッチ」を経由します(図12)。

図12:仮想サーバ環境のネットワーク接続イメージ

一方、コンテナ型仮想化におけるコンテナの通信はどうでしょうか。物理サーバの物理NICとNamespaceで分離されたコンテナ内の仮想NICの間にコンテナエンジンで制御されている仮想ブリッジがあり、コンテナとホストOS間の橋渡しをしています(図13)。

図12:仮想サーバ環境のネットワーク接続イメージ

さらに、ホストOSのNAT(Network Address Translation)機能により、コンテナのIPからホストOSが持つIPへ変換されます。これでコンテナは外部と通信できるようになるわけです。簡単にイメージするなら、とあるマンションに住んでいるとして、ホストOSのIPは住所、コンテナのIPはただの部屋番号に過ぎないと解釈できます。

ここでは物理サーバ、ハイパーバイザー型仮想化、コンテナ型仮想化におけるネットワークを簡単に紹介しましたが、ほかにもネットワーク関連の機器や技術要素は複数存在します。ネットワークは奥が深いので、コンテナにフォーカスした部分のみの説明に止めました。

おわりに

今回は、コンテナの誕生秘話から、コンテナがどのように動いているのかに焦点を当てて解説しました。次回はもう1つの重要なポイントとして管理ツールを取り上げます。もちろん、そこにはあの「クジラ」も登場してきます。

著者
熊田 寛(くまだ かん)
株式会社BFT
営業会社を経て、2017年に株式会社BFTに入社。IT業界に入って業務で扱う領域の広さと深さ、変化の早さに対応するのに奔走していたらもう3年目。
比較的新しいもの好きな面もあってか、ここ暫くは専らAWSに心惹かれている。好きなサービスはECSと EKS、と言いたいところだが、まだまだその深淵に触れたばかり。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています