VM・Dockerといった仮想化技術を理解する

# はじめに
本記事では、VMの簡単な説明からはじまって、コンテナ技術の説明をし、Dockerについて説明していきます。
なお、それぞれの具体的な使い方には触れません。
具体的なチュートリアルはこちらの記事がいいと思います。
[Dockerでプログラマが最低限知るべきことが、最速でわかるチュートリアル](https://qiita.com/woz/items/43462398765f8036f3a8 "Dockerでプログラマが最低限知るべきことが、最速でわかるチュートリアル")

# VMとコンテナについて
## VM
簡単にVMを説明します。
VMとはVirtual Machineのことで、「仮想マシン」などと呼ばれることもあります。
通常物理的に存在しているマシンを、仮想的に作り出して動かしています。
単一の物理リソースを複数の論理リソースにわけることで、まるで別のマシンであるかのように振る舞わせているというわけです。

そんなVMですが、VMと一言でいっても、大きく分けて2種類あります。
- **ホスト型**
- **ハイパーバイザー型**

です。
それではまず、ホスト型VMについて説明していきます。

## ホスト型
<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/f8fa3743-f708-cbc4-b6b0-e2d5d8b9ffae.png" width=60%>

ホスト型はOS上に土台となるソフトウェアをインストールし、ソフトウェア上で仮想マシンを稼働させる方式です。
例：VMware Player, VMware Fusion, Windows7でのXPモード

これらの仮想化ソフトで、仮想的なハードウェアを作り、OSやアプリケーションを動かしています。

図を見てもらうと分かるように、ホストOSの上に仮想環境が乗っています。
ホストOSにトラブルが起これば、アプリケーションとして動作している仮想化環境へもトラブルが波及してしまいます。

### メリット
- すでに利用しているサーバーやPCにもインストール可能なので手軽

### デメリット
- ハードウェアへアクセスするにはホストOSを経由する必要があるので、余計なオーバーヘッドが発生して十分な性能が出ない

## ハイパーバイザー型
<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/36d6bb96-d83d-35d7-8e57-fc21cc5a9512.png" width=70%>

ハイパーバイザー型は、サーバーへ直接インストールし仮想マシンを稼働させる方式です。
例：ESXi、Hyper-V、Xenなど
OSより下層に仮想化ソフトをおくことで、すべてのOSを仮想化環境で動かすことができます。

### メリット
- ホストOSを必要としないためハードウェアを直接制御することが可能
- 仮想マシンの速度低下を最小限に抑えられる
- 複数の仮想マシンを効率よく稼働させるための様々な仕組みが盛り込まれている

### デメリット
- 既存のホストOSをそのまま利用できない
- 専用の物理サーバーを用意する必要がある

## コンテナ
それでは、コンテナの説明に入っていきます。

単一のカーネル上で隔離されたプロセスをコンテナと呼びます。
コンテナを複数実行することで、あたかも複数のサーバーが動作しているかのように振る舞わせることができます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/87efb1c5-540f-e2fb-a2bc-15af4d8a10eb.png" width=60%>
VMではホストOSの上に仮想化ソフトウェアをはさんで、ゲストOSが存在していましたが、コンテナではDocker Engineの上にコンテナプロセスが乗っかっています。
以下に特徴をまとめます。
### 特徴
- 単一のOS上で隔離された複数のコンテナが実行される
- ベースとなるOSと異なるOS用のコンテナは実行できない
(例:Linux上でWindowsコンテナを動かすなど)
- コンテナ間でベースとなるOSは共有される
* コンテナはプロセスとして実行され、仮想化は行われない  
<font color="#db7aad">※仮想化とできることが似ているため</font>
<font color="#db7aad">「コンテナ型仮想化」と表現されることがある</font>
* Linux上ではLXCやlibcontainerが利用される

### メリット
* 構成が仮想化よりも単純なため高密度化が可能
* 仮想化よりもオーバーヘッドが少ない
* 新しいマシン(コンテナ)の起動がVMよりも高速

### デメリット
* OSと異なるシステムをコンテナで起動させることはできない
* カーネルを全てのコンテナで共有するため、カーネルに対する変更操作を個別に行うことができない

### VMとのちがい
VMとのちがいは、ズバリ仮想化の粒度がちがいます。
VMはマシン単位での仮想化であるのに対して、コンテナはプロセス単位での仮想化となっています。
コンテナの仕組みにより、仮想マシンやゲストOSは存在せず、コンテナに作成されたOS環境の起動、停止は非常に高速で、オーバーヘッドが小さいです。

VMはリソースの消費は大きいですが、自由度が高いです。
対してコンテナは、OSをホストと共有してしまう点では自由度は低いですが、軽量で可搬性が高い技術となっています。
下に簡単な比較表を作りました。

|   | VM | コンテナ |
|:--|:----------------|:----------|
| OS | 異なるOSでも可能 | 同じOSのみ(Linux系ならディストリビューション違っても可能) |
| OS設定 | 個別に変更可能 | 個別の変更不可 |
| ディスク・メモリ消費 | 大 | 小 |
| 構成| ハードウェアに依存 | ハードウェアに依存しない |
| 起動 | 遅い | 早い |


# Dockerとは
Docker=コンテナというイメージを持ちますが、Dockerは「コンテナをマネージメントするツール」というのが正しいです。
コンテナ技術というのはなにもDockerの専売特許というわけではないのです。
Linux上でコンテナを管理・実行するためのプラットフォームこそがDockerです。
他のコンテナ技術に関して知りたい方はこちらの記事をどうぞ。
[Docker だけじゃない Containers の世界](https://qiita.com/kentarosasaki/items/b44b5ffb57a69085027e "Docker だけじゃない Containers の世界")

## Dockerのアーキテクチャ
<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/e1fc9dc3-a139-0bcd-fa2d-f89e535b73c1.png" width=60%>
Dockerはクライアント・サーバー型の構成です。
DockerクライアントがDockerデーモンと通信することで、Dockerコンテナの構築・実行・配布をおこないます。

### Dockerデーモン
Dockerデーモンはホストマシン上で動作します。
コンテナの生成・実行・モニタリングとともに、Dockerイメージの構築と保存を受け持ちます。
ユーザーは直接デーモンとは通信せず、Dockerクライアントからコマンドでおこないます。

### Dockerクライアント
Dockerクライアントは、DockeデーモンとHTTP経由で通信・操作するためのアプリケーションです。
デフォルトでは、Unixドメインソケットを通じて行われますが、TCPソケットを使ったリモートクライアントや、ファイルデスクリプタを使ったsystemd管理下のソケットも利用できます。
すべての通信はHTTPを用いて行うので、リモートのDockerデーモンに接続することも容易です。
ユーザーからのコマンドを受け付けると、Dockerデーモンと通信し返します。

### Dockerイメージ
Dockerイメージとはコンテナの元になるひな形のことです。
Docker Hub上で配布されているものもありますが、Dockerfileという定義ファイルから独自のイメージを作成することも可能です。
イメージはリポジトリに保存されるので、複数のイメージが保存でき、IDやタグで指定も可能です。
また、これらのイメージはDocker Hub(DockerイメージのGitHubのようなもの)と呼ばれるオンラインサービスで共有可能です。

# まとめ
- VMとは仮想マシンのことで、1台のマシンをリソースを分けることで擬似的に複数台のマシンに見せかけている。
- VMは、ホスト型とハイパーバイザー型の2種類がある。

<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/f8fa3743-f708-cbc4-b6b0-e2d5d8b9ffae.png" width=40%><img src="https://qiita-image-store.s3.amazonaws.com/0/260994/36d6bb96-d83d-35d7-8e57-fc21cc5a9512.png" width=60%>

- コンテナは、単一のOS上で隔離されたプロセスであり、コンテナ間でOSは共有される
- あくまでプロセスであり、仮想化は行なわれていないが、理解する上では軽量なVMだというイメージでもよい

<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/87efb1c5-540f-e2fb-a2bc-15af4d8a10eb.png" width=60%>

|   | VM | コンテナ |
|:--|:----------------|:----------|
| OS | 異なるOSでも可能 | 同じOSのみ(Linux系ならディストリビューション違っても可能) |
| OS設定 | 個別に変更可能 | 個別の変更不可 |
| ディスク・メモリ消費 | 大 | 小 |
| 構成| ハードウェアに依存 | ハードウェアに依存しない |
| 起動 | 遅い | 早い |

- Dockerとは、コンテナを管理・実行するためのプラットフォーム

<img src="https://qiita-image-store.s3.amazonaws.com/0/260994/e1fc9dc3-a139-0bcd-fa2d-f89e535b73c1.png" width=60%>

# 参考サイト・文献
- 【図解】コレ１枚で分かるコンテナ型仮想化とDocker(http://blogs.itmedia.co.jp/itsolutionjuku/2015/05/docker.html)
- 第1回　Dockerとは：超入門Docker
(http://www.atmarkit.co.jp/ait/articles/1701/30/news037.html)
- Docker オライリー・ジャパン(https://www.oreilly.co.jp/books/9784873117768/)