# 機能設計書 90-ロールアウト管理（rollout）

## 概要

本ドキュメントは、kubectlの`rollout`コマンドによるロールアウト管理機能の設計を記述する。Deployment、DaemonSet、StatefulSetのロールアウト（デプロイメント）のステータス確認、履歴表示、ロールバック、一時停止/再開、再起動を管理するコマンド群を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesのワークロードリソースのデプロイメントライフサイクルを管理するための包括的なツールセットを提供する。安全なロールアウト、問題発生時のロールバック、段階的デプロイメント（一時停止/再開）など、本番環境でのデプロイメント管理に不可欠な機能群である。

**機能の利用シーン**：Deploymentのロールアウト状態監視、問題発生時の特定リビジョンへのロールバック、カナリアデプロイメント（一時停止/再開）、ローリングリスタートの実行、デプロイメント履歴の確認など。

**主要な処理内容**：
- **rollout status**: ロールアウトの進行状況をリアルタイムで監視
- **rollout history**: ロールアウトのリビジョン履歴を表示
- **rollout undo**: 前のリビジョンにロールバック
- **rollout pause**: ロールアウトの一時停止
- **rollout resume**: ロールアウトの再開
- **rollout restart**: ローリングリスタートのトリガー

**関連システム・外部連携**：API Serverに対してGET/PATCH/Watchリクエストを送信する。

**権限による制御**：対象リソースに対するget、patch権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | kubectl rollout | 主機能 | ワークロードリソースのロールアウトを管理する |

## 機能種別

操作管理 / デプロイメントライフサイクル管理

## 入力仕様

### 入力パラメータ

#### rollout status

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TYPE NAME | string | Yes | リソースタイプと名前 | deployment/daemonset/statefulset |
| -w / --watch | bool | No | ステータスの監視 | デフォルトtrue |
| --revision | int64 | No | 監視するリビジョン | 0以上 |
| --timeout | duration | No | 監視タイムアウト | デフォルト0（無制限） |
| -l / --selector | string | No | ラベルセレクター | - |
| -f / --filename | string[] | No | ファイルからリソース指定 | - |

#### rollout undo

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TYPE NAME | string | Yes | リソースタイプと名前 | deployment/daemonset/statefulset |
| --to-revision | int64 | No | ロールバック先リビジョン | デフォルト0（前リビジョン） |
| --dry-run | string | No | DryRun戦略 | none/client/server |
| -l / --selector | string | No | ラベルセレクター | - |

#### rollout history

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TYPE NAME | string | Yes | リソースタイプと名前 | deployment/daemonset/statefulset |
| --revision | int64 | No | 表示するリビジョン | 0以上 |
| -l / --selector | string | No | ラベルセレクター | - |

#### rollout pause / resume / restart

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TYPE NAME | string | Yes | リソースタイプと名前 | deployment/daemonset/statefulset |
| -l / --selector | string | No | ラベルセレクター | restart時のみ |

### 入力データソース

- コマンドライン引数
- ファイル指定（-f）

## 出力仕様

### 出力データ

| サブコマンド | 出力内容 | 例 |
|------------|---------|---|
| status | ロールアウトの進行状態 | deployment "nginx" successfully rolled out |
| history | リビジョン一覧または詳細 | REVISION CHANGE-CAUSE |
| undo | ロールバック結果 | deployment.apps/nginx rolled back |
| pause | 一時停止結果 | deployment.apps/nginx paused |
| resume | 再開結果 | deployment.apps/nginx resumed |
| restart | 再起動結果 | deployment.apps/nginx restarted |

### 出力先

- 標準出力（stdout）：操作結果メッセージ
- 標準エラー出力（stderr）：リソース未検出メッセージ

## 処理フロー

### 処理シーケンス（rollout status）

```
1. NewCmdRolloutStatus: コマンド定義
2. Complete: オプション補完
3. Validate: バリデーション
4. Run: ステータス監視
   ├─ Builder.Do(): リソース検索
   └─ r.Visit: 各リソースの処理
       ├─ StatusViewerFn: StatusViewer取得
       ├─ ListWatch設定
       └─ UntilWithSync: Watch APIでステータス監視
           ├─ Added/Modified: statusViewer.Status → 結果表示
           └─ Deleted: エラー（オブジェクト削除）
```

### 処理シーケンス（rollout undo）

```
1. NewCmdRolloutUndo: コマンド定義
2. Complete: オプション補完
3. Validate: バリデーション
4. RunUndo: ロールバック実行
   ├─ Builder.Do(): リソース検索
   └─ r.Visit: 各リソースの処理
       ├─ RollbackerFn: Rollbacker取得
       ├─ rollbacker.Rollback(toRevision)
       └─ PrintObj: 結果表示
```

### フローチャート（rollout status）

```mermaid
flowchart TD
    A[開始: Run] --> B[Builder.Do]
    B --> C[r.Visit]
    C --> D[StatusViewerFn]
    D --> E[ListWatch設定]
    E --> F[UntilWithSync]
    F --> G{イベント種別?}
    G -->|Added/Modified| H[statusViewer.Status]
    H --> I{done?}
    I -->|Yes| J[成功終了]
    I -->|No| K{--watch?}
    K -->|Yes| F
    K -->|No| L[現在のステータスで終了]
    G -->|Deleted| M[エラー: object deleted]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 対象リソースタイプ | deployment、daemonset、statefulsetのみ | 全サブコマンド |
| BR-02 | revision正数制約 | --revisionは0以上の整数 | status、history |
| BR-03 | watchデフォルト | statusのwatchはデフォルトtrue | rollout status |
| BR-04 | リビジョン0 | --to-revision=0は直前のリビジョン | rollout undo |
| BR-05 | 削除検出 | Watch中にオブジェクトが削除されたらエラー | rollout status |
| BR-06 | 新リビジョン自動追従 | Watch中に新しいロールアウトが開始されたら自動的に追従 | rollout status |

### 計算ロジック

特になし。ステータス判定はpolymorphichelpers.StatusViewerが各リソースタイプに応じて実装する。

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

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

| サブコマンド | 操作種別 | 概要 |
|------------|---------|------|
| status | SELECT + WATCH | リソース状態の取得と監視 |
| history | SELECT | リビジョン履歴の取得 |
| undo | SELECT + UPDATE | リビジョン取得とロールバック適用 |
| pause | UPDATE | spec.pausedフィールドの更新 |
| resume | UPDATE | spec.pausedフィールドの更新 |
| restart | UPDATE | spec.template.metadata.annotationsの更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | リソース未指定 | リソースタイプと名前を指定 |
| - | バリデーションエラー | revision負数 | 正の整数を指定 |
| - | Watch中エラー | オブジェクトが削除された | リソースの状態を確認 |
| - | タイムアウト | --timeout超過 | タイムアウトを延長 |

### リトライ仕様

rollout statusはWatch APIを使用して継続的にステータスを監視する。タイムアウトはwatchtools.ContextWithOptionalTimeoutで制御。

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

各リソースは個別に処理される。

## パフォーマンス要件

- rollout statusはWatch APIを使用するためロングポーリング
- タイムアウト0は無制限待機

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

- 対象リソースに対するget、patch権限が必要（RBAC）
- undoのDryRunでロールバック結果を事前確認可能

## 備考

- rolloutコマンドはサブコマンドパターンであり、rollout.go自体は各サブコマンドの登録のみを行う
- 対象リソースタイプはpolymorphichelpers パッケージで拡張可能
- restartサブコマンドはspec.template.metadata.annotationsに`kubectl.kubernetes.io/restartedAt`を設定することでローリングリスタートをトリガーする

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | rollout.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout.go` | NewCmdRollout関数（57-75行目）で6つのサブコマンド登録を確認 |

**読解のコツ**: rollout.goは薄いラッパーで、実際のロジックは各サブコマンドファイルに分散している。

#### Step 2: rollout status を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rollout_status.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_status.go` | RolloutStatusOptions構造体（64-82行目） |
| 2-2 | rollout_status.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_status.go` | Run関数（160-243行目）でWatch APIを使用したステータス監視を理解 |

**主要処理フロー**:
- **186-196行目**: ListWatch設定（DynamicClient使用）
- **199行目**: ContextWithOptionalTimeoutでタイムアウト制御
- **202-229行目**: UntilWithSyncによるWatch処理
  - **204-218行目**: Added/Modifiedイベントでステータス確認
  - **222-224行目**: Deletedイベントでエラー

#### Step 3: rollout undo を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rollout_undo.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go` | UndoOptions構造体（38-53行目） |
| 3-2 | rollout_undo.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go` | RunUndo関数（141-179行目） |

**主要処理フロー**:
- **160行目**: RollbackerFnでRollbacker取得
- **165行目**: rollbacker.Rollback(toRevision, dryRunStrategy)

#### Step 4: rollout history を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | rollout_history.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_history.go` | RolloutHistoryOptions構造体（50-67行目） |
| 4-2 | rollout_history.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_history.go` | Run関数（142-231行目） |

**主要処理フロー**:
- **163-201行目**: -o指定時のJSON/YAML出力
- **204-230行目**: テキスト出力（ViewHistory）

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

```
NewCmdRollout (rollout.go:57)
    │
    ├─ NewCmdRolloutStatus (rollout_status.go:96)
    │      └─ Run → UntilWithSync(Watch API)
    │             └─ statusViewer.Status
    │
    ├─ NewCmdRolloutHistory (rollout_history.go:78)
    │      └─ Run → historyViewer.ViewHistory / GetHistory
    │
    ├─ NewCmdRolloutUndo (rollout_undo.go:80)
    │      └─ RunUndo → rollbacker.Rollback
    │
    ├─ NewCmdRolloutPause (rollout_pause.go)
    │      └─ RunPause → ObjectPauser
    │
    ├─ NewCmdRolloutResume (rollout_resume.go)
    │      └─ RunResume → ObjectResumer
    │
    └─ NewCmdRolloutRestart (rollout_restart.go)
           └─ RunRestart → ObjectRestarter
```

### データフロー図

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

TYPE/NAME ──▶ Builder.Do() ──▶ サブコマンド処理
                                   │
                    ┌──── status ──▶ Watch API → statusViewer.Status ──▶ stdout
                    │
                    ├──── history ──▶ HistoryViewer.ViewHistory ──▶ stdout
                    │
                    ├──── undo ──▶ Rollbacker.Rollback ──▶ API Server PATCH ──▶ stdout
                    │
                    ├──── pause ──▶ ObjectPauser ──▶ API Server PATCH ──▶ stdout
                    │
                    ├──── resume ──▶ ObjectResumer ──▶ API Server PATCH ──▶ stdout
                    │
                    └──── restart ──▶ ObjectRestarter ──▶ API Server PATCH ──▶ stdout
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| rollout.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout.go` | ソース | 親コマンド定義・サブコマンド登録 |
| rollout_status.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_status.go` | ソース | statusサブコマンド |
| rollout_history.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_history.go` | ソース | historyサブコマンド |
| rollout_undo.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go` | ソース | undoサブコマンド |
| rollout_pause.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_pause.go` | ソース | pauseサブコマンド |
| rollout_resume.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_resume.go` | ソース | resumeサブコマンド |
| rollout_restart.go | `staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart.go` | ソース | restartサブコマンド |
