# 通知設計書 46-FailedMapVolume

## 概要

本ドキュメントは、Kubernetesにおけるブロックボリュームのマップ処理失敗時に発行されるイベント通知「FailedMapVolume」の設計を記述する。ブロックボリュームのデバイスマッピング操作が失敗した際に、Warningイベントとして記録される。

### 本通知の処理概要

本通知は、ブロックボリューム（rawBlockVolume）のマップ操作（MapVolume）が失敗した際に発行されるKubernetesイベントである。ブロックボリュームはファイルシステムとしてマウントされるのではなく、デバイスとして直接Podにマップされる。このマッピング処理のいずれかの段階で失敗した場合に本イベントが発行される。

**業務上の目的・背景**：ブロックボリュームのマッピング失敗は、データベースやストレージアプリケーションなどrawBlockデバイスを必要とするワークロードの起動を阻害する。運用者に速やかに通知し、原因調査と対処を促す必要がある。

**通知の送信タイミング**：GenerateMapVolumeFuncの処理中、BlockVolumeMapperの初期化失敗時（即座）、またはmapVolumeFunc内の各処理ステップ失敗時（eventRecorderFuncコールバック経由）に発行される。

**通知の受信者**：Podオブジェクトに対するイベントとして記録されるため、Pod所有者、Namespace管理者がkubectl describe podやイベント監視ツールを通じて確認できる。

**通知内容の概要**：「MapVolume.NewBlockVolumeMapper initialization failed」または各ステップの失敗メッセージが含まれ、どの段階でマッピングが失敗したかを示す。

**期待されるアクション**：管理者はエラーメッセージを確認し、ボリュームプラグインの設定、デバイスパス、ストレージバックエンドの状態を確認すべきである。

## 通知種別

Kubernetesイベント（Event API リソース）- EventType: Warning

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（EventRecorder経由） |
| 優先度 | 高（Warning） |
| リトライ | EventRecorderの内部リトライ機構に依存 |

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

Podオブジェクトに対してイベントが記録される。volumeToMount.Podが対象。

## 通知テンプレート

### メール通知の場合

該当なし（Kubernetesネイティブイベント）

### 本文テンプレート

```
# 初期化失敗時:
"MapVolume.NewBlockVolumeMapper initialization failed for volume %q (UniqueName: %q) pod %q (UID: %q) : %v"

# mapVolumeFunc内の各ステップ失敗時:
(*err).Error() がそのまま出力される
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ボリューム名 | VolumeSpecの名前 | volumeToMount.VolumeSpec | Yes |
| ユニーク名 | ボリュームの一意識別子 | volumeToMount.VolumeName | Yes |
| Pod名 | 対象Podの名前 | volumeToMount.Pod | Yes |
| Pod UID | 対象PodのUID | volumeToMount.Pod.UID | Yes |
| エラー詳細 | 失敗原因 | err | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | BlockVolumeMapper初期化 | NewBlockVolumeMapper失敗 | マッパー作成失敗（950行目） |
| 内部処理 | mapVolumeFunc実行 | 各ステップ失敗 | eventRecorderFunc経由（1145行目） |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| マッピング成功 | 全ステップ成功時はSuccessfulMountVolumeが発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[GenerateMapVolumeFunc呼び出し] --> B[FindMapperPluginBySpec]
    B --> C[NewBlockVolumeMapper]
    C -->|失敗| D[FailedMapVolume イベント発行]
    C -->|成功| E[mapVolumeFunc実行]
    E --> F[GetGlobalMapPath]
    F --> G[WaitForAttach]
    G --> H[SetUpDevice]
    H --> I[MapPodDevice]
    I -->|成功| J[SuccessfulMountVolume]
    I -->|失敗| K[eventRecorderFunc]
    K --> L[FailedMapVolume イベント発行]
    D --> M[終了]
    J --> M
    L --> M
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Pod | イベント発行対象 | volumeToMount.Pod |
| VolumeSpec | ボリューム情報 | volumeToMount.VolumeSpec |

### テーブル別参照項目詳細

#### VolumeSpec

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| PersistentVolume.Spec.AccessModes | ReadWriteOncePodチェック | 対象Volume |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Event | INSERT | FailedMapVolumeイベント作成 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | Event.Reason | "FailedMapVolume" | Warningイベント |
| INSERT | Event.Message | エラー詳細 | 失敗原因 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| マッパー初期化失敗 | NewBlockVolumeMapper失敗 | ボリュームプラグイン設定確認 |
| デバイスアタッチ待ち失敗 | WaitForAttach失敗 | ストレージバックエンド状態確認 |
| デバイスセットアップ失敗 | SetUpDevice失敗 | ノード上のデバイスパス確認 |
| デバイスマッピング失敗 | MapPodDevice失敗 | ボリュームパス・権限確認 |
| ReadWriteOncePod違反 | 別Podで既に使用中 | Podスケジューリング確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | operationExecutorによる指数バックオフリトライ |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | 全てのエラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | EventRecorderのデフォルト設定に従う |
| 1日あたり上限 | 制限なし（同一イベントは集約される） |

### 配信時間帯

制限なし（24時間365日）

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

イベントメッセージにはPod名、ボリューム名、デバイスパスが含まれる可能性があるが、機密情報は含まれない。

## 備考

- FailedMapVolumeはブロックボリューム専用のイベント。ファイルシステムボリュームのマウント失敗にはFailedMountVolumeが使用される
- ReadWriteOncePodアクセスモードの違反チェックもmapVolumeFunc内で行われる（969-977行目）

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: FailedMapVolumeはブロックボリュームのマップ失敗専用。ファイルシステムボリュームのマウント失敗はFailedMountVolume（64行目）を使用する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 923-951行目: GenerateMapVolumeFunc - BlockVolumeMapper初期化部分 |

**主要処理フロー**:
1. **930行目**: FindMapperPluginBySpecでブロックボリュームプラグイン検索
2. **945-947行目**: NewBlockVolumeMapperでマッパー作成
3. **948-951行目**: 作成失敗時にFailedMapVolumeイベント発行

#### Step 3: マップ操作の実行

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 962-1147行目: mapVolumeFunc - ブロックボリュームマッピングの本体処理 |

**主要処理フロー**:
- **969行目**: ReadWriteOncePodアクセスモードチェック
- **981行目**: GetGlobalMapPath呼び出し
- **991行目**: WaitForAttach呼び出し
- **1003-1009行目**: SetUpDevice呼び出し
- **1100-1111行目**: MapPodDevice成功時にSuccessfulMountVolumeイベント発行
- **1143-1146行目**: eventRecorderFunc - エラー時にFailedMapVolumeイベント発行

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

```
operationGenerator.GenerateMapVolumeFunc()
    |
    +-- FindMapperPluginBySpec()
    +-- NewBlockVolumeMapper()
    |       +-- [失敗時] og.recorder.Eventf(pod, Warning, FailedMapVolume, ...)
    |
    +-- mapVolumeFunc()
    |       +-- GetGlobalMapPath()
    |       +-- WaitForAttach()
    |       +-- SetUpDevice()
    |       +-- MapPodDevice()
    |       +-- [成功時] og.recorder.Eventf(pod, Normal, SuccessfulMountVolume, ...)
    |
    +-- eventRecorderFunc()
            +-- [失敗時] og.recorder.Eventf(pod, Warning, FailedMapVolume, ...)
```

### データフロー図

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

VolumeToMount             operationGenerator                 Kubernetes Event API
(VolumeSpec,         --> .GenerateMapVolumeFunc()       --> Event(Warning,
 Pod,                    .mapVolumeFunc()                    FailedMapVolume)
 DevicePath)             BlockVolumeMapper.MapPodDevice()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | FailedMapVolume定数定義（70行目） |
| operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | ソース | GenerateMapVolumeFunc実装（923-1150行目） |
| types.go | `pkg/volume/util/types/types.go` | ソース | ボリューム操作の型定義 |
