今回は、コンテナがどのような仕組みで作られているかを紹介していく。そのため、これまでよりも技術的な内容が含まれているが、すべてを深く理解しなければコンテナを扱えないというわけではないので恐れずに読み進めてほしい。

ここで紹介する内容は、コンテナが関係するすべての詳細な解説というよりは、序盤で理解しておくべき必要最低限の技術要素がわかる程度にしている。

今はその程度であったとしても、ICTエンジニアとしてはただ利用するよりも仕組み(アーキテクチャ)を知っているほうが、何をするにも深みのある活動につながることは間違いないであろう。

仮想化観点から見たLinuxベースのコンテナの仕組み

これまで見てきたように、コンテナの仕組みは「ホストOSのカーネルを共有する」点が重要になってくる。そして、現在はホストOSがWindowsやLinuxにかかわらず、コンテナを利用することができるようになってきている。OSはそれぞれ構造が異なるため、コンテナを構成する場合もやはり細かなところは異なってくる。

本稿では、ホストOSとしてLinuxを前提とし、その上でコンテナを利用する場合の構造を紹介する。

第3回で解説したように、コンテナには仮想化の技術が採用されている。どのような部分が"仮想化"されているのだろうか。以下、「コンピューティング」「ストレージ」「ネットワーク」の3つの観点からその仕組みを見ていくことにする。

コンテナの「コンピューティング」

第2回で説明したように、コンテナには「アプリケーション・ライブラリ・ミドルウェア」といったものが含まれている。これはコンテナの"中身"である。"コンテナ"というからには、この"中身"がコンテナ外部や他のコンテナとは隔離、分離されており、それぞれの要素を個別に稼働させるための仕組みが必要である。

アプリケーション、つまりプロセスを稼動させるということは、CPUやメモリといった物理的なリソースの割当も必要である。ここがいわゆるコンテナのコンピューティングのコアとなるところである。

Linuxカーネルにはnamespaces、cgroups呼ばれる機能が実装されており、これによりホストOSや他のコンテナと隔離し、リソース割当、制御することが可能となっている。

具体的に、cgroupsは物理的なリソースであるCPUやメモリを制御する。そして、namespacesはプロセスに対して以下の6種類のリソースを分離するための機能として提供する。

namespace 概要(分離する対象)
IPC System V IPCオブジェクト、POSIXメッセージキュー
Network ネットワークデバイス、IPアドレス、ルーティングテーブル、ポートなど
Mount マウントポイント
PID プロセスID
User ユーザー&グループID
UTS ホスト名、NISドメイン名

OSの構造を詳しく説明しているわけではないので、上記の表がそれぞれ何を示しているかがわからない読者も多いかもしれない。ここでは、コンテナとして他と分離されたいくつかの専用の空間が用意されている、というくらいの認識で構わない。

コンテナの「ストレージ」

先のセクションで、"中身"である「アプリケーション・ライブラリ・ミドルウェア」はコンテナがデータとして保持している、と述べた。コンテナはこのデータの取り扱い方が特徴的である。

コンテナを起動するには、まずこのコンテナの"中身”を保有する大元のデータの塊を作る。これをコンテナイメージ(下図3)と呼ぶ。コンテナを起動する際はこのコンテナイメージのスナップショットのような領域(下図1)が切り出され、アプリケーション(プロセス)が起動する。その後に書き込まれるデータはそのスナップショットの差分データとして別の領域(下図2)に保持される。この時、コンテナイメージ、つまり大元のデータの塊は変更されない。また、この差分データは一時的なものとして存在しており、コンテナが停止した後はスナップショットごと消えてなくなる。

なお、前述のようなコンテナ上でデータの取り扱われる表現はできるだけわかりやすくしたものであり、実際この実装は、devicemapper、aufs、overlayfsといった機能により提供されている。

コンテナ起動時にコンテナイメージが変更されないのは、読み込み専用として存在しているためであり、これは共有可能となっている。ここにはnamespacesの"マウントポイント"機能が働いており、1つのコンテナイメージから複数コンテナを起動させること、コンテナの作成(起動)と削除(停止)を繰り返し行うことができるようになっている。

これは、第4回においてコンテナの特徴として挙げていた「儚い」に当たるImmutable Infrastructureを想定した仕組みとして捉えられる。

コンテナの「ネットワーク」

コンテナが起動した後、そのアプリケーションは一般的にはコンテナ外との通信を行うことになる。よって、いわゆるネットワークインタフェースが必要となるのは想像できるだろう。

ネットワークインタフェースにはIPアドレス、またアプリケーションにアクセスするためにはポートの付与が必要である。コンテナ起動時にこれらも関連付けられる。これらは、ホストのOSとは別のネットワークに対して付与されるが、ホストの中のコンテナとホストの外との通信も正しく行うことができる。なぜなら、下図のように、独自に作成されたコンテナ内ネットワークと外部との通信を行うためにフォワーディングをしているからである。

上図では、コンテナ(1)でWebサーバが公開されていたと仮定し、外部ネットワークからそのWebサーバにアクセスする場合は、ホストOSの10.0.0.1:80にアクセスすることで、その通信はコンテナ(1)(172.16.0.1:8080)に転送されて通信が行われることになる。

なお、上記の通信は一番シンプルなコンテナと外部との通信の仕組みである。コンテナ間の通信や、外部(ホストOS外)との通信はこの仕組みに加えてさまざまな方式が組み合わさって行われることになる。

例えば、ホストOSを複数束ねてクラスタを組んだ場合のコンテナ間通信ではコンテナで立ち上げるサービスに冗長性を持たせるし、複数のコンテナで負荷分散を行う場合はオーバレイネットワークやプロキシなどの仕組みが使われる。

以上がコンテナの仕組みの概要となる。昨今のコンテナ技術はLinuxをベースとすると、ほぼすべてといっていいほどオープンな技術の組み合わせで構成されているため、本稿よりも詳細に解説しているWebの記事、書籍の文献は数多くある。仕組みやアーキテクチャに興味を持った場合は、資料をいくつも読み比べて見ることも大事である。また、仕組みはアップデートされる場合もあるため、継続した研鑽が大事である。

「コンテナの活用」といってもそのプラットフォームやプロダクトは現在多くのものが存在している。オープンな技術を用いて自身で作れるものから、ある程度サービスプロバイダーにまかせてしまえるものまでさまざまである。次回は、これらの選択肢について紹介する。

著者プロフィール

倉持健史


2001年4月からSPARC/Solaris , IA/Linux を中心としたSIに従事。その後、商用HAクラスタソフトウェアの開発からトレーナー・サポート・プリセールス・エバンジェリストと幅広く活動。
事業継続に関連したデータ保護の観点から外資系ストレージベンダにわたりパートナー・顧客のプリセールスを実施する傍ら、サイジングレポートツールの開発やOSSと組み合わせたソリューション開発や案件支援活動を行う。同時に、SNIA日本支部教育委員会副委員長として技術セミナーや書籍を執筆。
現在はシステムインテグレーターではあるものの、インフラ技術を横串にOSSを中心とした特にOpenStack、Ansible、Docker、Kubernetesといったトレンド技術要素を自社内エンジニアスキルアップトレーニング、社外でOSS技術のエバンジャライズを行っている。