Dockerの野望、Kubernetesへ

[(2018/08/09追記)たくさん「いいね」を頂きました。ありがとうございます:hugging:](#20180809追記たくさんいいねを頂きましたありがとうございますhugging)

# これは何？
- ネットにある多くの情報は「Dockerの本質について」触れていないものが多いように感じたので、そのギャップを自分が理解した範囲で埋めてみます。
- 主に以下のことを説明します。そのため、Docker(Kubernetes)の特徴の説明の多くを省略しています。
 - 「なぜDockerが生まれたのか？」（Docker以前～Dockerの先にあるもの）
 - 「Dockerは純粋な仮想化ではない」(これまでの仮想化との違いの話)
 - 「Dockerが１コンテナ１アプリの理由」
 - **「Docker＝開発環境を簡単に、早く作れていいね」という＊だけ＊ではない。**
 - **「Dockerの野望(本当のゴール)＝負荷分散システム(Kubernetes)」であることを説明する。**
- 最後になりましたが、私のDockerの経験は浅く、Kubernetesは使ったこともありません。なので、嘘を書いている可能性もあります。鵜呑みにしないでください。

# 仮想化の進化について
- １台の物理サーバを「より効率的に使いたい」「同一サーバ上に隔離環境を作りたい」という目的から始まり仮想化は進化してきたようです。
- 仮想化方式の違いを知るには次のようなポイントがあります。
 - 環境の隔離
 - 起動の速さ
 - 仮想イメージの大きさ(サイズ)
 - 起動(systemd,init)の仕組みの違い

## 1) 物理サーバ
- 仮想化が無い時代。

```
+-------------+ +-------------+ ---
| application | | application |  ↑
+-------------+-+-------------+  |
| systemd                     |  |distribution
+-----------------------------+  |
| linux kernel                |  ↓
+-----------------------------+ ---
| hardware                    |
+-----------------------------+
```

## 2) ハードウェア仮想化
- **1台のPC上で複数のゲストOSを動かしたい。ソフトウェアでPCをシミュレーションしてしまおう**
- ソフトでハードウェア(HW)をシミュレーションすることで、1HWをあたかも複数あるように見せる。

```
 +-------------+ +-------------+ +-------------+ +-------------+
7| application | | application | | application | | application |
 +-------------+-+-------------+ +-------------+-+-------------+
6| systemd                     | | systemd                     |
 +-----------------------------+ +-----------------------------+
5| linux kernel                | | linux kernel                |
 +-----------------------------+ +-----------------------------+
4| 仮想hardware                | | 仮想hardware                |
 +-----------------------------+-+-----------------------------+
3| virtualbox, kvm など                                        |・・・ここまで１つ
 +-------------------------------------------------------------+
2| linux kernel                                                |
 +-------------------------------------------------------------+
1| hardware                                                    |
 +-------------------------------------------------------------+
```

## 3) Linux(LXC)コンテナ
- １台のPC上で複数のゲストOSを動かしたい、**Linux限定 ならもっと早く動かせるよね**
- linux kernel が持つ名前空間を分離する機能を使って、1つのカーネルをあたかも複数あるように見せる。

```
 +-------------+ +-------------+ +-------------+ +-------------+
4| application | | application | | application | | application |・・・systemdからアプリを起動する。(通常のLinuxの仕組みと同様)
 +-------------+-+-------------+ +-------------+-+-------------+
3| systemd                     | | systemd                     |
 +-----------------------------+-+-----------------------------+
2| linux kernel ＆ 名前空間分離する機能を使用                     |・・・ここまで１つ
 +-------------------------------------------------------------+
1| hardware                                                    |
 +-------------------------------------------------------------+
```

## 4) Dockerコンテナ
- １台のPC上で複数のゲストOSを動かしたい、**Linux限定、１コンテナ１アプリ限定ならもっともっと早く動かせるよね**
- Linuxコンテナと違い、１コンテナ１アプリケーションとし、直接アプリケーションを起動する。

```
 +-----------------------------+ +-----------------------------+
3| application                 | | application                 |・・・アプリを直接起動する
 +-----------------------------+ +-----------------------------+
 | (systemdなし)               | | (systemdなし)               |
 +-----------------------------+-+-----------------------------+
2| linux kernel ＆ 名前空間分離する機能を使用                     |・・・ここまで１つ
 +-------------------------------------------------------------+
1| hardware                                                    |
 +-------------------------------------------------------------+
```

# 開発現場での仮想化技術へのニーズの変化
- 開発現場が、コンテナを利用した開発に至るまで。

```
１）１台のPCで開発
　↓＜課題＞
　↓・毎回、開発環境の構築に手間がかかる。
　↓・前の開発環境に簡単には戻せない。
　↓・同じ環境のはずなのに、自分のPCではなぜか動かない。
　↓
　↓＜対策＞
　↓・ハードウェア仮想化(virtualboxなど)で解決
　↓
２）１台のPCで、ハードウェア仮想化を利用して開発
　↓＜課題＞
　↓・起動/停止が遅い。
　↓
　↓＜対策＞
　↓・Linuxコンテナ、Dockerコンテナで解決
　↓
３）１台のPCで開発、Linux/Dockerコンテナを利用して開発
```

# 実は、Dockerは＊純粋＊な仮想化ではない

- virtualbox、LXC/LXDは、OSとしてはLinuxサーバ(ディストリビューション)そのものを使います。これを、ここでは＊純粋＊な仮想化と呼びます。（物理サーバで得た経験をそのまま活かせます）
- 一方、DockerはLinuxの一般的な起動方法(systemd,init)を捨て、ログを管理する仕組みなどを変更しました。この点については、新たにDockerの流儀を学ぶ必要があります。
- それでは、なぜ、Dockerは「今までのLinuxの一般的な方法をあえて変更」してしまったのでしょう？

# なぜ、Dockerは＊純粋＊な仮想化を実現しなかったのか？
- いきなり答えから書きます。
 - **「Dockerで分散システムを実現したかった」**からです。
- では、なぜ分散システムなのか？

# 運用現場での仮想化技術へのニーズの変化
- 運用現場が、Dockerによる分散システムに至るまで。

```
１）１台のPCでサービス提供
　↓＜課題＞
　↓・負荷の増大に耐えられなくなった！
　↓
　↓＜対策＞
　↓・複数サーバにして解決
　↓
２）WEBサーバｘ5台、APサーバｘ5台、DBサーバでサービス提供
　↓＜課題＞
　↓・ピーク負荷の為に、365日ずっと合計5＋5＋1台を起動
　↓　しておくのはもったいない！
　↓
　↓＜対策＞
　↓・自動スケーリングにして解決
　↓
３）WEBサーバｘ1～5台、APサーバｘ1～5台を自動スケーリング、DBサーバでサービス提供
　↓＜課題＞
　↓・もっと自由で効率的な方法はないのか？
　↓
　↓＜対策＞
　↓・サーバ単位ではなく、アプリ単位で自動スケーリングできればもっと効率的では。
　↓・小さなアプリ(サービス)で開発すれば工期も短縮できるし、変更も小さくて済むはず。など
　↓
４）Dockerによる分散システムの実現へ＝Kubernetes
```

# Dockerによる負荷分散＝Kubernetes

Dockerコンテナを使うことで、今までの負荷分散の仕組みと比べると、以下の特徴があるようだ。

- 言語や環境の自由度が高い
 - Docerコンテナ内で、どんな言語を使ってもいいし、環境もコンテナに閉じているので自由に選べる。

- 起動が早い
 - Dockerは、Linuxの一般的な起動方法(systemd,init)を捨て、直接アプリケーションを起動する仕組み(１コンテナ１アプリの原則)としたので、起動するまでのステップが大幅に短くなった。(その代わり、Dockerの流儀に従う必要がある)

今までの負荷分散システムと比べると Kubernetes は、後発ということもあって、より良いものになる可能性がある。
一方、分散ストレージ については、Kubernetes 自身はサポートしていないので、
パフォーマンスがでるような仕組みを別途考える、あるいは用意する必要がある。

# マイクロサービスの時代へ
- 「ハードウェア」という概念が、「クラウド」の登場で薄くなった。
- 「サーバ」という概念が、「Docker」の登場で薄くなった。
- 今は昔と比べて「アプリ」の比重がより重くなっている＝マイクロサービスの時代へ

# 「Docker＝開発環境を簡単に、早く作れていいよね」の先にあるもの

- 以上の説明より、もしも単に開発環境を仮想化したいだけなら、LXC/LXDでもいいはず。
- Dockerを使うなら、そこがゴールではなく、その先があることも知っておいたほうが良さそう。

# とても参考になったもの

[開発におけるDocker導入のメリット - Qiita]
(https://qiita.com/minodisk/items/5ffd20588b995523756f)
Dockerのメリットがコンパクトで分かりやすく参考になりました。

[Docker（コンテナ型仮想化）と Kubernetes についての簡単な紹介 － ゆびてく]
(https://ubiteku.oinker.me/2017/02/21/docker-and-kubernetes-intro/)
Kubernetesとは何なのか？が分かりやすく参考になりました。

[レガシー分散システムからモダン分散システムへ - ブログなんだよもん]
(http://koduki.hatenablog.com/entry/2017/01/30/025604)
分散システムとは何なのか？Dockerとは？について参考になりました。

[知らぬはエンジニアの恥。今さら聞けない【コンテナ/仮想化技術】11選 - paiza開発日誌]
(https://paiza.hatenablog.com/entry/2014/10/21/%E7%9F%A5%E3%82%89%E3%81%AC%E3%81%AF%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%81%A5%E3%80%82%E4%BB%8A%E3%81%95%E3%82%89%E8%81%9E%E3%81%91%E3%81%AA%E3%81%84%E3%80%90%E3%82%B3%E3%83%B3)
コンテナ、仮想化技術について参考になりました。

# (2018/08/09追記)たくさん「いいね」を頂きました。ありがとうございます:hugging:

- とても驚いています。この記事の最初に、次のように書いたので、まさかこんなに「いいね」をもらえるとは想像していませんでした。

> 最後になりましたが、私のDockerの経験は浅く、Kubernetesは使ったこともありません。なので、嘘を書いている可能性もあります。鵜呑みにしないでください。

- そもそも、Docker便利なのは使ってすぐに分かったのですが、しばらくすると違和感がモヤモヤと湧いてきました。ネットで情報収集する中で、最近になってやっと、その答えを自分なりに１本につなげて書けたので「詳しくないエンジニアの話に需要あるのかな？」とも思いつつ、最近アウトプットしていないので、投稿したというのが本当のところです。
- 実は「Kubernetes の先はどうなるのかな？」も、いくつか考えて（妄想して）いたのですが、さすがにそこまで書いてしまうと、話がぶれそうに感じたのと、まとめるのも難しそうでしたので、省いてしまいました。
- ですが、この記事の「いいね」に背中を押されていると思って、近々（？）この続きを書いてみます。