# 機能設計書 57-ボリューム管理

## 概要

本ドキュメントは、KubeletのVolume Managerによる、Podに必要なボリュームのAttach、Mount、Unmount、Detachを管理する機能の設計を記載する。

### 本機能の処理概要

KubeletのVolume Managerは、スケジュールされたPodが必要とするボリュームのライフサイクル（Attach、Mount、Unmount、Detach）を管理する非同期制御ループ群で構成される。Desired State of World（DSW）とActual State of World（ASW）の2つの状態モデルを使い、宣言的にボリュームの目標状態と実際の状態を管理し、差分を検出してReconcilerが必要な操作を実行する。

**業務上の目的・背景**：Kubernetesでは多様なストレージバックエンド（クラウドディスク、NFS、CSIドライバー等）を統一的に扱う必要がある。Volume Managerにより、Podの要求するボリュームが確実にマウントされた状態でコンテナが起動し、Pod削除時に適切にクリーンアップされることを保証する。

**機能の利用シーン**：PersistentVolumeClaimを使用するPodの起動時のボリュームAttach/Mount、Pod削除時のUnmount/Detach、ノードの正常シャットダウン時のボリュームクリーンアップ。

**主要な処理内容**：
1. Desired State of World Populator: Pod仕様からマウント対象ボリュームを特定しDSWに追加
2. Reconciler: DSWとASWの差分を検出し、必要なAttach/Mount/Unmount/Detach操作を実行
3. WaitForAttachAndMount: Pod起動前にボリュームの準備完了を待機
4. OperationExecutor: 実際のボリューム操作（CSIドライバー等への委譲）を実行
5. CSIマイグレーション: in-treeプラグインからCSIドライバーへの透過的マイグレーション

**関連システム・外部連携**：CSIドライバー（Volume Attach/Mount操作）、API Server（VolumeAttachment、PV/PVC）、Container Runtime（マウントポイント設定）。

**権限による制御**：ボリュームのAttach/DetachはKubeletまたはAttach/Detachコントローラーが実行。Mount/Unmountはnode上のKubeletが実行。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Kubelet内部機能のため画面関連なし |

## 機能種別

リソース管理 / ストレージ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Pod | *v1.Pod | Yes | ボリュームを必要とするPod | volumes[]が存在 |
| PersistentVolumeClaim | *v1.PersistentVolumeClaim | No | PVC参照 | バインド済みであること |
| VolumeAttachment | *storagev1.VolumeAttachment | No | ボリュームアタッチメント | - |

### 入力データソース

- Pod仕様: spec.volumes[]、spec.containers[].volumeMounts[]
- API Server: PV、PVC、VolumeAttachment、StorageClass
- CSIドライバー: ボリューム操作結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MountedVolumes | sets.Set | マウント済みボリューム一覧 |
| UnmountedVolumes | []MountedVolume | 未マウントボリューム一覧 |

### 出力先

- ファイルシステム（ボリュームマウントポイント）
- ASW（Actual State of World、インメモリ）
- Prometheusメトリクス

## 処理フロー

### 処理シーケンス

```
1. DSW Populator起動（100ms間隔）
   └─ Pod一覧からボリューム要件をDSWに同期
2. Reconcilerループ（100ms間隔）
   └─ DSWとASWの差分検出、必要操作の実行
3. Pod起動前のWaitForAttachAndMount
   └─ 最大2分3秒待機、全ボリュームのAttach/Mount完了確認
4. Unmount/Detach
   └─ Pod削除後にボリュームのUnmount → Detach
```

### フローチャート

```mermaid
flowchart TD
    A[Pod追加] --> B[DSW Populator]
    B --> C[DSWにボリューム追加]
    C --> D[Reconciler検出]
    D --> E{Attach必要?}
    E -->|Yes| F[WaitForAttach]
    E -->|No| G{Mount必要?}
    F --> G
    G -->|Yes| H[MountVolume]
    G -->|No| I[完了]
    H --> I
    I --> J[ASW更新]

    K[Pod削除] --> L[DSWからボリューム削除]
    L --> M[Reconciler検出]
    M --> N[UnmountVolume]
    N --> O{Detach必要?}
    O -->|Yes| P[DetachVolume]
    O -->|No| Q[完了]
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | Attach前提 | ブロックデバイスのMountにはAttach完了が前提 | CSIボリューム等 |
| BR-57-02 | Attach待機タイムアウト | WaitForAttachは最大10分 | ボリュームAttach時 |
| BR-57-03 | Pod起動待機タイムアウト | WaitForAttachAndMountは最大2分3秒 | Pod起動時 |
| BR-57-04 | 順序保証 | Mount前にAttach、Detach前にUnmount | 全ボリューム操作 |
| BR-57-05 | CSIマイグレーション | in-treeプラグインはCSIドライバーに自動マイグレーション | CSIマイグレーション有効時 |

### 計算ロジック

- podAttachAndMountTimeout = 2分 + 3秒（認識しやすいタイムアウト値）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| DSW管理 | DesiredStateOfWorld（インメモリ） | INSERT/DELETE | 目標ボリューム状態管理 |
| ASW管理 | ActualStateOfWorld（インメモリ） | INSERT/UPDATE/DELETE | 実際のボリューム状態管理 |

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

#### DesiredStateOfWorld（インメモリ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | volumeName → VolumeToMount | Pod起動時 | DSW Populatorが追加 |
| DELETE | volumeName | Pod削除時 | DSW Populatorが削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| VolumeAttachmentLimitExceeded | リソース制限 | ノードのボリュームアタッチメント上限超過 | 別ノードにスケジュール |
| AttachTimeout | タイムアウト | ボリュームAttachが10分以内に完了しない | CSIドライバー/ストレージバックエンドを確認 |
| MountTimeout | タイムアウト | WaitForAttachAndMountが2分3秒以内に完了しない | ボリュームとCSIドライバーの状態を確認 |
| CSIDriverNotFound | 設定エラー | 指定CSIドライバーが未登録 | CSIドライバーのデプロイを確認 |

### リトライ仕様

- Reconcilerは100ms間隔で差分検出と操作実行を再試行
- 個別のMount/Attach操作にはexponential backoffが適用

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

DSWとASWはインメモリで管理。各操作はOperationExecutorを通じて非同期実行され、完了コールバックでASWを更新。

## パフォーマンス要件

- Reconcilerループ間隔: 100ms
- DSW Populatorループ間隔: 100ms
- WaitForAttachAndMountタイムアウト: 2分3秒
- WaitForAttachタイムアウト: 10分

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

- ボリュームマウントはKubeletのファイルシステム権限で実行
- CSI通信はUnix Domainソケット
- fsGroupによるボリュームのファイル所有権制御

## 備考

- VolumeAttachmentLimitExceededReasonはPod Admission拒否の理由として使用
- CSIマイグレーションによりin-treeボリュームプラグインは段階的に廃止予定

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | volume_manager.go | `pkg/kubelet/volumemanager/volume_manager.go` | VolumeManagerインターフェース |
| 1-2 | cache/ | `pkg/kubelet/volumemanager/cache/` | DesiredStateOfWorld、ActualStateOfWorld |

**読解のコツ**: Volume Managerは「Desired State」と「Actual State」の2つの状態モデルを比較するReconcilerパターンを採用。まずこの2つのインターフェースを理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | volume_manager.go | `pkg/kubelet/volumemanager/volume_manager.go` | VolumeManagerインターフェース定義 |

**主要処理フロー**:
- **57-75行目**: 定数定義（reconcilerLoopSleepPeriod=100ms、podAttachAndMountTimeout=2m3s等）
- **94-119行目**: VolumeManager インターフェース（Run、WaitForAttachAndMount、WaitForUnmount等）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reconciler/ | `pkg/kubelet/volumemanager/reconciler/` | DSWとASWの差分検出・修復 |

#### Step 4: DSW Populatorを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | populator/ | `pkg/kubelet/volumemanager/populator/` | Pod一覧からDSWへのボリューム同期 |

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

```
Kubelet
    |
    +-- VolumeManager.Run()
    |       +-- DSW Populator [100ms間隔]
    |       |       +-- Pod一覧取得
    |       |       +-- DSW.AddVolume()
    |       |
    |       +-- Reconciler [100ms間隔]
    |               +-- DSW vs ASW 差分検出
    |               +-- OperationExecutor.AttachVolume()
    |               +-- OperationExecutor.MountVolume()
    |               +-- OperationExecutor.UnmountVolume()
    |               +-- OperationExecutor.DetachVolume()
    |
    +-- VolumeManager.WaitForAttachAndMount()
            +-- ASW.GetMountedVolumesForPod()
```

### データフロー図

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

Pod仕様               ──▶  DSW Populator         ──▶  Desired State of World
(volumes[])

DSW + ASW             ──▶  Reconciler             ──▶  Actual State of World
                            |
                            +-- Attach/Mount/Unmount/Detach
                            |
                            v
CSIドライバー          ◀──  OperationExecutor     ──▶  ファイルシステム
(gRPC)                                                   (マウントポイント)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| volume_manager.go | `pkg/kubelet/volumemanager/volume_manager.go` | ソース | VolumeManager主実装 |
| cache/ | `pkg/kubelet/volumemanager/cache/` | ソース | DSW/ASWの状態管理 |
| reconciler/ | `pkg/kubelet/volumemanager/reconciler/` | ソース | 差分検出と修復 |
| populator/ | `pkg/kubelet/volumemanager/populator/` | ソース | DSW Populator |
| metrics/ | `pkg/kubelet/volumemanager/metrics/` | ソース | メトリクス定義 |
