# 機能設計書 8-ReplicaSetコントローラー

## 概要

本ドキュメントは、Kubernetes ReplicaSetコントローラーの機能設計書である。指定されたレプリカ数のPodを維持するようにPodの作成・削除を管理する。

### 本機能の処理概要

ReplicaSetコントローラーは、ReplicaSetリソースで定義された目標レプリカ数と実際に稼働しているPod数を比較し、過不足があればPodの作成または削除を行う。Deploymentコントローラーの下位層として機能し、Podの実際の管理を担当する。

**業務上の目的・背景**：アプリケーションの可用性を保証するために、常に指定された数のPodレプリカが稼働していることを保証する。ノード障害やPodクラッシュによりPod数が目標を下回った場合は自動的に新しいPodを作成し、不要なPodが存在する場合は削除する。この自己回復機能により、運用者が手動でPod数を管理する必要がなくなる。

**機能の利用シーン**：Deploymentによるアプリケーション管理の内部動作として自動的に使用される。直接ReplicaSetを操作するケースは稀だが、スケールアウト/イン時のPod管理、ノード障害時のPod自動復旧、ローリングアップデート時の新旧Pod管理など。

**主要な処理内容**：
1. ReplicaSetリソースの監視（Informer経由）
2. ラベルセレクターに基づくPodの所有権管理（adopt/release）
3. 目標レプリカ数と実際のPod数の比較
4. 不足分のPodのバッチ作成（BurstReplicas=500制限）
5. 超過分のPodの削除（優先度に基づく選択）
6. ReplicaSetステータスの更新
7. Expectationsパターンによる重複操作防止

**関連システム・外部連携**：API Server（Pod/ReplicaSetリソースの読み書き）、スケジューラー（作成されたPodのノード割り当て）

**権限による制御**：ReplicaSetの操作にはapps/replicasetsリソースへのRBACアクセス権が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | kubectl rollout | API連携 | ロールアウト時にReplicaSetの作成・スケーリングが行われる |
| 10 | kubectl scale | API連携 | ReplicaSetコントローラーが目標レプリカ数に合わせてPodを作成/削除する |

## 機能種別

コントローラー / リコンシリエーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ReplicaSet.Spec.Replicas | *int32 | No | 目標レプリカ数（デフォルト1） | 0以上 |
| ReplicaSet.Spec.Selector | LabelSelector | Yes | Pod選択ラベルセレクター | 不変 |
| ReplicaSet.Spec.Template | PodTemplateSpec | Yes | Podテンプレート | 有効なPod仕様 |
| ReplicaSet.Spec.MinReadySeconds | int32 | No | Podが利用可能と判定されるまでの秒数 | 0以上 |

### 入力データソース

API Server経由のInformer（ReplicaSet, Pod）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Pod | v1.Pod | 作成されるPodリソース |
| ReplicaSet.Status | ReplicaSetStatus | ReplicaSetのステータス更新 |
| Event | v1.Event | Pod作成/削除イベント |

### 出力先

API Server経由でetcdに永続化

## 処理フロー

### 処理シーケンス

```
1. Informerからのイベント検知
   └─ ReplicaSet/Podの変更をWorkQueueにエンキュー
2. syncReplicaSet（メインリコンシリエーションループ）
   └─ WorkQueueからReplicaSetキーを取得して同期処理開始
3. Pod所有権の解決
   └─ ラベルセレクターに一致するPodを取得し、ControllerRefに基づきadopt/release
4. レプリカ数の差分計算
   └─ 目標レプリカ数 - アクティブPod数 = 作成/削除すべきPod数
5. Pod作成（不足時）
   └─ BurstReplicas制限内でバッチ作成（slowStartBatch）
6. Pod削除（超過時）
   └─ 優先度に基づき削除対象Podを選択して削除
7. ステータス更新
   └─ ReplicaSet.Statusのレプリカ数を更新
```

### フローチャート

```mermaid
flowchart TD
    A[Informerイベント] --> B[WorkQueueエンキュー]
    B --> C[syncReplicaSet]
    C --> D[Pod所有権解決]
    D --> E{レプリカ差分}
    E -->|不足| F[Pod バッチ作成]
    E -->|超過| G[Pod 選択削除]
    E -->|一致| H[ステータス更新]
    F --> H
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-1 | BurstReplicas | 1回のsyncで最大500個のPodを作成/削除 | Pod作成/削除時 |
| BR-2 | slowStartBatch | Pod作成は1, 2, 4, 8, ...と指数的にバッチサイズを増加 | Pod作成時 |
| BR-3 | Expectations | 未確認のPod作成/削除がある場合はsyncをスキップ | 重複操作防止 |
| BR-4 | Pod削除優先度 | Pending > Unknown > NotReady > Ready、同条件なら若いPodを残す | Pod削除時 |
| BR-5 | statusUpdateRetries | ステータス更新は最大1回リトライ | ステータス更新失敗時 |
| BR-6 | ControllerRef管理 | OwnerReferenceに基づくPodの所有権管理（adopt/release） | 全sync時 |

### 計算ロジック

- 作成すべきPod数 = spec.replicas - activePodsCount（BurstReplicasでキャップ）
- 削除すべきPod数 = activePodsCount - spec.replicas（BurstReplicasでキャップ）
- slowStartBatch: 初回1、成功ごとに倍増（1, 2, 4, 8, 16, ...最大BurstReplicas）

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Pod作成 | etcd | INSERT | PodTemplateに基づくPodの作成 |
| Pod削除 | etcd | DELETE | 超過Podの削除 |
| ReplicaSet Status更新 | etcd | UPDATE | レプリカ数のステータス更新 |

### テーブル別操作詳細

#### etcd

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | /registry/pods/{namespace}/{name} | PodTemplate + OwnerReference | generateName使用 |
| DELETE | /registry/pods/{namespace}/{name} | 削除対象Pod | gracePeriodSeconds考慮 |
| UPDATE | /registry/replicasets/{namespace}/{name} | status フィールド | レプリカ数更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Pod作成失敗 | ResourceQuota超過、NodeSelector不一致 | ResourceQuotaやNode設定を確認 |
| - | Pod削除失敗 | Pod既に削除済み | 正常（次のsyncで解消） |
| - | ステータス更新Conflict | 並行更新による競合 | 自動リトライ（1回） |

### リトライ仕様

ワークキューのrate limiterにより自動リトライ。slowStartBatchのバッチ内エラーは後続バッチサイズに影響しない。

## トランザクション仕様

Pod作成/削除は個別にAPI Server経由でアトミックに実行。バッチ作成は並列ゴルーチンで行われるが、各Pod作成は独立したトランザクション。

## パフォーマンス要件

- BurstReplicas=500により、大規模スケーリング時のAPI Server負荷を制限
- slowStartBatchにより、作成エラー時の無駄なAPI呼び出しを抑制

## セキュリティ考慮事項

- ReplicaSetの操作にはapps/replicasetsリソースへの適切なRBAC権限が必要
- Pod作成時のセキュリティコンテキストはPod Security Admissionで検証される

## 備考

ReplicaSetコントローラーはReplicationController（旧API）も処理可能。ReplicationControllerのオブジェクトはReplicaSetに変換されて同じコントローラーロジックで処理される。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | replica_set.go | `pkg/controller/replicaset/replica_set.go` | ReplicaSetController構造体（**84-119行目**）。GroupVersionKind, kubeClient, podControl, burstReplicas, expectations, rsLister, podLister, queueフィールド |

**読解のコツ**: **17-26行目**のコメントに注意。このコードはReplicaSetとReplicationControllerの両方を処理する。`rsc.Kind`で適切なリソースタイプを参照すること。BurstReplicas=500（**72行目**）がバッチサイズ上限。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | replica_set.go | `pkg/controller/replicaset/replica_set.go` | NewReplicaSetController / NewBaseController関数でInformerイベントハンドラを登録 |

#### Step 3: 同期処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | replica_set.go | `pkg/controller/replicaset/replica_set.go` | syncReplicaSet関数でメインリコンシリエーション実行 |
| 3-2 | replica_set_utils.go | `pkg/controller/replicaset/replica_set_utils.go` | ユーティリティ関数（Pod所有権管理等） |

### プログラム呼び出し階層図

```
ReplicaSetController.Run()
    │
    ├─ worker() → processNextWorkItem()
    │      │
    │      └─ syncReplicaSet()
    │             │
    │             ├─ claimPods() → Pod所有権管理（adopt/release）
    │             │
    │             ├─ manageReplicas()
    │             │      ├─ [不足] slowStartBatch() → createPod()
    │             │      └─ [超過] getPodsToDelete() → deletePod()
    │             │
    │             └─ calculateStatus() → updateReplicaSetStatus()
    │
    └─ Informer Event Handlers
           ├─ addRS() / updateRS() / deleteRS()
           └─ addPod() / updatePod() / deletePod()
```

### データフロー図

```
[入力]                      [処理]                          [出力]

ReplicaSet Spec ──────▶ ReplicaSetController ──────▶ Pod (作成/削除)
├─ replicas               ├─ syncReplicaSet()            ├─ ownerReference
├─ selector               ├─ claimPods()                 └─ PodTemplate由来
└─ template               ├─ manageReplicas()
                           └─ calculateStatus()     ReplicaSet Status
                                                     ├─ replicas
Pod Status ────────────▶ 差分計算 ──────────────▶ ├─ readyReplicas
                                                     ├─ availableReplicas
                                                     └─ fullyLabeledReplicas
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| replica_set.go | `pkg/controller/replicaset/replica_set.go` | ソース | コントローラー本体 |
| replica_set_utils.go | `pkg/controller/replicaset/replica_set_utils.go` | ソース | ユーティリティ関数 |
| doc.go | `pkg/controller/replicaset/doc.go` | ソース | パッケージドキュメント |
| metrics/ | `pkg/controller/replicaset/metrics/` | ソース | コントローラーメトリクス |
| config/ | `pkg/controller/replicaset/config/` | ソース | コントローラー設定 |
