はっきりさせよう: コンテナーはVMではない

この記事はBob Reselmanによるゲスト投稿です。

Linuxコンテナーはただの軽量仮想マシン(VM)だというのはよくある誤解です。これは事実ではありません。LinuxコンテナーはVMと共通する機能を多数備えているように見えますが、この2つはアーキテクチャ的に異なります。開発者やテスト技術者は、この違いを知っておいて損はありません。

コンテナーとVMはどのように異なるか、それぞれの利点と危険を説明しましょう。

コンテナーはLinuxのファイルシステムと緊密に結び付いている

コンテナーとVMの本質的な違いは、VMはホストマシンから独立したカーネルを持っていますが、コンテナーはホストマシンのカーネルを使用するという点です。(図1を参照)。

カーネルはOSの最下層にあり、コンピューターとやりとりします。カーネルはコンピューターで実行されるアプリケーションの実行モジュールとコンピューター自体を仲介します。カーネルはマシンとやりとりし、サービスやサーバーとして認識されるプロセスがプロセス間通信(IPC)を使用して互いに情報を取得できるようにします。

カーネルはディスクI/O、ネットワークトラフィック、ストレージを管理します。事実上、カーネルがマシンを動かしていると言えます。

図1: 仮想マシンは独自の仮想カーネルを持つ別個のコンピューターであるいっぽう、コンテナーはホストシステムのカーネルを使用します。

独自のカーネルを持っているか、ホストのカーネルを使用するかは重要です。なぜなら、この違いによって、VMはホストのOSとは異なるOSを実行できるからです。LinuxホストシステムはWindowsなど他のOSを実行するVMをサポートしますが、Linuxホストで実行されるコンテナーはLinuxを実行する必要があります。

また、VMにはホストマシンから独立した仮想ファイルシステムがありますが、コンテナーはホストマシンのファイルシステムを使用します。

では、コンテナーがホストのカーネルとファイルシステムを使用しているなら、どうしてVMのような独立したコンピューティングユニットに見えるのかという疑問を持たれるかもしれません。答えは、コンテナーはLinuxOSを構成する3つの基本的な分離メカニズムを利用しているからです。

1つ目のメカニズムはネームスペースです。ネームスペースは、コンピューターのアクセスとアクティビティを局所化するLinuxの分離機能です。たとえば、特定のユーザー用のネームスペースを作成し、そのネームスペースにプロセスなどのコンピューターリソースへのユニークなアクセスを割り当てます。すると、コンピューターで多数のプロセスを実行しながら、特定のプロセスをあるネームスペースに割り当て、別のプロセスのセットを異なるネームスペースに割り当てることができます。最初のネームスペースのプロセスは、仕組みとして他のネームスペースのプロセスを意識しません。

2つ目のメカニズムはcgroupです。cgroup(control groupの略)はLinuxのリソースに制限をかける機能です。たとえば、1つのプロセスが使用できるCPUの割合を制限するcgroupを作成できます。

3つ目のメカニズムはUnionFSです。このサービスを使用すると、コンテナーのファイルシステムは独立したリソースのように見えるいっぽうで、実際にはホストのファイルシステムを共有します。これは特に、コンテナー内の実行モジュール(たとえばMySQLなど)を表すコンテナーレイヤーにとって重要です。

複数のコンテナーが1つのアプリケーションをそれぞれ固有のファイルシステムで実行しているように見えるいっぽうで、背後ではアプリケーションごとにベースとなるファイルのセットがあり、さらにコンテナー固有のオーバーレイファイルのセットがあります。これらオーバーレイファイルはコンテナーの書き込みレイヤーと呼ばれます。結果として、コンテナーのアプリケーションがrootユーザーによって制御されたファイルシステムの一部に書き込みを行っているように見えるとき、実際は、コンテナーのために用意されたホストOSファイルシステムの書き込み可能なエミュレーションに書き込んでいるのです。

これら3つの機能をまとめると、コンテナーになります。コンテナーの作成、運用、管理の調整に伴うすべての作業は、ホストマシンで実行されるサービスであるコンテナーランタイムエンジンによって行われます。

最もよく知られたコンテナーランタイムエンジンはdockerdですが、ほかにrktcontainerdなどもあります。

メリットと危険性

簡単に言えば、仮想マシンは物理的ホストで実行されるコンピューターを完全にソフトウェアで表現したものです。1つのホスト上で多数のVMを実行できます。各VMは固有の仮想カーネルを持つため、固有のファイルシステムとCPU、さらに固有のネットワークとディスク装置を持つように見えます。

コンテナーはVMと似た動きをする分離されたユニットですが、ホストのカーネルや、その他のホスト上のシステムを使用します。VMはホストから独立しているように見えますが、コンテナーはホストの上で実行されます。

仮想マシンと比較したコンテナーの本質的なメリットは、コンテナーはメモリへのロードが非常に高速であることです――必要な準備を行えば、ミリ秒単位です。VMをホストにロードするのは、はるかに時間がかかります。高速なロードという特長があるため、インスタンスをオンデマンドでほぼ即時にスケールさせる必要がある分散アプリケーションのデプロイメントユニットとして、コンテナーは最適な選択肢です。これがKubernetesDocker Swarmなどのコンテナーオーケストレーション技術が普及した理由です。

コンテナーの最大のリスクは、コンテナーがホストの上で実行され、ホストのカーネルにアクセスできることです。root 権限で実行されているコンテナーは、ホストマシンに大きな被害を与える可能性があります。これは本当に脅威です。いっぽう、VMでrootとして実行すると、VM自体に問題を引き起こすことはありますが、不正な操作がホストマシンにまで影響を及ぼすことはまれです。仮想マシンのハイパーバイザー技術が中間に入って適切に処理します。

コンテナー技術でもうひとつ考慮すべき問題は、コンテナーを連携させ、データを共有するとなると、知るべきことが多くなる点です。たとえば、Dockerを使用するアプリケーションをDockerコンテナーにホストするには、Dockerについていろいろなことを知る必要があります。ここにある私が作成したコンテナーのサンプルは、Jenkinsサーバーを実行し、CI/CDプロセスの一環としてホストのDockerインスタンスを使用してコンテナーを作成します。

コンテナーオーケストレーション技術がコンテナー間通信管理のかなりの部分を肩代わりしてくれるのは事実ですが、「あとで大きなつけがやってくる」という面もあります。いずれ、ただアプリケーションを起動し、単純なHello World以上のことを実行させるために、コンテナーについていろいろと学ぶ必要が出てくるでしょう。

VMでは、いったんうまくいけば、デスクトップシステムでアプリケーションを起動し、実行するために必要な知識以外には、それほど知る必要はないでしょう。デメリットは、習得が容易な反面、不利益もあることで、その不利益というのがスピードです。

まとめ

コンテナー技術について言うべきことはたくさんあります。仮想マシンが提供する分離という利点をすべて備えているうえに、ロードのスピードが向上します。しかし、トレードオフもあります。仮想マシンでは、VMを起動して実行すれば、あとは通常どおり使うだけです。コンテナーは開発者やテスト技術者にとって、より複雑な技術です。

また、注意していないと、コンテナーは多大なセキュリティリスクをもたらします。しかし、昨今の技術シーンでコンテナーがこれほど普及していることを考えても、コンテナーセキュリティのベストプラクティスを実現するには、インターネットを小一時間検索し、積極的に正しい対応をするという以上のことが求められます。実際、コンテナーセキュリティをめぐって一大産業が台頭してきています。

仮想マシンでも、コンテナでも、その両方でも、どんな技術を選ぶにせよ、重要なことは、どちらの技術も独立し、分離された大規模なコンピューティングを可能にするが、2つは同じではないのを理解することです。コンテナーは軽量仮想マシンではありませんし、仮想マシンはコンテナーではありません。ユニークな違いがあり、その違いを知ることが重要です。

筆者のBob Reselmanについて:全国的に著名なソフトウェア開発者、システムアーキテクト、業界アナリスト、テクニカルライター/ジャーナリスト。コンピュータープログラミングに関する書籍のほか、ソフトウェア開発テクノロジーおよびテクニック、ソフトウェア開発カルチャーに関する記事を多数執筆。元Cap GeminiのPrincipal ConsultantおよびコンピューターメーカーGatewayのPlatform Architect。ロサンゼルス在住。現在は、ソフトウェア開発およびテスト活動のかたわら、自動化が雇用に与える影響に関する書籍を執筆中。連絡はLinkedInwww.linkedin.com/in/bobreselmanまで。

(この記事は、開発元Gurock社の Blog 「Once and for All: Containers Are Not VMs」2020年3月12日の翻訳記事です。)

eBook 公開中

Paul Gerrard著 効果的なテスト管理12の秘密 (日本語)

テスト計画やテスト管理に役立つ12のトピックを解説します。

詳細はこちら