メモ：Google製DockerクラスタツールKubernetes

メモ：Google製DockerクラスタツールKubernetes
===

はじめに
----
[Bounscale](https://github.com/bounscale/bounscale/)というオートスケールするHeroku Addonを作っています。

Bounscaleは現在はHerokuに対応していますが、元々Herokuに関わらず主要なクラウドのリソースをオートスケールさせたいと考えています。なので今後数年のトレンドを持って行きそうなDockerの動向はもちろん注視しています。

そんな中、DockerのクラスタツールKubernetesがGoogleから発表されたので、概要をつかむために少しドキュメントを読んだので所感を含めてまとめておきます。

注意
----
[公式のGithubのWikiのデザインドキュメント](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/DESIGN.md)などを読んで自分なりに理解した内容をまとめています。私見メモであり推測も多分に含まれているいい加減な文書です。翻訳ではありません。また、理解に誤りが含まれていると思います。原文読んでください。

Kubernetes?
----
これはなんて読むんでしょう。辞書でも出てこないのでお手上げです。キュベルニーツ?検索性は高そうです。どういう意味なのかわかっていません。

追記：コメント欄で教えてもらいました！
```
Kubernetesの意味と読み方、たぶんわかりました！（？）
・意味：ギリシャ語で「人生の道標」
・読み方：クーベルネイテス（koo-ber-nay'-tace）
```

```
"Kubernetes" の意味ですが、
Google Cloud Platform Blog に書いてあったなと思って見直すと、
http://googlecloudplatform.blogspot.jp/2014/06/an-update-on-container-support-on-google-cloud-platform.html

(For the curious, Kubernetes (koo-ber-nay'-tace) is Greek for “helmsman” of a ship.)

船の舵取りだそうです。なので、 Captain (船長) はキミだ！みたいな。
```

```
英語での読み方はクバネテス、正確にはクゥーバネィテスですね。作者のビデオで確認できます：
https://www.youtube.com/watch?v=tsk0pWf4ipw
```


背景
---
Dockerは「軽量なコンテナイメージを」「簡単に差分共有できる」っていうところが革新的なのかなと思います。

裏返すとただそれだけの存在で、HerokuやCloudFoundryのように、スケールアウトをコマンド１つでできるわけでもないし、デプロイがgit push一発で終了するわけでもないし、正常にサービスが動き続けるためのモニタリングの仕組みを持っているわけでもありません。

世の中的にはDockerを使ってImmutable Infrastructureを実現！と盛り上がってますが、Dockerは(とても大事な）パズルの1ピースで、これだけでは運用はできません。

そんなDockerの周りのピースを埋めるのがKubernetesだと考えられます。

概要
---
[Overview](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/DESIGN.md#overview)を読んでみると、kubernetesはDockerを包括するような形で"clustered container scheduling service"を提供するんだそうです。

このschedulingという表現が聞きなれなかったのですが、どうもクラスタ管理系でよくつかわれる「orchestration」を更に進化させたものが「schedule」である、というニュアンスで使っているようです。この辺りは後のPodの説明で少し出てきます。

アーキテクチャ
---

### 全体図
デザインドキュメントではKubernetesを構成するたくさんの言葉というか要素の定義がつらつらと文章で書いてあります。図がほしいな、と思ったので起こしてみました。理解があってるのかかなり怪しいですが。

#### 図
![kubernetes.png](https://qiita-image-store.s3.amazonaws.com/0/27361/9f2c228d-75bf-ce84-09fc-0ff1f565acea.png)

### Node
Nodeという単位が一番大きい構成要素のようです。これは具体的にはCoreOSなどのDockerコンテナのホストOSと対応しているように思います。物理的にはベアメタルだったりIaaS/VMwareだとかの仮想マシン1台だったりとイコールなのかなと。

なお図には分かりやすくするために思い切りCoreOSと書いていますが、これは私が勝手に書いたもので、デザインドキュメントにはCoreOSの名前は出てきていません。

### Container
Containerはそのまま、LXCなどのコンテナ仮想化のコンテナの単位のようです。ここまでは普通にDockerの話だと思います。

### Pod
ここからKubernetes独特の概念が出てきます。

PodというのはContainerをまとめたものだそうです。単にまとめたのではなくて、同一のNode上に存在するように"schedule"されたContainer群のことをPodと呼ぶと。おそらく、どこのNodeにいるかは保証しないけど、同一PodのContainerは必ず同じ場所にいるようにすることをscheduleと表現しているのだと思われます。

同一のNode上にあるので、同じネットワークだとかストレージだとかを共有していて、データ共有だとかデプロイだとか、スケーリングだとかの単位として扱うと便利だよね、と。

例としてはキャッシュとか、バックアップの取得とか、ログ取得とか、Proxyとか、管理とか、そういう周辺的な機能をPod内のコンテナが提供するような想定でいるようです。

アプリ本体のコンテナの近くに、パフォーマンスに影響を与えやすい周辺的な機能を提供するコンテナを配置することで効率をよくするということなんですかね。

### Kubelet
Kubeletは[YAMLで書かれたPodのマニフェストファイル](https://developers.google.com/compute/docs/containers/container_vms#container_manifest)を読み込んで、Pod/Containerを起動・維持するような役割っぽいです。

マニフェストファイルの中身を見ると、利用するポートとかボリュームとか環境変数、そしてDockerイメージの指定ができます。

マニフェストが各Pod単位で存在するような感じに書いてあるのですが、実際のマニフェストファイルを見るとPodという名前が出てくるわけでもなく、この辺りは結構理解が怪しいです。

（よく見ると上のリンクはKubernetesではなくてGCEのドキュメントですね・・・。そのうち差し替わるのでしょうか。）

ちなみにマニフェスト情報はファイルとかHTTPのエンドポイントとか、etcdとかHTTPサーバだとか、いろんな方法で更新できるみたいです。

### Label
Labelは各Podの役割をゆるく定義するキーバリューとのこと。

例えば、environment=devとか、environment=productionとか、tier=frontendとか、tier=backendとか、のラベルを付けることで、そのPodが開発用なのかプロダクションなのか、あるいはフロントサーバなのかバックエンドサーバなのかなどを自由に分類して、Label毎にまとめてデプロイを実施したり等、管理用途に活用できるようです。

また、スケールの仕組みにもLabelを使うようで、新たに特定のLabelを付けたPodを作るとスケールアウトして、Labelを消すとスケールインするようなイメージっぽいです。

なお、Labelは1つのPodに複数付けることができるみたいです。

### Proxy
サービスとして定義されたNodeへアクセスをフォワードするような仕組みとのこと。おそらくサービスにアクセスするためのロードバランサのような感じでしょうか。

### Master
各種Nodeその他を管理するのがMaster。
基本的には設定変更の受付と展開が役割です。

#### API Server
名前のまま、[Kubernetes API](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/api/kubernetes.html)を提供しているサーバです。

pod/service/replicationControllerの設定を受け付けるREST APIで、PodをNodeに配置したり、Podの情報を同期したりする役割とのことです。

#### etcd
etcdが提供されていて、etcd経由で設定を各Nodeに連携できるようです。

### Network Model
Dockerはネットワーク周りがポートフォワードだらけで結構つらいです。[Pipework](https://github.com/jpetazzo/pipework)だとか周辺ツール含めて、色々改善の検討がされている状況です。

Kubernetesもそこはサポートしたいと考えているようで、Pod単位にIPを割り当てられるのがゴールのような事が書いてあります。

対応環境
---
今のところはGCEのみの対応ですが、[今後は色々対応していくつもり](https://github.com/GoogleCloudPlatform/kubernetes#kubernetes-can-run-anywhere)ということがREADME.mdにかいてあります。実際のところ、今はGCEのアカウントがないと[Getting Started](https://github.com/GoogleCloudPlatform/kubernetes#prerequisites)も動かせないです。

ソースを見ると、[cloudprovider](https://github.com/GoogleCloudPlatform/kubernetes/tree/master/pkg/cloudprovider)というディレクトリが準備されているので、なんとなくここを増やせば他のクラウドにも対応できるのかな、という感じはします。ここはcontributeしがいがあるところかもしれませんね。

おわりに
---
所感として、デザインドキュメントには将来の話が書いてある(=未実装)箇所が散見されます。まだまだこれからのプロダクトという印象を受けました。

また、例えばCloudFoundryのHealthManagerのような監視絡みの話が出てきていないように見えました。役割的にはKubeletがコンテナの維持担当なので、[少しソース見ましたが](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/pkg/kubelet/kubelet.go)、どうもやっている様子はなさそうです。
将来的にはやってくれるのかもしれませんが、機能としてもまだ不足があるような印象を受けました。

[MesosがDeimosというDocker向けプラグイン](https://github.com/mesosphere/deimos)を出したり、[CloudFoundryがDocker向けBosh](http://www.infoq.com/jp/news/2014/06/docker-cloud-foundry-bosh)を出したり、競合達もDockerを使ったシステム運用を実現するための様々な機能を提供している・しようとしています。

これらの競合と比べて、自社内で20億のコンテナを管理しているというGoogle主導でKubernetesがどのような発展を見せるか今後もウォッチしていきたいと思います。