# 機能設計書 37-Volume関連コントローラー

## 概要

本ドキュメントは、Kubernetes kube-controller-managerに含まれるVolume関連コントローラー群の機能設計を記述する。PersistentVolume/PersistentVolumeClaim のバインディング、Attach/Detach操作、Volume拡張を担当する複数のサブコントローラーで構成される。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesにおけるストレージ管理の中核機能を提供する。PersistentVolume（PV）とPersistentVolumeClaim（PVC）のライフサイクル管理、ノードへのボリュームアタッチ・デタッチ操作、およびボリュームの容量拡張をコントロールする。

**機能の利用シーン**：
- PVCの作成時にPVとのバインディングが自動実行される
- PodがPVCを参照してノードにスケジュールされた際にボリュームのアタッチが実行される
- Podが削除されノードからボリュームが不要になった際にデタッチが実行される
- PVCの容量変更リクエスト時にボリューム拡張が実行される

**主要な処理内容**：

**PersistentVolumeController（PV/PVCバインダー）**:
1. PVとPVCの状態を監視し、適切なバインディングを実行する
2. PVのリサイクル・削除ポリシーに基づくクリーンアップを実行する
3. StorageClassに基づく動的プロビジョニングのトリガーを管理する

**AttachDetachController**:
1. Podのスケジューリング状態を監視し、必要なボリュームアタッチを検出する
2. DesiredStateOfWorldとActualStateOfWorldの差分を検出する
3. Reconcilerが実際のアタッチ・デタッチ操作を実行する

**ExpandController**:
1. PVCの容量変更リクエストを検出する
2. CSIドライバーに対する拡張操作のアノテーションを付与する

**関連システム・外部連携**：CSIドライバー、StorageClass、VolumeAttachment API、kubelet

**権限による制御**：PV、PVC、VolumeAttachment、StorageClass、CSINode等に対するCRUD権限。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | kubectl get pv/pvc | 参照画面 | PV/PVCの状態確認 |
| - | kubectl describe pvc | 参照画面 | PVCのイベント・条件確認 |

## 機能種別

ライフサイクル管理 / ストレージ操作 / 状態同期

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| PV.Spec | v1.PersistentVolumeSpec | Yes | PVの仕様（容量、AccessModes等） | 有効なPV仕様 |
| PVC.Spec | v1.PersistentVolumeClaimSpec | Yes | PVCの仕様（要求容量、AccessModes等） | 有効なPVC仕様 |
| Pod.Spec.Volumes | []v1.Volume | No | Podのボリューム参照 | PVCまたは直接指定 |

### 入力データソース

- PV Informer: PersistentVolumeの変更イベント
- PVC Informer: PersistentVolumeClaimの変更イベント
- Pod Informer: Podの変更イベント（AttachDetachController）
- Node Informer: ノードの変更イベント（AttachDetachController）
- VolumeAttachment Informer: VolumeAttachmentの変更イベント
- StorageClass Informer: StorageClassの変更イベント
- CSINode Informer: CSINodeの変更イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PV.Spec.ClaimRef | *v1.ObjectReference | PVCへのバインド参照 |
| PVC.Spec.VolumeName | string | バインドされたPV名 |
| PV.Status.Phase | v1.PersistentVolumePhase | PV状態（Available, Bound, Released, Failed） |
| PVC.Status.Phase | v1.PersistentVolumeClaimPhase | PVC状態（Pending, Bound, Lost） |
| VolumeAttachment | storagev1.VolumeAttachment | アタッチ・デタッチ状態 |
| Node.Status.VolumesAttached | []v1.AttachedVolume | ノードにアタッチされたボリュームリスト |

### 出力先

- Kubernetes API Server（PV/PVC更新、VolumeAttachment作成・削除、Node Status更新）
- Kubernetes Events（バインド、プロビジョニング、エラーイベント）

## 処理フロー

### PV/PVCバインディング処理シーケンス

```
1. PV/PVC変更イベントを受信
   └─ volumeWorker/claimWorkerがキューからキーを取得
2. syncVolume/syncClaimを実行
   └─ PVの場合: 現在のフェーズに基づく状態遷移
      ├─ Available → バインド候補のPVCを検索
      ├─ Bound → ClaimRefの整合性を確認
      └─ Released → リサイクル/削除ポリシーを実行
   └─ PVCの場合: 現在のフェーズに基づく状態遷移
      ├─ Pending → 一致するPVを検索してバインド
      └─ Bound → PVの存在と整合性を確認
3. バインド実行
   └─ PV.Spec.ClaimRefを設定
   └─ PVC.Spec.VolumeNameを設定
   └─ 両方のフェーズをBoundに更新
```

### AttachDetach処理シーケンス

```
1. DesiredStateOfWorldPopulatorがPod/Nodeを監視
   └─ 必要なボリュームアタッチをDesiredStateに追加
2. Reconcilerが定期的にDesired vs Actualを比較
   └─ 不足 → Attach操作を実行
   └─ 過剰 → Detach操作を実行（アンマウント待ち）
3. StatusUpdaterがNode.Status.VolumesAttachedを更新
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | PV-PVCマッチング | AccessModes、容量、StorageClassが一致するPVとPVCをバインドする | PVC Pending時 |
| BR-37-02 | 最小容量選択 | 要求容量以上の最小PVを選択する | バインド候補選定時 |
| BR-37-03 | Reclaim Policy | PV解放時にRetain/Delete/Recycleポリシーに従う | PV Released時 |
| BR-37-04 | Attach前提条件 | アタッチ前にCSI Nodeのボリュームリミットをチェックする | Attach操作時 |
| BR-37-05 | Detachアンマウント待ち | デタッチ前に最大6分間アンマウントを待機する | Detach操作時 |
| BR-37-06 | ExpandController | PVC容量変更時にCSIプラグインへの拡張アノテーションを付与する | PVC容量変更時 |

### 計算ロジック

- PV-PVCマッチング: AccessModesのインデックスで候補を絞り込み、容量でソート
- Reconciler周期: 100ms（AttachDetach）
- アンマウント待ち上限: 6分

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| バインド | PV | UPDATE | ClaimRef設定、Phase更新 |
| バインド | PVC | UPDATE | VolumeName設定、Phase更新 |
| アタッチ | VolumeAttachment | CREATE | ボリュームアタッチの記録 |
| デタッチ | VolumeAttachment | DELETE | ボリュームデタッチの記録 |
| ステータス更新 | Node | PATCH (Status) | VolumesAttached更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | リソース不在 | PV/PVC/Nodeが削除されている | 正常終了扱い |
| Conflict | 競合エラー | 同時更新 | リトライ |
| Timeout | アンマウントタイムアウト | 6分以内にアンマウント完了しない | 強制デタッチ |

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

PVとPVCのバインドは2段階のAPI呼び出し（PV更新 → PVC更新）で行われる。中間状態が発生しうるが、Reconcilerにより最終整合性が保たれる。

## パフォーマンス要件

- Reconcilerループ周期: 100ms
- DesiredStateOfWorld更新周期: 1分
- Pod一覧再取得周期: 3分
- PV/PVCバインド: ワーカーベースで並列処理

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

- CSI Migration対応により、in-treeプラグインをCSIドライバーに透過的に移行
- VolumeAttachmentリソースでアタッチ状態を追跡
- ServiceAccountトークンをCSIドライバーに渡す機能（TokenRequest）

## 備考

- ExpandControllerは現在Deprecated（非推奨）であり、アノテーション付与の用途のみ残存
- PersistentVolumeControllerはVolumeIndex（AccessModesインデックス）を使用してマッチングを高速化
- AttachDetachControllerはDesired/Actual State of Worldパターンで状態管理

---

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

### 推奨読解順序

#### Step 1: 全体構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | volume/ | `pkg/controller/volume/` | ディレクトリ構成: attachdetach/, persistentvolume/, expand/, ephemeral/ |

#### Step 2: AttachDetachControllerの構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | attach_detach_controller.go | `pkg/controller/volume/attachdetach/attach_detach_controller.go` | TimerConfig（66-85行目）、DefaultTimerConfig（89-94行目） |

**読解のコツ**: AttachDetachControllerはDesired State of World（DSW）とActual State of World（ASW）の差分を検出するReconcilerパターンを使用。cache/、populator/、reconciler/、statusupdater/ の4サブパッケージに分かれる。

#### Step 3: PersistentVolumeControllerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.go | `pkg/controller/volume/persistentvolume/index.go` | persistentVolumeOrderedIndex（34-36行目）でAccessModesインデックス |

**読解のコツ**: PVの検索はAccessModesをキーとしたインデックスで高速化。容量でソートされたリストから最小容量のPVを選択する。

#### Step 4: ExpandControllerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | expand_controller.go | `pkg/controller/volume/expand/expand_controller.go` | expandController構造体（73-80行目）、Deprecated注記（71行目） |

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

```
[AttachDetachController]
NewAttachDetachController
    ├─ cache.NewDesiredStateOfWorld
    ├─ cache.NewActualStateOfWorld
    ├─ populator.NewDesiredStateOfWorldPopulator
    ├─ reconciler.NewReconciler
    └─ statusupdater.NewNodeStatusUpdater

Run
    ├─ Populator.Run (DSW更新ループ)
    ├─ Reconciler.Run (Attach/Detachループ, 100ms)
    └─ StatusUpdater.Run

[PersistentVolumeController]
NewController
    ├─ volumeWorker
    │   └─ syncVolume → updateVolumePhase
    └─ claimWorker
        └─ syncClaim → bind / unbind

[ExpandController]
NewExpandController
    └─ syncHandler
        └─ expand (アノテーション付与)
```

### データフロー図

```
[AttachDetach]
Pod/Node変更 ──▶ DSWPopulator ──▶ DesiredStateOfWorld
                                        │
                                   Reconciler (100ms)
                                        │
                              ┌────────────────────┐
                              │ Desired vs Actual   │
                              └────────┬───────────┘
                                Attach/Detach操作
                                        │
                              ActualStateOfWorld ──▶ NodeStatus更新

[PV/PVC Binder]
PV変更 ──▶ volumeQueue ──▶ syncVolume ──▶ PV Phase更新
PVC変更 ──▶ claimQueue ──▶ syncClaim ──▶ PVC Phase更新/Bind
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| attach_detach_controller.go | `pkg/controller/volume/attachdetach/attach_detach_controller.go` | ソース | AttachDetachController |
| cache/ | `pkg/controller/volume/attachdetach/cache/` | ソース | DSW/ASWキャッシュ |
| populator/ | `pkg/controller/volume/attachdetach/populator/` | ソース | DSW更新 |
| reconciler/ | `pkg/controller/volume/attachdetach/reconciler/` | ソース | Attach/Detach実行 |
| statusupdater/ | `pkg/controller/volume/attachdetach/statusupdater/` | ソース | Node Status更新 |
| index.go | `pkg/controller/volume/persistentvolume/index.go` | ソース | PVインデックス |
| expand_controller.go | `pkg/controller/volume/expand/expand_controller.go` | ソース | Volume拡張 |
