Docker導入のための、コンテナの利点を解説した説得資料

## 何がしたいのか

最近はDockerを導入したサービスがガンガン出てきている一方、現場でのDocker導入に足踏みをしているところもあると思います。
今回はDockerを導入するために、「コンテナを利用するとこんなに便利!!」という主張を展開することで、現場でのDocker導入の推進をしたいと思います！

まあ、スライドモードを使いたかったんですよ

---

## TL;DR

- コンテナと仮想環境は別物だよ
- コンテナでの運用するといいことがたくさんあるよ
  - どんな環境でも同じように動かせる
  - デプロイ・ロールバックが簡単 
  - システムが簡単に把握できる
  - あいのり環境もいける

---
# コンテナとは
---
## コンテナ ≒ VM ??
Docker導入しようって言うとこんな話を聞くことがある

- コンテナってVMみたいなもんでしょ？
- VMの上にまたVM作るの?
- AMI使ってるから、わざわざコンテナにする必要がない

---
## コンテナ != VM
VMとコンテナが比較されることが多い( [例えばこんな記事](https://thinkit.co.jp/story/2015/08/05/6284) )ため、よく勘違いされるが、コンテナとVMはまるで別物

VMは一つの**PCの電源をつけてから消すまで**をまるごとシミュレートするが、コンテナはその中で動く一つ一つの処理、例えば`service httpd start `のような**一つのコマンド**のみをシミュレートする

---
こんな感じ

![docker.png](https://qiita-image-store.s3.amazonaws.com/0/102182/fc78b44b-4bfb-e43e-abda-4f1d0a0c51fb.png)

---
## コンテナとは何か
コンテナを簡単に説明するなら、以下の通り


「**ある前提となる状態**のもとで、あるコマンドを叩いたときに発生する処理の内容を再現するもの」

---
## 例
以下のDockerfileを見る

```Dockerfile
FROM centos:6.5

RUN yum install -y httpd

CMD ["cat", "/etc/httpd/conf/httpd.conf"]
```
これは、「CentOS 6.5で、`yum`経由で`httpd`をインストールし、
`cat /etc/httpd/conf/httpd.conf`とコマンドを打ったときの処理」を再現する。

---
# コンテナ運用の利点

---
## どの環境でも同じように動く

---
## コンテナのもつ再現性
コンテナが「**ある前提となる状態**のもとで、あるコマンドを叩いたときに発生する処理の内容を再現するもの」と述べたが、この「ある前提となる状態」には**Linux ディストリビューションの情報**も含まれている
つまり、例えば「CentOS6.5上でyumでインストールしたhttpdを動かしている」コンテナはUbuntuだろうがDebianだろうがScience LinuxだろうがMac、Windowsだろうが、**どこでも全く同じように動作する**ということである

---
こんな変な環境でも、**少なくともコンテナの部分だけは**同じように動いてくれる ( 作れとは言ってない )

![container.png](https://qiita-image-store.s3.amazonaws.com/0/102182/23dde6ed-92c7-224e-8563-7f6796c97d94.png)

---
## デプロイ・ロールバック

---
Dockerのコンテナイメージはリポジトリ管理できるので ( Docker Registry )、デプロイは一番新しいイメージからコンテナを起動すればよいし、ロールバックは今より古いバージョンのイメージからコンテナを起動すればいい。

![deploy.png](https://qiita-image-store.s3.amazonaws.com/0/102182/1ddd62bb-ec17-75c8-aebf-5959ec90783f.png)

---
## コードデプロイとの違い

- コンテナは動作状態自体が含まれているため、ロールバックを確実に行うことが可能
- コードのみのデプロイだと、サーバの状態がデプロイ前後で変わっている可能性を考慮してロールバックする必要がある
- 代わりにコンテナを利用したデプロイの場合はイメージを作成するというひと手間がかかる

---
## システムの把握を簡略化

---
とあるシステム

![complex.png](https://qiita-image-store.s3.amazonaws.com/0/102182/db38b8d9-1c1c-e6c4-d358-cc4e5a093d88.png)

---
問題点

- そもそもこういう構成になっているというのを調べたり引き継ぎしたりしなければならないのが大変
- リクエストルートが凝っていて、追跡が大変
- ディストリビューションにバンドルされたhttpdなどを使っているため、年月がたってもサーバを更新できない
- 何をしているのかわからないものがある

---
Dockerだと

- 構成は?
  - HostサーバはDockerさえ入っていればよい。アプリの構成は動いているコンテナを`docker ps`で調べるか、手元のDockerfileを参照するなどすれば把握できる
- バージョンは?
  - イメージビルドの時点でバージョンなどは任意に指定できるので、Hostのパッケージ管理システムに依存しない。好きなものを使おう
- リクエストルートを凝るのは難しいかもしれない...が`swarm`modeを使えば実現できるかも？

---
## あいのり環境も現実的なラインに

---
### あいのり環境とは

- 一つのサーバに複数のアプリケーションが入っている状態
- 調達した大きめのサーバを有効的に使える
  - AWSなどはネットワークの質がインスタンスのサイズでも変わってくるため、よいネットワーク環境を使えるかもしれない
  - 費用を低減できる

---
### あいのり環境と複雑さ

- 複数サービスの存在により、サーバに必要なモジュールがどんどん増える
- 各サービスへのルーティングなども必要になる
- 新しいアプリを加えようとすると依存性やサーバの状態により、新しい言語やバージョンを入れられない場合もある
- サーバがブラックボックス化する
- 運用できなくなる
- DIE

---
###ごった煮環境
APP1に必要なのはなんなのか？

![gottani.png](https://qiita-image-store.s3.amazonaws.com/0/102182/a2eaf7bb-f30c-9dd6-741d-19ffc7cb4a4d.png)

---
## コンテナを使った複雑さの回避

- Docker コンテナでアプリケーションをデプロイする場合、サーバには**Dockerさえ入っていれば**良い
- 依存性やバージョンはコンテナの内部で完結するので、言語・バージョンを気にすることなく、好きなような実装が可能
- ルーティングはポートマッピングである程度解決できる

---
### とにかくDockerさえ入っていれば良い
HostにDockerさえ入っていれば、各アプリケーションの入ったコンテナを立ち上げるだけであいのり環境ができる

![sukkiri.png](https://qiita-image-store.s3.amazonaws.com/0/102182/ff788eae-2125-f67e-69c6-6c111896d625.png)


---
## ちなみに

あいのり環境なんて変な呼び方しているけど、各アプリケーション間につながりがあると、みんな大好き**マイクロサービス**になったりする。
Dockerとマイクロサービスは等しくはないけれど、マイクロサービスを実現するための手段としてはDockerを使うのは現実的である

---
# まとめ

---
- Dockerコンテナは「前提条件を持った処理」であって、VMとは違う
- コンテナを使ったアプリはDockerさえあれば、Hostの環境に関係なく、どこでも同じように動く
- コンテナでアプリを運用すると、システムがスッキリするしさらにマイクロサービスを構築することもできる
- こんてな、みんなどんどん使っていきましょう！