コンテナとは ― Dockerと仮想マシンの違い
コンテナは、
コンテナとは、アプリを隔離して動かす仕組み
開発したアプリを本番のサーバに載せると、環境の違いで動かないことがあります。コンテナは、アプリと、そのアプリを動かすのに必要なファイルをひとまとめにして、ほかのアプリから隔離して動かす仕組みです。開発・テスト・本番で同じ中身を動かせるので、環境の違いによる不具合が減ります。
隔離された環境はコンテナごとに別ですが、OSのカーネルは、同じホストのすべてのコンテナが共有します。ホストとは、コンテナを動かすコンピュータのことです。カーネルとは、OSの中心にあたる部分で、プログラムにCPUやメモリを割り当てます。
Dockerは、コンテナを作って動かすためのソフトウェアです。公式ドキュメントは、Dockerを、アプリの開発・配布・実行のためのオープンなプラットフォームと説明しています。コンテナについては、実行に必要なファイルを備えた、隔離されたプロセスと説明しています。プロセスとは、実行中のプログラムのことです。
NISTは、1つのカーネルを複数のアプリに見せる仕組みをアプリケーション仮想化と呼んでいます。NISTの説明では、この技術はコンテナと呼ぶことが多いとされています。仮想化の方式の1つとして、コンテナ型と呼ぶこともあります。
コンテナと仮想マシンの違いは、OSのカーネルを共有するかどうか
仮想マシン(VM)は、1台ごとにOSを丸ごと持ち、ハイパーバイザーがハードウェアを分けます。コンテナは、OSのカーネルを共有したまま、アプリごとに環境を分けます。次の図は、2つの方式の層を並べたものです。共有する層と、1つずつ専用の層がどこで分かれるかを確かめられます。
層を押すと、その層が共有か専用かが出ます。
アプリは、1つずつ専用の層です。
アプリは、VMごとのゲストOSの上で動きます。ほかのVMのアプリとは、ゲストOSごと分かれています。
ゲストOSは、1つずつ専用の層です。
VMごとに、OSが1つずつ丸ごと入っています。NISTは、VMが完全なゲストOSを含むと説明しています。LinuxとWindowsのように、VMごとにOSの種類を変えることもできます。
ハイパーバイザーは、全体で共有する層です。
物理サーバに1つだけあり、すべてのVMが使います。NISTによると、ハードウェアのレベルで資源をVMに分けて、VM同士を分離します。
物理ハードウェアは、全体で共有する層です。
CPU・メモリ・ディスクなどの実体です。1台の物理サーバを、すべてのVMで分け合って使います。
コンテナ(アプリ)は、1つずつ専用の層です。
コンテナには、アプリと、動かすのに必要なファイルだけが入っています。OSのカーネルは入っておらず、下のホストOSのものを使います。
コンテナランタイムは、全体で共有する層です。
コンテナごとの動作環境を作り、維持するソフトウェアです。ホストOSに入っていて、すべてのコンテナの起動や停止を受け持ちます。
ホストOSは、全体で共有する層です。
OSのカーネルが1つだけあり、すべてのコンテナが共有します。コンテナ同士は分けられていますが、仮想マシンと違って、カーネルまでは分かれていません。
物理ハードウェアは、全体で共有する層です。
CPU・メモリ・ディスクなどの実体です。コンテナは、ホストOSを通してこれを使います。
仮想マシンにあって、コンテナに無い層が、ゲストOSです。コンテナのイメージにはカーネルが入っていません。その分、コンテナは小さく作れます。Dockerの公式ドキュメントは、コンテナは軽くて速いので、ハイパーバイザー型の仮想マシンの代わりになりうると説明しています。
| 比べる | 仮想マシン | コンテナ |
|---|---|---|
| カーネル | VMごとに | ホストOSの |
| 別のOS | Linuxと | ホストと |
| 分離の | 明確な | 強いが、 |
| 更新の | 動かしたまま | 更新した |
NISTは、動かせるコンテナがホストのOSの系統で決まる点も挙げています。Linuxのホストで動かせるのはLinux向けのコンテナで、Windowsのホストで動かせるのはWindows向けのコンテナです。
イメージとコンテナの関係は、ひな形と、そこから起動した実体
イメージとは、コンテナを動かすのに必要なファイルをまとめた、読み取り専用のひな形です。コンテナとは、そのイメージから起動した、実行中の実体です。
料理にたとえると、イメージはレシピと材料の一式で、コンテナは出来上がった料理です。同じレシピから何皿でも作れますし、料理を直してもレシピは変わりません。
イメージは、層を重ねて作ります。いちばん下の層にはUbuntuなどのOSのファイルが入りますが、カーネルは入りません。その上に、アプリの実行に必要なライブラリなどと、自分のコードを足していきます。
イメージを作り直すとき、Dockerは、変更した層とその上に重なる層を作り直し、下の層は前回のものを使い回します。イメージ自体は作ったあとに書き換えません。中身を変えたいときは、新しいイメージを作ります。
レジストリとは、作ったイメージを保管し、必要な場所に配る置き場です。Docker Hubが代表例で、Amazon Elastic Container Registryのように、クラウド事業者が用意するものもあります。NISTによると、レジストリではイメージに名前と版を付けて管理でき、他の人が作ったイメージを探して取り寄せることもできます。
オーケストレーションとは、多数のコンテナの配置と再起動を自動で行う仕組み
オーケストレーションとは、多数のコンテナの配置と監視を自動で行う仕組みです。どのホストで動かすかを決め、状態を見続けて、必要なら入れ替えます。この役を受け持つソフトウェアを、オーケストレーターと呼びます。Kubernetesが代表例で、NISTは、ほかにMesosとDocker Swarmを挙げています。
利用者は、動かしたいコンテナの数と、1つあたりに必要なCPUやメモリの量を伝えます。オーケストレーターは、各ホストの空きを調べて、コンテナを置くホストを決めます。そのあとレジストリからイメージを取り寄せて、コンテナとして起動します。
起動したあとも、オーケストレーターはホストの状態を見続けます。ホストが故障したときは、別のホストでコンテナを起動し直すことがあります。Kubernetesの公式ドキュメントの説明では、望む状態を書いておくと、Kubernetesが実際の状態をそこへ近づけます。止まったコンテナは再起動され、負荷が高いときは、CPUの使用率に応じて台数を自動で増やせます。Kubernetesの構成と、止まったコンテナが元の数へ戻る流れは、Kubernetesの記事で説明しています。AWSでこの役を受け持つサービスは、Amazon ECSのページでEKSとの違いと合わせて説明しています。コンテナの中で動くアプリの不調を調べる方法は、オブザーバビリティの記事で説明しています。
小さな構成では、オーケストレーターを置かないこともあります。その場合は、ホストがレジストリから直接イメージを取り寄せて、コンテナを起動します。
コンテナのメリットと注意点
メリット
- 開発・テスト・本番で、同じイメージを動かせるため、環境の違いによる不具合が減る
- どのコンテナも同じイメージから作られ、状態を持たないため、台数を確実に増減しやすい
- 更新は、新しいイメージを作って置き換えるだけで済み、本番で手作りのスクリプトを実行して導入する必要がなくなる
台数を簡単に増やせるので、コンテナはスケールアウトと相性がよい仕組みです。コンテナを動かすサーバやネットワークは、構成を書いたファイルから作ることもできます。この方法をIaCと呼びます。アプリを小さなサービスに分けてサービスごとにコンテナで動かす作りは、マイクロサービスの記事で説明しています。分けたサービスを自動でテストして届ける流れは、CI/CDの記事が詳しいです。
注意点
- カーネルを共有するため、仮想マシンより分離が弱く、設定が甘いと、ほかのコンテナやホストにアクセスされやすくなる
- コンテナの中に書いたデータは、作り直すと残らないため、データベースなど外の置き場に書く必要がある
- コンテナのIPアドレスはオーケストレーターが割り当て、頻繁に変わるため、IPアドレスで通信を制限する規則が使いにくい
- 既存の市販ソフトは、開発元がコンテナでの動作に対応していないと、コンテナで動かしにくい
仮想マシンとコンテナの使い分け
どちらが優れているかは一概に言えず、求めるものによって向く方式が変わります。
求めるものを選ぶと、向く方式が出ます。
仮想マシンが向く
NISTによると、コンテナは強い分離を持ちますが、仮想マシンほど明確な境界ではありません。コンテナはカーネルを共有するため、設定が甘いと、コンテナ同士やホストに触れやすくなります。
仮想マシンが向く
仮想マシンは、ゲストOSを丸ごと持つため、OSの種類を変えて同じ物理サーバに載せられます。コンテナはホストOSのカーネルを使うので、Linuxのホストで動かせるのはLinux向けのコンテナだけです。
コンテナが向く
コンテナのイメージは、機器や環境をまたいで持ち運べるように作られています。開発環境で作ったイメージを、テスト環境、本番環境へと、そのまま移して動かせます。
コンテナが向く
NISTは、スケールアウトの場面でコンテナが使いやすいと説明しています。どのコンテナも同じイメージから作られ、状態を持たないので、増やすのも消すのも確実に行いやすいからです。Dockerの公式ドキュメントも、軽くて速いことを特徴に挙げています。
両方を組み合わせる
NISTは、仮想マシンとコンテナのどちらかを選ぶ必要はないとしています。仮想マシンでハードウェアを分け、その上でコンテナを使ってアプリをまとめる使い方が、よく行われます。
クラウドで借りるサーバは、多くが仮想マシンです。EC2のインスタンスも、多くは仮想マシンです。その中に、コンテナを動かすソフトウェア(コンテナランタイム)を入れれば、複数のコンテナを動かせます。NISTによると、仮想マシンとコンテナは組み合わせて使われることが多くあります。コンテナを載せるサーバの管理まで事業者に任せたいときは、関数の単位でコードを動かすサーバーレスも候補になります。仮想マシンで動いていたアプリをコンテナへ移すことは、クラウド移行の手法でいうリプラットフォームの例の1つです。
コンテナを使って、別の事業者のクラウドへ移しやすくする考え方もあります。マルチクラウドとベンダーロックインのページで説明しています。
参考にした資料
練習問題(全5問)
正解:同じ
NISTは、
正解:コンテナを
イメージは、
正解:イメージを
レジストリは、
正解:
オーケストレーターは、
正解:コンテナの
コンテナは、
選んでから「採点する」を押すと、解説つきで答え合わせができます。