# 機能設計書 7-Deploymentコントローラー

## 概要

本ドキュメントは、Kubernetes Deploymentコントローラーの機能設計書である。Deploymentリソースの宣言的更新を管理し、ローリングアップデート、ロールバック、スケーリングを制御する。

### 本機能の処理概要

Deploymentコントローラーは、Deploymentリソースの望ましい状態（desired state）と実際の状態（actual state）を比較し、ReplicaSetの作成・スケーリングを通じて宣言的なアプリケーション更新を実現する。

**業務上の目的・背景**：ステートレスアプリケーションのデプロイ・更新を安全かつ自動的に行うための中核機能である。ゼロダウンタイムでのローリングアップデート、更新に問題があった場合の自動ロールバック、レプリカ数の宣言的管理により、運用者はアプリケーションの望ましい状態を宣言するだけでよく、実際の更新プロセスはコントローラーが自動的に制御する。

**機能の利用シーン**：Webアプリケーションのデプロイと更新、コンテナイメージのバージョンアップ、レプリカ数の変更（スケールアウト/イン）、更新の一時停止と再開、問題発生時のロールバック、カナリアデプロイの実現など。

**主要な処理内容**：
1. Deploymentリソースの監視（Informer経由）
2. ReplicaSetの作成・更新・削除管理
3. ローリングアップデート戦略の実行（maxSurge/maxUnavailable制御）
4. Recreate戦略の実行（全Pod停止後に新Pod起動）
5. ロールバック処理（以前のReplicaSetリビジョンへの復帰）
6. プロポーショナルスケーリング（更新中の比例的レプリカ配分）
7. デプロイメント進捗の監視とCondition更新

**関連システム・外部連携**：ReplicaSetコントローラー（Pod管理の委譲先）、API Server（リソースの読み書き）、etcd（永続化）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | kubectl rollout | API連携 | ロールアウト操作の結果としてDeploymentコントローラーがローリングアップデートを制御する |
| 10 | kubectl scale | API連携 | スケーリング結果としてDeploymentコントローラーがレプリカ数を調整する |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Deployment.Spec.Replicas | *int32 | No | 目標レプリカ数（デフォルト1） | 0以上 |
| Deployment.Spec.Strategy.Type | string | No | 更新戦略（RollingUpdate/Recreate） | 有効な戦略タイプ |
| Deployment.Spec.Strategy.RollingUpdate.MaxSurge | IntOrString | No | 更新中の最大超過Pod数（デフォルト25%） | 0以上 |
| Deployment.Spec.Strategy.RollingUpdate.MaxUnavailable | IntOrString | No | 更新中の最大利用不可Pod数（デフォルト25%） | 0以上 |
| Deployment.Spec.RevisionHistoryLimit | *int32 | No | 保持するリビジョン履歴数（デフォルト10） | 0以上 |
| Deployment.Spec.ProgressDeadlineSeconds | *int32 | No | 進捗デッドライン秒数（デフォルト600） | 0以上 |
| Deployment.Spec.Paused | bool | No | 一時停止フラグ | - |
| Deployment.Spec.Selector | LabelSelector | Yes | Pod選択ラベルセレクター | 不変（作成後変更不可） |
| Deployment.Spec.Template | PodTemplateSpec | Yes | Podテンプレート | 有効なPod仕様 |

### 入力データソース

API Server経由のInformer（Deployment, ReplicaSet, Pod）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReplicaSet | apps/v1.ReplicaSet | 作成/更新されるReplicaSetリソース |
| Deployment.Status | DeploymentStatus | Deploymentのステータス更新 |
| Event | v1.Event | デプロイメント関連イベント |

### 出力先

API Server経由でetcdに永続化

## 処理フロー

### 処理シーケンス

```
1. Informerからのイベント検知
   └─ Deployment/ReplicaSet/Podの変更をWorkQueueにエンキュー
2. syncDeployment（メインリコンシリエーションループ）
   └─ WorkQueueからDeploymentキーを取得して同期処理開始
3. リビジョン管理
   └─ 全ReplicaSetの取得とリビジョン番号の同期
4. 戦略判定
   └─ 一時停止/スケーリング/ローリングアップデート/Recreateを判定
5. 戦略実行
   └─ 判定結果に基づきReplicaSetのスケーリングを実行
6. ステータス更新
   └─ Deployment.Statusのレプリカ数、条件等を更新
7. クリーンアップ
   └─ RevisionHistoryLimitを超過した古いReplicaSetを削除
```

### フローチャート

```mermaid
flowchart TD
    A[Informerイベント] --> B[WorkQueueエンキュー]
    B --> C[syncDeployment]
    C --> D{Deploymentの状態}
    D -->|一時停止中| E[syncStatusOnly]
    D -->|スケーリングのみ| F[sync - scale処理]
    D -->|RollingUpdate| G[rolloutRolling]
    D -->|Recreate| H[rolloutRecreate]
    E --> I[ステータス更新]
    F --> I
    G --> G1[新ReplicaSetスケールアップ]
    G1 --> G2[旧ReplicaSetスケールダウン]
    G2 --> I
    H --> H1[旧ReplicaSet全停止]
    H1 --> H2[新ReplicaSet起動]
    H2 --> I
    I --> J[クリーンアップ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-1 | maxRetries | 最大15回リトライ後にワークキューから除外（5ms*2^(n-1)のバックオフ） | syncDeployment失敗時 |
| BR-2 | プロポーショナルスケーリング | 複数ReplicaSetが存在する場合、レプリカ数を比例配分 | ローリングアップデート中のスケーリング |
| BR-3 | ProgressDeadline | 進捗がない場合、ProgressDeadlineSecondsを超過するとProgressing条件をFalseに更新 | ローリングアップデート中 |
| BR-4 | RevisionHistoryLimit | 指定数を超えた古いReplicaSet（replicas=0）を削除 | デプロイメント完了後 |
| BR-5 | PodTemplate Hash | ReplicaSet名にPodTemplateのハッシュを付与して一意性を保証 | ReplicaSet作成時 |

### 計算ロジック

ローリングアップデート時のレプリカ計算:
- maxSurge: deployment.replicas + maxSurge（合計レプリカ上限）
- maxUnavailable: deployment.replicas - maxUnavailable（利用可能レプリカ下限）
- 新ReplicaSetのスケールアップ上限 = maxSurge - 現在の全レプリカ数
- 旧ReplicaSetのスケールダウン数 = 全レプリカ数 - (deployment.replicas - maxUnavailable)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ReplicaSet作成 | etcd | INSERT | 新しいReplicaSetを作成 |
| ReplicaSet更新 | etcd | UPDATE | ReplicaSetのレプリカ数を更新 |
| ReplicaSet削除 | etcd | DELETE | 古いReplicaSetを削除（クリーンアップ） |
| Deployment Status更新 | etcd | UPDATE | Deploymentのステータスを更新 |

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

#### etcd

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | /registry/replicasets/{namespace}/{name} | 新ReplicaSet（PodTemplateハッシュ付き名前） | Deployment.Specに基づいて生成 |
| UPDATE | /registry/replicasets/{namespace}/{name} | spec.replicas の更新 | スケーリング時 |
| DELETE | /registry/replicasets/{namespace}/{name} | - | RevisionHistoryLimit超過分 |
| UPDATE | /registry/deployments/{namespace}/{name} | status フィールド | ステータス更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ReplicaSet作成失敗 | API Server通信エラー | 自動リトライ（最大15回） |
| - | スケーリング失敗 | ResourceQuota超過 | ResourceQuotaを調整 |
| - | ProgressDeadline超過 | Podが起動しない | Podの状態を確認、イメージ/リソース設定を修正 |

### リトライ仕様

Exponential Backoffで最大15回リトライ。5ms, 10ms, 20ms, ..., 最大約82秒のバックオフ間隔。

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

各ReplicaSetの更新はAPI Server経由でアトミックに実行（resourceVersionによる楽観的排他制御）。Deployment全体の更新はステータスパッチで行われる。

## パフォーマンス要件

- Informerイベント検知後のリコンシリエーション開始: 即時（WorkQueue経由）
- ローリングアップデートの進行速度: maxSurge/maxUnavailableによって制御

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

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

## 備考

DeploymentコントローラーはReplicaSetを直接操作し、Pod管理はReplicaSetコントローラーに委譲する。この2層構造により、更新戦略の柔軟性とPod管理の効率性を両立している。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | deployment_controller.go | `pkg/controller/deployment/deployment_controller.go` | DeploymentController構造体（**67-100行目**）。rsControl, client, syncHandler, dLister, rsLister, podLister, queueフィールドを確認 |

**読解のコツ**: `syncHandler`フィールドはテスト用のインジェクションポイント。実際は`syncDeployment`メソッドが設定される（**152行目**）。Informerパターンを理解していると読みやすい。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | deployment_controller.go | `pkg/controller/deployment/deployment_controller.go` | NewDeploymentController関数（**104行目**）でInformerのイベントハンドラを登録。Run関数（**171行目**）でワーカーゴルーチンを起動 |

**主要処理フロー**:
1. **104行目**: NewDeploymentControllerでコントローラー初期化
2. **123-150行目**: Deployment, ReplicaSet, PodのInformerにイベントハンドラ登録
3. **171行目**: Run関数でキャッシュ同期待機後、ワーカー起動
4. **189行目**: WaitForNamedCacheSyncWithContextでInformerキャッシュの同期を待機
5. **193-197行目**: 指定数のワーカーゴルーチンを起動

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sync.go | `pkg/controller/deployment/sync.go` | syncStatusOnly（**45行目**）、sync（**57行目**）でスケーリングとクリーンアップ処理 |
| 3-2 | rolling.go | `pkg/controller/deployment/rolling.go` | rolloutRolling（**31行目**）でローリングアップデートロジック。reconcileNewReplicaSet（**68行目**）とreconcileOldReplicaSets |
| 3-3 | recreate.go | `pkg/controller/deployment/recreate.go` | rolloutRecreate（**29行目**）でRecreate戦略。旧RS停止→新RS起動の順序 |

**主要処理フロー**（rolling.go）:
- **31行目**: rolloutRolling関数 - ローリングアップデートのメインロジック
- **39行目**: reconcileNewReplicaSetでスケールアップ判定
- **49行目**: reconcileOldReplicaSetsでスケールダウン判定
- **58行目**: deploymentCompleteチェック後にクリーンアップ

#### Step 4: 進捗管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | progress.go | `pkg/controller/deployment/progress.go` | ProgressDeadlineの管理とDeployment Conditionの更新 |

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

```
DeploymentController.Run()
    │
    ├─ worker() → processNextWorkItem()
    │      │
    │      └─ syncDeployment()
    │             │
    │             ├─ getReplicaSetsForDeployment()
    │             ├─ getPodMapForDeployment()
    │             │
    │             ├─ [一時停止中] syncStatusOnly()
    │             │      └─ syncDeploymentStatus()
    │             │
    │             ├─ [スケーリング] sync()
    │             │      ├─ scale()
    │             │      ├─ cleanupDeployment()
    │             │      └─ syncDeploymentStatus()
    │             │
    │             ├─ [RollingUpdate] rolloutRolling()
    │             │      ├─ reconcileNewReplicaSet() → scaleReplicaSet()
    │             │      ├─ reconcileOldReplicaSets() → scaleReplicaSet()
    │             │      ├─ cleanupDeployment()
    │             │      └─ syncRolloutStatus()
    │             │
    │             └─ [Recreate] rolloutRecreate()
    │                    ├─ scaleDownOldReplicaSetsForRecreate()
    │                    ├─ scaleUpNewReplicaSetForRecreate()
    │                    └─ syncRolloutStatus()
    │
    └─ Informer Event Handlers
           ├─ addDeployment() / updateDeployment() / deleteDeployment()
           ├─ addReplicaSet() / updateReplicaSet() / deleteReplicaSet()
           └─ deletePod()
```

### データフロー図

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

Deployment Spec ──────▶ DeploymentController ──────▶ ReplicaSet (新規作成/更新)
├─ replicas               ├─ syncDeployment()              ├─ spec.replicas
├─ strategy               ├─ rolloutRolling()              └─ annotations (revision)
├─ template               ├─ rolloutRecreate()
└─ selector               └─ sync()                    Deployment Status
                                                        ├─ replicas
ReplicaSet Status ─────▶ ステータス計算 ──────────▶ ├─ updatedReplicas
Pod Status ────────────▶                              ├─ readyReplicas
                                                        ├─ availableReplicas
                                                        └─ conditions
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| deployment_controller.go | `pkg/controller/deployment/deployment_controller.go` | ソース | コントローラー本体（構造体、初期化、ワーカー） |
| sync.go | `pkg/controller/deployment/sync.go` | ソース | 同期処理、スケーリング、ステータス更新 |
| rolling.go | `pkg/controller/deployment/rolling.go` | ソース | ローリングアップデート戦略 |
| recreate.go | `pkg/controller/deployment/recreate.go` | ソース | Recreate戦略 |
| rollback.go | `pkg/controller/deployment/rollback.go` | ソース | ロールバック処理 |
| progress.go | `pkg/controller/deployment/progress.go` | ソース | 進捗監視とCondition管理 |
| util/ | `pkg/controller/deployment/util/` | ソース | ユーティリティ関数（リビジョン管理等） |
| config/ | `pkg/controller/deployment/config/` | ソース | コントローラー設定 |
