Google Container Engineの諸概念

- Container Cluster
- Kubernetes master
- Pods
- Replication Controller
- Services

といったGoogle Container Engine(GKE)を使う上で理解しておくべき諸概念のまとめです。

基本的にはGoogle Container Engineドキュメントの[Conceptsの章](https://cloud.google.com/container-engine/docs/clusters/?hl=ja)の訳です。

厳密でない部分も多々あります。英語のままの方がむしろ分かりやすい部分はそのままの用語で書いてあります。


#Container Cluster
applicationの基礎。Kubernetesが走っているインスタンスのグループ
1つ以上のnodeインスタンスとKubernetes master endpointで構成される。

#Kubernetes master
全てのContainer Clusterは単一のmaster endpointを持つ。master endpointはContainer Engineで
管理される。
masterはclusterへの統一的なviewを提供し、publicにアクセス可能なendpointを通じてclusterとやりとりする
窓口となる。
managed masterはKubernetes API Serverも走らせており、RESTリクエストによりpodを作成、削除、同期させることができる。

#Nodes
1つのConatainer Clusterは1つ以上のnodeインスタンスをもつ。
これらのnodeインスタンスはmasterにより管理され、Docker containersのサポートに必要なサービスを走らせている。
それぞれのNodeはDocker runtimeを走らせ、Dockerコンテナを管理するKubelet agentをホストする。
それぞれのnodeは1つのシンプルなnetwork proxyも走らせている。

| -----(Container Cluster)------- |
| (nodes)<---(Kubernetes master)<-- Container Engine
|---------------------------------|

#Pod
podとはあるコンテナ化された環境における、アプリケーションに固有の'論理的なhost'である。
podは比較的密接に関連付けられた1つ以上のコンテナを含む。
podは強固なエンティティというよりもどちらかといえば使い捨てのものとみなされる。
Podsはnodesに割り当てられ、終了か削除までそこに生き続ける。
あるnodeが死んだとき、そのnodeに割り当てられたpodsは削除される。
あるpodsは新しいnodeに再割り当てされることはなく、代わりに新しいpodsが割り当てられる。
####**Podsの役割**
 - *リソースの共有と通信*

 Podsはその構成物どうしのデータ共有や通信を容易にする。
 pod内のcontainerは全て同じnetwork namespace/IP とport spaceを使用し、localhostにより互いを見つけ通信する。
 それぞれのpodはフラットにシェアされたnetworking namespaceにおけるIP addressをもつ。そのアドレスはネットワーク経由で
 その他の物理的なコンピューターやコンテナと完全に通信できる。
 pod内のコンテナのためのhostnameにはpodの名前がセットされる。
 
 - *管理*

 podsは生の低levelコンテナインターフェースより高度に抽象化されたインターフェースを提供することで
 アプリケーションのデプロイや管理をシンプルにする。
 podsはデプロイや水平スケーリング/レプリケーションの単位として機能する。
 Co-location, fate sharing, coordinate replication, リソース共有、依存関係の管理は自動的に行われる。
 
 - *Podsの使用*
 
 Podsは垂直に統合されたapplication stacksをホストするのに利用可能であるが、
 本来の用途は次に挙げるようなco-located, co-managed helper programをサポートすることである。
  >- Content management systems, file and data loaders, local cache managers, etc.
  >- Log and checkpoint backup, compression, rotation, snapshotting, etc.
  >- Data-change watchers, log tailers, logging and monitoring adapters, event publishers, etc.
  >- Proxies, bridges, and adapters.
  >- Controllers, managers, configurators, and updaters. 

一般に個々のpodsは同じアプリケーションの複数のインスタンスを動かそうとしない。
 
# Replication Controller
Replication Controllerはある特定の数のpodのレプリカが同時に動いていることを保証するものである。
もし多すぎる場合はいくつかのpodsをkillする。少なすぎる場合はその分を起動させる。
ただ単にシングルインスタンスやbulkのpodsを生成するのでなく、Replication Controllerは何らかの理由で消されたり
終了したpodsを置換する。
こうした理由から、たとえアプリケーションが単一のpodのみから成る場合でもReplication Controllerを使うことを推奨する。
ある`replicationController`は`RestartPolicy=Always`をもつpodのみに適用される。
あるreplication controllerはそれ自体のみでは決して終了しないが、サービスと同様に長生きするものと期待することはできない。サービスは複数のReplication Controllerによって制御されているpodsから構成されているかもしれないし、その場合には
多くのreplication controllerがサービスのライフサイクルの中で消えたり作られたりするだろう。
サービスやそのクライアントはreplication controllerには無意識であるべきである。

####**replication controllerはどのように動く？**
   - Pod template
     あるreplication controllerはテンプレートから新しいpodsを生成する。
     全てのレプリカの現在の望ましい状態を指定するというよりも、templateはクッキーばさみに近い。
     一度クッキーがカットされたら、クッキーはカッターと関係なくなる。
     後に起こるテンプレートの変更や新しいテンプレートへの変更は、すでに作成されているpodsに直接影響しない。
   - Labels
     replication controllerが監視するpodsのpopulationはlabel selectorで定義される。
     label selectorはcontrollerとcontrollerにより制御されるpods間の緩やかな関係をつくる。
     結果、ただひとつのreplication controllerが任意のpodを制御する。
     つまりreplication controllersのlabel selectorは重複したセットをターゲットとしない。
     あるpodをreplication controllerのtarget setから削除しようとするとき、podのlabelを変更すればいい。
     このpod削除のテクニックを、デバッグやデータ復旧などで活用できる。
     このようにして削除されたpodは自動的に置き換えられ、同じ数が維持される。
     
####**Common Usage Pattern**
   **Rescheduling**
     1つでも1000個でも、replication controllerは指定した数のpodsが存在していることを保証する。

   **Scaling**
     Replication controllerは手動でも自動でもレプリカの数を容易にスケールup/downさせることができる。
     replication controllerの`replicas`fieldを更新することでスケールさせられる。

   **Rolling Updates**
     Replication controllerはpodsをひとつずつ置き換えることでrolling updateを容易にできるようデザインされている。
     推奨すべきアプローチは
      1. 1つのreplicaで新しいreplication controllerを作成
      2. 新しい(+1)、古い(-1)controllerをひとつずつリサイズ
      3. 0 replicasになるまで古いreplicaを削除
     This predictably updates the set of pods regardless of unexpected failures.
     2つのreplication controllerが少なくとも1つの区別されたlabelによってpodsを作成する必要がある。

   **Multiple release tracks**
     rolling updateが進行中の間にアプリケーションの複数releasesを走らせるの加えて、複数のrelease trackを用いて
     拡張された期間の間かあるいは継続的に複数releasesを走らせるのが一般的だ。
     例えばあるサービスは`tier in (frontend), environment in (prod)`によって全てのpodsをターゲットにするかもしれない。
     あなたは今このtierを予定する10のreplicatedされたpodsを持っているとする。
     しかしこの構成要素の新しいバーションをテストできるようにしたい。
     あなたは9個の主要なレプリカとしてセットされたreplicasによってあるreplicationControllerをセットアップする。
     そのときのlabelは`tier=frontend, environment=prod, track=stable`である。
     そしてもうひとつのreplicationControllerを1つのテスト用としてセットされたレプリカによりセットアップする。
     そのときのlabelは`tier=frontend, environment=prod, track=test`である。
     今やサービスはテスト用と非テスト用の両方をカバーしている。
     しかしテストをしたり結果をモニターしたり、といったことのためにreplicationControllerを別々に更新できる。

# Services
   **serviceとは**
   Container Engineのpodsは非永続的である。特にreplication controllersのようなものに動かされるときpodsは
   たえず変動している。
   それぞれのpodsが自身のIPアドレスを得たとして、それらのアドレスはずっと不変のものであると考えてはならない。
   これは間違いのもとになる:クラスタ内でもしあるpods(backendsと呼ぼう)が他のpods(frontendsと呼ぼう)への
   機能を提供するならば、frontendsはどうやってbackendsを見つけるのだろう。
   
   servicesに入れ。

   あるserviceはpodsの論理的なsetとそれらへのアクセスポリシーを定義する抽象体である。
   servicesの目的は、非Kubernetesアプリケーションがbackendsにアクセスするための架け橋を
   Kubernetes固有のコードを書くことなしに提供することである。
   あるserviceはclientsにIPとportのペア(アクセスされると適切なbackendsにリダイレクトする)を提供する。
   ターゲットとされたpodsのまとまりはlabel selectorにより決定される。

   例えば、3つの生きたレプリカで構成されるひとつの画像処理backendについて考えてみよう。
   これらのレプリカは交換可能である- つまりfrontendsはどのbackendが使われているかは気にしない。
   そのセットからなる実際のpodsが変更されるとき、frontendクライアントはそれを知る必要はない。
   service abstractionがこのdecouplingを可能にする。

   **How do they work?**
   クラスタ内のそれぞれのノードはサービスプロキシを走らせる。このアプリケーションはservice objectsを追加したり削除し
   たりするのに、Container Engineによって管理されるcluster masterを監視している。
   もし、あるserviceのlabel selectorがあるpodのlabelsにマッチしたとき、
   プロキシはローカルノードにおけるそのserviceやpodへのtrafficeのためのportを開く。
   
   あるpodがスケジュールされているとき、managed masterはそれぞれのactive serviceのための一連の環境変数を加える。

   あるserviceは、そのlabel selectorを通して、0かそれ以上のpodsを解決できる。serviceの生存期間を通じて、
   そのserviceから構成される一連のpodsは大きくなったり小さくなったり、あるいは完全にひっくり返ったりすることができる。
   Clientsはそれらがあのbackendがserviceから取り除かれた際にそのbackendを実際に使用している場合にだけissuesを見る。