プログラマのためのDocker超入門 04.Dockerのよさ（前編）

　
![docker.png](https://qiita-image-store.s3.amazonaws.com/0/66457/da2303a9-e25a-8035-3e5f-e5692ef96383.png)

# 前提

以下、`インフラ？誰かに頼むから大丈夫！`な方への記事です。
正確な説明や比喩よりも、わかりやすさを優先します。

# これまであがった課題など

明確に書いていなかったものも含め、こんな課題がありそうです。

初回の[仮想化](/pottava/items/7086f9d63487aa3d7d08)では

~~* 環境間の差異を完全になくすことはできない~~[^1]
* ひとつの仮想環境で利用できるOSはひとつに限定されてしまう[^2]
* 仮想環境の中で何が動いているのか、外からはわかりにくい

前々回の[構成管理](/pottava/items/5b386a952bf1d26ea387)では

* OSによっては構成管理が期待通りに動かない
* 同じ定義書を利用しても、やはり隣の人とまったく同じ環境になる保証がない
* ひとつのプロジェクトで、複数バージョンのソフトウェアを同時に使うのは依然困難
* そもそもプロジェクトごとに定義書作るのは（煩雑さが緩和されず）やっぱり大変

前回の[クラウド](/pottava/items/3d75477b467d93de8784)では

* サーバは数分で起動するが、数分は決して速くない
* スナップショットからは作業履歴を追いにくい
* サーバスペックは複数種類からの選択で、それでは過剰もしくは不足
* ポータビリティ[^3]が下がるベンダーロックインの心配
* サーバ単位でDisposable Componentsするのは時間的金銭的に非効率

# Dockerとはなにか

Dockerは上述の課題、すべてとは言わないまでも、そのかなりを解決します :smiley: 
Dockerがどんなもので、どうやってそれらを解決するのかを見てみましょう。

1. Dockerはコンテナ型仮想化、動くプロセスはたった1つ
2. イメージを使ってコンテナを起動する Docker
3. 起動も停止も一瞬
4. gitのようにcommit, push, pullを使った作業の履歴管理ができる
5. Dockerイメージは、クラスのように継承できる
6. コンテナが利用するCPUやメモリに上限を設け、リソース管理できる
7. Windowsを含めた大手OS、クラウド各社がサポートを表明

今回は 3まで見ていきましょう！

## 1.1 Dockerはコンテナ型仮想化、動くプロセスはたった1つ

もしかしたらみなさんがすでに馴染みのある仮想化ソフト Boot Campや Parallels[^4]、
または [01.仮想化](/pottava/items/7086f9d63487aa3d7d08)で仮想開発環境としておすすめした Vagrant + VirtualBoxであっても
仮想化といえば、コンピュータそのもの、マシンといわれる単位で行うものでした。
Macの上に Windowsを起動したら、そこで Excelや Wordが使えますよね？
それは、Parallelsなどが `Windows端末そのもの`を再現するためです。

一方で Docker。同じ仮想化ツールですが、実は全然違います。

Dockerは、マシンではなく、`コンテナ`[^5]を起動します。
コンテナの中では通常、プロセスは一つしか動きません。
つまり、Windowsではなく、Excel`だけ`が起動するようなものです。

Vagrant + VitualBoxでは、例えば、起動した唯一の Ubuntuサーバの中で
Nginxや JVM、MySQLといった複数のサービスが動いていたかと思います。
しかしDockerで同じ構成にしようとすると、こんな感じ

```bash
$ docker ps

CONTAINER ID   STATUS         NAMES
48d97913fd70   Up 10 seconds  nginx
64ec5a454f68   Up 10 seconds  javavm
5e07fef69752   Up 10 seconds  mysql
```

つまり、各サービスごとにコンテナを起動します。
（3つの仮想環境でひとつのプロジェクトを構成します）

## 1.2 コンテナ型仮想化の恩恵

一見、3つも仮想環境を立ち上げる Dockerは管理が煩雑です。
しかし一方で、以下の問題が解決したようです。

> ・ひとつの仮想環境で利用できるOSはひとつに限定されてしまう

実は上の `nginx`、`javavm`、`mysql`、
それぞれベースになっている OSが違っていても問題ありません。
仮に

* Nginxを担当する Aさんは 得意な Red Hat Enterprise Linux 7で
* Javaアプリを開発するあなたはなんとなく Ubuntu 14.04で
* MySQLを担当する Bさんは公式と同じ Debian 7.7 Wheezyで

分業しても、全体としては期待通りにちゃんと動作します[^6]。
また、これも解決します。

> ・仮想環境の中で何を動かしているのか、外からはわかりにくい

さきほどコンテナの一覧を表示したコマンド `docker ps` ですが
このコンテナ一覧は、現在動作しているプロセスそのものです :wink: 

## 2. イメージを使ってコンテナを起動する

Vagrant + VirtualBoxでも Parallelsでも どんなクラウドでも、
仮想マシンの起動には`テンプレート`[^7]となるデータが必要になります。
例えば Vagrantなら、[ここ](http://www.vagrantbox.es/)から `Box`を探すことになりますし
EC2なら最初に `AMI`を選びます。

Dockerの場合は、テンプレートのことを Dockerイメージと呼び、
そこからインスタンス化された環境のことを Dockerコンテナと呼びます。

Vagrantにも boxのサイトがあったように、Dockerにも公式イメージを
管理しているサイトがあります。
[Docker Hub Registry](https://registry.hub.docker.com/)です。

ここに掲載されているアプリケーションなら、
いずれもこんな感じでかんたんに起動できます。

```bash
$ # docker run [オプション] Dockerイメージ [コンテナ内でプロセスを起動するためのコマンド]
$ docker run -d -v /content:/usr/share/nginx/html nginx
```


## 3. 起動も停止も一瞬

コンテナ型ではない仮想化の場合、環境の立ち上げは速くても数十秒かかりました。
しかし Dockerはコンテナ型、起動はほんの一瞬です。1秒かかりません[^8]。

```bash
$ # docker run [オプション] Dockerイメージ [コンテナ内でプロセスを起動するためのコマンド]
$ docker run -d -p 3305:3306 -e MYSQL_ROOT_PASSWORD=pw55 mysql:5.5
$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pw56 mysql:5.6
$ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=pw57 mysql:5.7
```

MySQL Serverをローカルにインストールすることもなく
`一瞬`で MySQL5.5、MySQL5.6、MySQL5.7サーバが`同時に`起動しましたね！
ということは、

> ・複数バージョンのソフトウェアを同時に使うのは依然困難

これが解決したようです。
そして、起動と停止が一瞬ということは

> ・サーバは数分で起動するが、数分は決して速くない

これも解決です。

# 今回のまとめ

Dockerを使うことで、仮想化や構成管理を使う以上に、
よりかんたんで柔軟な開発、リリース作業ができそうじゃないですか？
次回は Dockerの特徴、後半をお届けします。

[05. Dockerのよさ（中編）](/pottava/items/5b101cbae8eae4754b3e)へ

　
[^1]: サーバをテンプレート化して共有すればやれますよね、ということで訂正します・・
[^2]: 何かをインストールしようとしてググると、実はそれは CentOS 5向けの記事で、いま目の前にある CentOS 6にはあてはまらない、みたいなことがよくあります。もし、アプリごとに OSを自由に選べるとしたら、インストール作業がずっと楽になると思いませんか？
[^3]: [可搬性](http://e-words.jp/w/%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3.html)。他のクラウド、他のOSの上でも動くものは可搬性が高い、といいます
[^4]: [Boot Camp](https://www.apple.com/jp/support/bootcamp/)や [Parallels](http://www.parallels.com/jp/products/desktop/)は Mac OS Xの上にWindows OSを起動できる仮想化ソフト
[^5]: コンテナが何かは、次回以降でもう少し掘り下げます
[^6]: これも、ホストではなくプロセスのみを起動するコンテナ型のなせる技ですね
[^7]: 仮想環境の元となるデータ。オブジェクト指向言語で言えば、[クラス](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%B9_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))にあたります
[^8]: イメージのダウンロードが済んでいれば、ですが・・