はじめに
概要
コンテナ技術と仮想マシンの違いについてなんとなく分かっているフリをしていたので、実際にどのような点で違いがあり、メリットデメリットがあるのか調べてみました。
コンテナ側の内容が多めです。
コンテナ技術とは
では、コンテナ技術とはどのようなものかについて見ていきます。
よくコンテナ技術と比較されるのが、仮想マシン技術です。
二つの違いは
コンテナ:「OSレベル」での仮想化技術
仮想マシン:「ハードウェアレベル」での仮想化技術
です。
この図では、
コンテナはubuntuやdebianなどの「OS」とapacheやpythonなどの「アプリケーション」を仮想化しています。
それに対して、仮想マシンでは上記に加えて「カーネル」と「ハードウェア」部分も仮想化しています。
ここでいうハードウェアというのは、CPUやメモリ、ストレージといったPCのリソースを完全にホストOSから独立した状態で割り当てるということです。
特徴
コンテナはOSより上層を仮想化しています。
例えば、ubuntu上にpythonをインストールした状態を仮想化することが可能です。
これを一つのパッケージ化(イメージ化)することで、環境の再利用が可能になります。
PCは物理リソース(CPUやメモリ)を効率よく使用するために、カーネルを使用しています。
コンテナではホストOSのカーネルを利用することで、コンテナの構成要素を削減しています。
それによってコンテナは仮想マシンに比べて、環境を簡単に複製したり使い捨てることができます。
このコンテナの扱いやすさによって、デプロイのテストやマイクロサービスアーキテクチャの構築というのは非常に楽になりました。
仮想マシンでは物理マシンを買ってくるのと同じように、仮想マシンに独立したCPUやメモリ、ストレージといったリソースを割り当てることが可能です。
もちろん、どちらもリソースはホストOSのリソースを使用することになります。
カーネルの役割
カーネルの共有という言葉が出てきたのでカーネルの役割を解説します。
カーネルはハードウェアとソフトウェアの間のインターフェースとして機能します。
具体的には、プロセス管理、メモリ管理、デバイス管理などを行います。
コンテナでは、ホストOSのカーネルを共有するためハードウェアのリソースを効率的に使用し、個々のコンテナが独自のOSを必要とせずに動作できます。
カーネルを共有することによるメリット
では、カーネルを共有することでどのような利点があるのでしょうか。
速い
カーネルはPCの起動時にハードウェアの初期化やBIOSの起動、OSの入ったストレージへのアクセスなどハードウェアレベルの仕事をしています。
コンテナはこれらのカーネルの仕事を省略して、直接OSを起動します。
これによるメリットは「速さ」です。
起動、停止、削除の速さはコンテナ技術による圧倒的なメリットでしょう。
軽い
仮想マシンではカーネルも仮想化します。
そのため、カーネルの容量というのが発生します。
コンテナにはこのカーネルに割り当てる容量が必要ないため、仮想マシンに比べて軽量です。
カーネルを共有することでの注意点
カーネルの種類に依存する
Linuxベースのカーネルではwindowsのコンテナを起動することはできません。
逆も然りです。
ただし、windows10以降ではWSL2というLinuxカーネルをwindows上で実行できるようになっています。本題から逸れるためここでは割愛します。
独立性とセキュリティ
コンテナはホストOSのカーネルを使用しています。
そのため、ホストOS上で動作している複数のコンテナの内一つが攻撃を受けると、その範囲が他のコンテナ、ホストOSにまで影響を与える可能性があります。
一方、仮想マシンでは個々の仮想マシンが完全に独立しています。
そのため、一つの仮想マシンが攻撃を受けたとしても他のマシンへの被害を抑えることがコンテナに比べると容易です。
では、独立性の強い仮想マシン同士でネットワークを組むことは可能なのか?
これは可能です。それぞれは物理のホストと同じように考えればよいので、IPアドレスの割り振り等、適切なネットワークの設定を行うことで通信が可能です。
他にも、ホストOSのディスクを共有することでファイルのやり取りを行うことも可能です。
しかし、これらの通信では通常のホスト間でのやりとりと同様に、通信を暗号化するなどセキュリティの対策が必要です。
仮想マシンだから安全でコンテナだから安全ではない。ということではありません。
どちらも適切なセキュリティの設定を行う必要があります。
結局どっちがいいの?
ここまででコンテナと仮想マシンの違いを説明してきましたが、どちらが正解ということではありません。以下は一例です。
[仮想マシン]
- 独立したゲストOSが必要な場合
- 異なるOSを同時に実行する必要がある場合(Linuxカーネルとwindowsカーネルの共存など)
- 強固な隔離が求められるセキュリティが重要な環境
[コンテナ]
- 素早い起動やスケーリングが必要な場合
- マイクロサービスのような分散型アプリケーションを開発する場合
- 開発環境と本番環境を合わせる場合
上記は一部の例ですが、作成するアプリケーションや環境の要件によってうまく使い分ける必要があります。
まとめ
色々と違いを説明しましたが、仮想マシン上でコンテナを動かすということも可能です。
そうすることでホストOSに依存することなくコンテナを立ち上げることができます。
どちらかに依存するのではく、状況により何を使うと楽になるか。ということを考えるといいと思います。
所感
なんとなくコンテナはカーネルを共有しているという事は知っていましたが、今回勉強したことによってカーネルを共有することで、どのような利点があるという部分まで理解できました。