Kubernetes コントローラの概要についての自習ノート


k8sクラスタにワークロードをかける際に、重要な役割を果たすのが、コントローラの存在の様だ。 全部を詳細に追うのは、たいへんなので、概要レベルで自習したノートです。

私見ですが、重要な順にソートすると、デプロイメント、レプリカ・セット、ステートフル・セット、ジョブ、デーモン・セットという感じでしょうかね。



## レプリカ・セット (Replica Sets)
`ReplicaSet`は、次世代のレプリケーション・コントローラです。 レプリカ・セット と レプリケーション・コントローラ の唯一の違いはセレクタサポートです。 レプリカ・セットは、新しいセットベースのセレクター要件をサポートしますが、レプリケーション・コントローラーは等価ベースのセレクター要件のみをサポートします。


#### ユースケース
kubectlコマンドは、レプリケーション・コントローラとレプリカ・セットをサポートしています。1つの例外は、`kubectl rolling update`コマンドです。 ローリング・アップデート機能を使用する場合は、代わりにデプロイメントでのロールアウトを検討してください。 また、`kubectl rolling update`コマンドは命令形式ですが、デプロイメントはYAMLに定義する宣言型であるため、レビジョン管理とロールバック機能があるため、デプロイメントが優れています。

ReplicaSetsは独立して使用できますが、現在では主に、ポッドの作成、削除、および更新を調整するメカニズムとしてデプロイメントによって使用されています。 デプロイメントを使用する場合、作成するレプリカセットの管理について心配する必要はありません。 デプロイメントはレプリカセットを所有し、管理します。

#### 参照資料 
* https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/



## レプリケーション・コントローラ (Replication Controller)
レプリカ・セットを設定するには、デプロイメントでReplicaSetを設定する方法が推奨されています。
ReplicationControllerは、指定された数のポッドのレプリカが、常に実行されていることを確認して保証します。 

#### 参照資料 
*  https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/



## デプロイメント (Deployments)

デプロイメントは、ポッドとレプリカ・セット（次世代レプリケーションコントローラ）の宣言的な更新を提供します。 デプロイメント・オブジェクトの目的の状態を記述するだけで、デプロイメント・コントローラは、実際の状態を目的の状態へ、制御下の速度で、変更します。 デプロイメントを定義して新しいリソースを作成したり、既存のリソースを新しいものに置き換えることができます。

典型的な使用例は次のとおりです。

* デプロイメントを作成し、レプリカセットとポッドが起動します。
* デプロイメントの状態をチェックして、成功か否かを確認できます。
* 実行中のデプロイメントを更新して、ポッドを再作成できます。（たとえば、新しいイメージを使用するなど）
* 更新後のデプロイメントが安定しないケースには、以前のレビジョンにロールバックできます。
* デプロイメントの一時停止と再開

#### 参照資料 
* https://qiita.com/MahoTakara/items/0245a9f18c7a97bcdd31
* https://kubernetes.io/docs/concepts/workloads/controllers/deployment/




## ステートフル・セット (StatefulSets)

ステートフル・セットは、ステートフルなアプリケーションを管理するために使用されるワークロードAPIオブジェクトです。

注：ステートフル・セットは、Kubernetes version 1.9で安定しており、正式リリースとなりました。

一連のポッドのデプロイメントとスケーリングを管理し、これらのポッドの順序と一意性について保証します。

ステートフル・セットは、デプロイメントと同様に、同一のコンテナ仕様に基づいたポッドを管理します。 デプロイメントとは異なり、ステートフル・セットは、それぞれのポッドに固定されたIDを保持します。 これらのポッドは同じ仕様で作成されていますが、互換性はありません。各ポッドは、どの再スケジューリングでも維持される永続的な識別子を持っています。

ステートフル・セットは、他のコントローラと同じパターンで動作します。 ステートフル・セットで、目的の状態を定義すると、ステートフル・セット・コントローラは、現在の状態からそこに到達するために必要な更新を行います。


ステートフル・セットは、次の様な要件がある場合に有用です。

* 静的でユニークなネットワーク識別子
* 静的な永続ストレージ
* 順序性が保証されたグレースフルなデプロイとスケーリング
* 順序性が保証されたグレースフルな終了と削除
* 順序性が保証された自動的なローリング・アップデート

上記において、「静的」とは、ポッド横断的な再スケジューリングの持続性、と同義です。 アプリケーションが安定した識別子を必要とせず、デプロイメント、削除、スケーリングを命じられた場合は、ステートレス・レプリカのセットを提供するコントローラーでアプリケーションをデプロイする必要があります。 デプロイメントややレプリカ・セットなどのコントローラは、ステートレスなニーズに適しています。

参考資料
* https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/




## デーモン・セット (Daemon Sets)

デーモン・セットは、すべての（またはいくつかの）ノードがポッドのコピーを実行することを保証します。 ノードがクラスタに追加されると、ポッドが追加されます。 ノードがクラスタから削除されると、それらのポッドはガベージコレクションされます。 デーモン・セットを削除すると、作成したポッドがクリーンアップされます。

以下は、デーモン・セットの典型的なユースケースです

* 各ノードでglusterd、cephなどのクラスタストレージデーモンを実行
* fluentdやlogstashなど、すべてのノードでログ収集デーモンを実行
* Prometheus Node Exporter、collectd、Datadogエージェント、New Relicエージェント、Ganglia gmondなど、すべてのノードでノード監視デーモンを実行

参考資料
* https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/



## ガベージ・コレクション (Garbage Collection)

Kubernetesガベージコレクタの役割は、以前は所有者があったが所有者をもたない特定のオブジェクトを削除することです。
一部のKubernetesオブジェクトは、他のオブジェクトの所有者です。 たとえば、レプリカセットは、一連のポッドの所有者です。 所有オブジェクトは、所有者オブジェクトの従属オブジェクトと呼ばれます。 すべての従属オブジェクトには、所有オブジェクトを指すmetadata.ownerReferencesフィールドがあります。


参考資料
* https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/


## ジョブ (Jobs - Run to Completion)

ジョブは1つまたは複数のポッドを作成し、指定された数のポッドが正常終了することを保証します。 ポッドが正常終了すると、ジョブは成功とみなします。 指定された数の正常終了に達すると、ジョブ自体は完了です。 ジョブを削除すると、作成したポッドがクリーンアップされます。

シンプルなケースでは、確実なポッドの処理を実行するために、1つのジョブ・オブジェクトを作成します。 ジョブ・オブジェクトは、ポッドに障害が発生した場合やノードのハードウェア障害やノードの再起動などにより削除された場合、新しいポッドを開始します。

ジョブを使用して、複数のポッドを並行して実行することもできます。

参考資料
* https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/




## クーロン・ジョブ (Cron Jobs)

Cronジョブは時間ベースのジョブを管理します。

* 特定の時点で1回
* 特定の時点で繰り返し

1つのCronJobオブジェクトは、crontab（cronテーブル）ファイルの1行に似ています。 Cron形式で書かれたスケジュールに従って定期的にジョブを実行します。

注：スケジュールの疑問符（？）は、アスタリスク*と同じ意味を持ちます。つまり、指定されたフィールドに使用可能な値のいずれかを表します。

注：バッチ/ v2alpha1 APIグループ内のCronJobリソースは、クラスタバージョン1.8から非推奨になりました。 代わりに、APIサーバーでデフォルトで有効になっているbatch / v1beta1を使用するように切り替える必要があります。 さらにこの文書では、すべての例でbatch / v1beta1を使用します。

典型的な使用例は次のとおりです。

* 指定された時点でジョブの実行をスケジュールします。
* 定期的なジョブを作成します。 データベースのバックアップ、電子メールの送信

参考資料
* https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/