# 通知設計書 56-VolumeDelete

## 概要

本ドキュメントは、PersistentVolume（PV）の削除処理中に、ボリュームがまだ使用中であるためにすぐには削除できない状態を通知するイベント「VolumeDelete」の設計について記述する。

### 本通知の処理概要

**業務上の目的・背景**：PVのReclaimPolicyが `Delete` に設定されている場合、PVCが解放された後にPVとその関連ストレージアセットの削除が試行される。削除処理が即座に完了しない場合（例：ストレージバックエンドがボリュームをまだ使用中と判断した場合）、この通知が発行される。この通知はPVの削除が進行中であるが完了していないことをクラスタ管理者に伝え、ストレージバックエンドの状態確認を促す。

**通知の送信タイミング**：PV ControllerのdeleteVolumeOperation内で、`doDeleteVolume` がエラーを返し、かつそのエラーが `IsDeletedVolumeInUse` に該当する場合に発行される。これは削除対象のボリュームがまだ使用中であることを示す。

**通知の受信者**：PVオブジェクトに対するKubernetes Eventとして発行される。`kubectl describe pv` や `kubectl get events` で監視しているクラスタ管理者、ストレージ管理者が受信者となる。

**通知内容の概要**：ストレージバックエンドから返されたエラーメッセージ（ボリューム使用中の理由）がそのまま通知される。

**期待されるアクション**：受信者は、ストレージバックエンドの状態を確認し、ボリュームの使用が解除されるのを待つ。コントローラは自動的に再試行するため、通常は手動介入は不要。

## 通知種別

Kubernetes Event（EventType: Normal）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（deleteVolumeOperationはgoroutineで実行） |
| 優先度 | 中（一時的な遅延の通知であり、自動的に再試行される） |
| リトライ | コントローラの同期ループにより自動再試行 |

### 送信先決定ロジック

PVオブジェクトに対してEventを発行する。

## 通知テンプレート

### Kubernetes Event

| 項目 | 内容 |
|-----|------|
| 送信元コンポーネント | pv controller |
| EventType | Normal |
| Reason | VolumeDelete |
| 関連オブジェクト | PersistentVolume |

### 本文テンプレート

```
%s
```

ストレージバックエンドのエラーメッセージ（`err.Error()`）がそのまま使用される。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| err | ボリューム削除エラーの詳細 | doDeleteVolume()の戻り値 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| PV Controller同期 | deleteVolumeOperation | doDeleteVolumeがエラーかつIsDeletedVolumeInUseがtrue | pv_controller.go 1356-1359行目 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 削除成功 | doDeleteVolumeが成功した場合はイベントなしでPVが削除される |
| IsDeletedVolumeInUse以外のエラー | ボリューム使用中以外のエラーの場合はVolumeFailedDeleteイベントが発行される |
| PVが再利用不要 | isVolumeReleasedがfalseの場合、削除処理自体がスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[deleteVolumeOperation開始] --> B[最新PV情報を取得]
    B --> C{PVは再利用が必要?}
    C -->|No| D[処理スキップ]
    C -->|Yes| E[doDeleteVolume実行]
    E --> F{削除成功?}
    F -->|Yes| G{deleted == true?}
    G -->|Yes| H[API ServerからPVを削除]
    G -->|No| I[外部プラグインによる削除待ち]
    F -->|No| J{IsDeletedVolumeInUse?}
    J -->|Yes| K[Event: VolumeDelete<br/>Normal, err.Error]
    J -->|No| L[Event: VolumeFailedDelete<br/>Warning, PVをFailed状態に]
    K --> M[次回同期で再試行]
    L --> M
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| PersistentVolumes | PV状態の最新情報取得 | API Server経由で直接取得 |
| PersistentVolumeClaims | PVCの存在確認（isVolumeReleased内） | コントローラキャッシュ経由 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Events | INSERT | VolumeDeleteイベントの記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ボリューム使用中 | ストレージバックエンドがボリュームを使用中と判断 | 自動再試行を待つ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 無制限（syncVolume毎に再試行） |
| リトライ間隔 | PV Controller同期ループの間隔に依存 |
| リトライ対象エラー | IsDeletedVolumeInUseエラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Event APIのレート制限に準拠 |
| 1日あたり上限 | 同一理由のイベントは集約される |

### 配信時間帯

制限なし

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

- ストレージバックエンドのエラーメッセージがそのまま通知されるため、バックエンドの内部情報が漏洩する可能性がある
- Kubernetes RBACによりEventの読み取り権限が制御される

## 備考

- VolumeDeleteはNormalイベントであり、VolumeFailedDeleteとは区別される
- IsDeletedVolumeInUseエラーの場合、PVはFailed状態に遷移しない（一時的な待機状態）
- VolumeFailedDeleteの場合はPVがFailed状態に遷移する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/controller/volume/events/event.go` | 26行目: `VolumeDelete` 定数定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pv_controller.go | `pkg/controller/volume/persistentvolume/pv_controller.go` | 1321-1389行目: deleteVolumeOperation全体の処理フロー |

**主要処理フロー**:
1. **1330行目**: 最新PV情報をAPI Serverから取得
2. **1342行目**: `isVolumeReleased` で削除が必要か判定
3. **1352行目**: `doDeleteVolume` 実行
4. **1356行目**: エラー時に `IsDeletedVolumeInUse` を判定
5. **1359行目**: ボリューム使用中の場合 `eventRecorder.Event(volume, Normal, VolumeDelete, err.Error())`
6. **1363行目**: その他のエラーの場合 `VolumeFailedDelete` イベント発行

#### Step 3: IsDeletedVolumeInUseの判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | errors（cloud-provider） | `k8s.io/cloud-provider/volume/errors` | IsDeletedVolumeInUse関数の実装 |

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

```
PersistentVolumeController.syncVolume()
    |
    +-- deleteVolume()
            |
            +-- scheduleOperation("delete-...", deleteVolumeOperation)
                    |
                    +-- kubeClient.CoreV1().PersistentVolumes().Get()
                    +-- isVolumeReleased()
                    +-- doDeleteVolume()
                    |       |
                    |       +-- (error, IsDeletedVolumeInUse=true)
                    |       |       +-- eventRecorder.Event(volume, Normal, VolumeDelete, err.Error())
                    |       |
                    |       +-- (error, IsDeletedVolumeInUse=false)
                    |       |       +-- updateVolumePhaseWithEvent(Failed, Warning, VolumeFailedDelete, ...)
                    |       |
                    |       +-- (success, deleted=true)
                    |               +-- kubeClient.CoreV1().PersistentVolumes().Delete()
                    |
                    +-- (success, deleted=false) -> external plugin handles deletion
```

### データフロー図

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

PV (Released状態)  ---->  deleteVolumeOperation()   ---->  Kubernetes Event
                          |                                (VolumeDelete: Normal)
                          +-> doDeleteVolume()              または
                          +-> volerr.IsDeletedVolumeInUse() (VolumeFailedDelete: Warning)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/controller/volume/events/event.go` | ソース | VolumeDelete定数定義（26行目） |
| pv_controller.go | `pkg/controller/volume/persistentvolume/pv_controller.go` | ソース | deleteVolumeOperation（1321-1389行目） |
| errors | `k8s.io/cloud-provider/volume/errors` | ソース | IsDeletedVolumeInUse判定関数 |
