Kubernetes運用前に勉強していること基礎編03-03

# Kubernetes運用前に勉強していること基礎編03-03

> **注意**  
> 本記事の内容は個人的な勉強・備忘録を目的としており、勤務先や関係者とは一切関係ありません。

---

## はじめに

Kubernetesの本番環境での運用を始めるにあたり、個人で勉強している内容を整理した記事です。構築や運用に必要な知識、注意点、実践して学んだことを随時更新していきます。基礎編の想定読者はコンテナの知識があり、Kubernetesでコンテナ運用したいがどうすればいいかを迷っている人です。今回は前回の引き続きで、Kubernetesのリソースカテゴリを学ぶことを目的としています。

## 勉強中の主な内容

- 基礎編
  - クラウドネイティブとは
  - Kubernetesのアーキテクチャ概要
  - <font color="Red">Kubernetesのリソース（今回の話）</font>

# Job
Jobは、指定した処理を完遂するまでPodを実行し続けるためのリソースである。Jobを作成すると一時的なPodが起動し、タスク（バッチ処理など）が成功終了するか、所定の試行回数を満たすまで再試行される。Jobが管理するPod群のうち、成功完了したPodの数が目標値に達するとJob自体が完了と見なされ、それ以降Podの再実行は行われない。
ジョブ用のPodを必要なだけ（成功するまで繰り返し）走らせて確実に所定回数成功させるのがJobリソースの役割である。

### Jobにの実行パターン

- 単発実行ジョブ: 1つのPodを立ち上げ、それが成功終了すればJob完了。Podが失敗したら再試行
- 並列実行ジョブ: 複数のPodを同時に起動し、それぞれがタスクを実行。全てのPodが成功終了（または必要な完了数に到達）すればJob完了
- コンプリート数指定: .spec.completionsで例えば5と指定すると、成功完了したPodが合計5になるまでPodを生成し続ける
- 永久リトライしない設定: 失敗しても再試行しない、あるいは一定回数以上失敗したら諦める（backoffLimitで制御）ことも設定できる

### 設計思想
JobはKubernetesにおけるバッチ処理フレームワークである。ReplicaSet/Deploymentが常駐サービスの高可用性を追求するのに対し、Jobは確実にタスクを実行し終えることを目的としている。
したがって、エラーハンドリング（再試行）や成功判定といったロジックが組み込まれており、人手を介さずにタスク実行の信頼性を担保する。また並列処理にも対応しているため、ワーカー並列によるスループット向上もできる。

# CronJob
CronJobは、Cron（スケジューラ）のようにJobを定期的に作成・実行するためのリソースである。CronJob自体はスケジュールとJobテンプレートを持ち、例えば「毎日深夜2時にバックアップJobを実行」などのスケジュールをcron形式で指定できる。CronJobコントローラはスケジュールに従って新たなJobオブジェクトを生成し、そのJobが前述のルールでPodを完了させることで、定期実行が実現される。

### 設計思想
CronJobは、Kubernetesクラスターを一種の巨大な計算スケジューラとして扱い、インフラとスケジューリングの管理負荷を減らすことを目的にしている。従来、ジョブスケジューラやcron管理は各サーバーごと（EC2）に設定する必要がありましたが、CronJobにより全てクラスターAPIで一括管理でき、宣言的にスケジュールをコード化（Infrastructure as Code）できる。また、Kubernetesの他のリソースと同様にCronJob自体もYAMLで定義・デプロイできるため、GitOps的な運用も可能になる。

# サービスのデザインパターン紹介
Kubernetesは、実際のクラウドネイティブな開発で困ったことを自動化することを目的としてるため、サービスモデルの知見があるとアプリケーション運用時に、どうな課題を解決するために生まれたサービスなのかを直感的に理解できる。この後、２つのサービスモデル紹介する。過去記事の[Kubernetes運用前に勉強していること基礎編03-02](https://qiita.com/yuya3-t/items/bb3b50c605fd115be22b)を読むことをお勧めする）

## コントローラーサービス

コントローラーサービスとは、受動的に動作し、システム内のイベントに反応してアクションを実行するサービスである。具体的には、宣言的（declarative）に記述されたリソースの理想状態（Desired State）と実際の状態（Actual State）を監視し、その差分を解消するための調整プロセスを自動実行する。

![コントローラーサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/10af6ecd-9f5b-4c14-85da-6b2f57ffeb2c.png)

コントローラーサービスは図のような構成になっており、下記のステップで構成される。




* 観察：Kubernetesが発行するイベントを監視し、現在の状態を把握する
* 分析：希望する状態との間にある差分を特定する
* 行動：現在の状態を希望する状態に移行する

### Custom Resource Definition（CRD）について

コントローラーサービスは、KubernetesのCustom Resource Definition（CRD）で実現される。CRDは、特定ドメインの方式をKubernetesプラットフォーム上で管理するためのリソースを定義する仕組みである。カスタムリソースはKubernetes APIを通じて管理され、最終的にはバックエンドストアのetcdに保存される。CRDを用いることで、ユーザーは自身のアプリケーションやサービスに固有のリソースタイプをKubernetesに追加でき、標準的なKubernetesリソースと同様に管理や操作できる。

### コントローラーサービスを利用した具体的アプリケーション例

#### Argo CD

GitOpsの仕組みを実現するアプリケーションである。歴史的には、Gitを中心とした宣言的なアプリケーション管理が求められる中で、GitOpsという概念が登場しました。GitOpsの運用を容易にするため、Argo CDはGitリポジトリに置かれた宣言的な設定を監視している。

具体的には、Argo CDが提供する『Application』というCustom Resource(CR)を利用する。Application CRには、「どのGitリポジトリを対象にするか」「対象のリポジトリのどのパスを参照するか」「どのクラスタに展開するか」などが記述されている。


![コントローラーサービス_argocd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/d2deddf8-bbe8-4ed7-9be6-db8cfb2c8ba3.png)

Argo CDは図のような要素で構成されおり、コントローラーサービス同じようなステップになっている。

- 観察：
  - 指定されたGitリポジトリとKubernetesクラスタを監視
  - Gitリポジトリ上の定義とクラスタ内の現在の状態を取得
- 分析：
  - Gitリポジトリ内の定義とKubernetesクラスタの現在の状態を比較・差分特定
- 行動：
  - 差分が存在する場合、自動的にKubernetesクラスタをGitリポジトリで定義された状態へと修正・同期

これにより、Gitに記述した状態が常にクラスタへ反映され、アプリケーションの安定運用が実現されている。


## オペレーターサービス

オペレーター（Operator）は、コントローラーを拡張させたものであり、カスタムリソース定義（CustomResourceDefinition: CRD）を用いて高度な調整プロセスを実現している。オペレーターサービスは、複雑なアプリケーションのライフサイクル管理を行うために考えられました。

オペレーターは、Kubernetes自体と対象となる外部アプリケーションの両方の領域を理解し、人間が行うべき作業を自動化する。オペレーターは次のように分類される。

* インストールCRD
  * 特定のアプリケーションをインストール・管理するためのCRD
    * 例）Prometheusをインストール・管理するPrometheus Operator
* アプリケーションCRD
  * アプリケーション固有のドメインロジックをKubernetesと密接に結びつけるためのCRD
    * 例）Prometheus OperatorのServiceMonitor CRD

### オペレーターサービスを利用した具体的アプリケーション例

#### Prometheus Operator

Kubernetes上でPrometheusの監視設定を自動的に管理する。具体的には、「ServiceMonitor」というCRDを用いて監視対象を動的に管理する。ServiceMonitorは、監視対象のServiceを定義するリソースで、ラベルによって対象のServiceを特定する。

![Prometheus-Operator02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976553/f7f7a3a2-94d0-4302-a360-47a27c3ad7ab.png)


Prometheus Operatorのアーキテクチャは図のような要素で構成されている。

- 観察：
  - ServiceMonitorリソースを常に監視
  - 変更があれば、差分を検知
- 分析：
  - 変更されたServiceMonitorを元に、監視対象のServiceリソースを特定
- 行動：
  - 対象のServiceのエンドポイント情報を収集
  - 自動的にPrometheusの設定ファイルを更新
  - Prometheusは常に最新の監視対象を把握し、スクレイピング

これにより、監視設定の手動更新が不要となり、設定を常に最新状態に保つことができる。

#### CloudNativePG（PostgreSQL Operator）

PostgreSQLのクラスタをKubernetes上で運用するためのオペレーターである。具体的には、CloudNativePGオペレーターは、「PostgreSQLCluster」というCRDを活用してPostgreSQLクラスタの状態を宣言的に定義している。このCRDには、クラスタの規模、レプリケーション設定、バックアップポリシー、リカバリ方法などが含まれている。

CloudNativePGのアーキテクチャは次の要素で構成されている。

- 観察：
  - オペレーターはPostgreSQLCluster CRDを監視
  - リソースの変更やイベントを検知
  - Kubernetesリソースの状態も継続的に監視
- 分析：
  - クラスタの実際の状態とPostgreSQLClusterで定義された理想の状態を比較して差分を特定
- 行動：
  - 差分がある場合、StatefulSetやPVCの追加・削除・変更
  - クラスタのスケーリング、バックアップの実施、フェイルオーバー処理などのアクションを自動実施

これにより、複雑なデータベース運用タスクが自動化され、高度な永続性と高可用性が実現される。

# 補足

過去の記事で記載していた内容を補足として追記しています。

## Kubernetesのリソースカテゴリ

 Kubernetesのリソースカテゴリは、[『Kubernetes完全ガイド第二版』](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-Top-Gear-%E9%9D%92%E5%B1%B1/dp/4295009792)をベースとしている。

| カテゴリ                                      | 概要                                   | 
| ------------------------------------------ | ------------------------------------ | 
| **Workload APIs**<br> | アプリケーション（コンテナ）の実行を管理するためのリソース        | 
| **Service APIs**<br> | Pod内のコンテナをネットワーク経由で公開し、アクセスを提供するリソース|
| **Config APIs**<br> | コンテナで利用する設定や機密情報を管理するためのリソース  | 
| **Storage APIs**<br> | コンテナで利用する永続化データを管理するためのリソース  | 
| **Cluster APIs**<br> | クラスタ内のリソースの運用や管理、セキュリティを制御するリソース     |
| **Metadata APIs**<br>        | クラスタ内の他リソースの操作や動的なメタデータ管理を行うリソース  |

# Workload APIs（ワークロード）

WorkloadカテゴリはPodやそれを管理するコントローラを含み、コンテナ化されたワークロードのデプロイ・実行を担うオブジェクト群である。ユーザは望ましい状態を宣言し、Kubernetesのコントローラが実際の状態を調整する。下記の表では主要リソースについて説明している。

| リソース種類          | 説明とユースケース例      |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Pod**  | 最小のデプロイ単位（コンテナの集合）。単体で使うよりDeployment等で管理されることが多い  |
| **Deployment**  | ステートレスなアプリケーションの管理に使用。複数のPodレプリカを管理しローリングアップデートなどを提供する                                                     |
| **ReplicaSet**  | Deploymentから内部的に生成されるリソースで、Podの所定数維持を担う。通常は直接操作せずDeployment経由で使用する |
| **StatefulSet** | ステートフルなアプリケーションのためのリソース。各Podに安定した固有ID（ホスト名）と永続ボリュームを割り当て、順序付けたデプロイ/削除を保証する |
| **DaemonSet**   | 全て（または特定）のノード上で1つずつPodを実行するためのリソース。|
| **Job**         | 一時的なバッチ処理ジョブの実行に使用。完了すべきタスクをPodとして実行し、成功終了で完了とする  |
| **CronJob**     | 定期実行ジョブ。スケジュールに従いJobを作成する |

# 参考文献

- [Kubernetes完全ガイド](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-Top-Gear-%E9%9D%92%E5%B1%B1/dp/4295009792)
- [分散システムデザインパターン](https://www.oreilly.co.jp//books/9784873118758/)
- [Kubernetesパターン](https://www.oreilly.co.jp/books/9784814400881/)
- [Argo CDのアーキテクチャ](https://argo-cd.readthedocs.io/en/stable/operator-manual/architecture/)