# 通知設計書 50-FailedMountOnFilesystemMismatch

## 概要

本ドキュメントは、Kubernetesにおけるファイルシステム不一致によるマウント失敗時に発行されるイベント通知「FailedMountOnFilesystemMismatch」の設計を記述する。PVCで要求されたファイルシステムとディスク上の実際のファイルシステムが一致しない場合に、PersistentVolumeオブジェクトに対してWarningイベントとして記録される。

### 本通知の処理概要

本通知は、ボリュームのマウント処理中にファイルシステムの不一致（FilesystemMismatch）エラーが検出された際に発行されるKubernetesイベントである。PVCで指定されたファイルシステムタイプ（例：ext4）と、ディスクに実際に存在するファイルシステム（例：xfs）が異なる場合にマウントが失敗し、このイベントが発行される。

**業務上の目的・背景**：ファイルシステムの不一致は、ボリュームの再利用や誤設定により発生する。この問題はデータ損失のリスクがあるため、通常のマウント失敗（FailedMount）とは別に、専用のイベント理由で記録することにより、管理者が問題の根本原因を迅速に特定できるようにする。

**通知の送信タイミング**：GenerateMountVolumeFuncのmountVolumeFunc内またはMountDevice処理でマウントエラーが発生し、そのエラーがFilesystemMismatchタイプであると判定された場合に発行される。checkForFailedMount関数内で判定される。

**通知の受信者**：PersistentVolumeオブジェクトに対するイベントとして記録される（PodやPVCではなくPV）。ストレージ管理者がkubectl describe pvやイベント監視ツールを通じて確認できる。

**通知内容の概要**：「MountVolume failed for volume ... : {filesystem mismatch error details}」というメッセージが含まれ、ファイルシステム不一致の詳細を示す。

**期待されるアクション**：管理者はPVのファイルシステム設定とディスク上の実際のファイルシステムを確認し、必要に応じてPVの再作成やディスクのフォーマットを行うべきである。データ損失のリスクがあるため慎重な対応が求められる。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

PersistentVolumeオブジェクトに対してイベントが記録される。og.recorder.Eventf(pv, v1.EventTypeWarning, kevents.FailedMountOnFilesystemMismatch, simpleMsg)により、volumeToMount.VolumeSpec.PersistentVolumeがイベント対象となる。PVがnilの場合はイベントは発行されない。

## 通知テンプレート

### メール通知の場合

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

### 本文テンプレート

```
"MountVolume failed for volume %q (UniqueName: %q) pod %q (UID: %q) : %s"
```

%sにはmountError.Error()の内容が入る。GenerateMsg関数により生成される。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ボリューム名 | VolumeSpecの名前 | volumeToMount.VolumeSpec | Yes |
| ユニーク名 | ボリュームの一意識別子 | volumeToMount.VolumeName | Yes |
| Pod名 | 対象Podの名前 | volumeToMount.Pod | Yes |
| Pod UID | 対象PodのUID | volumeToMount.Pod.UID | Yes |
| エラー詳細 | マウントエラーの詳細 | mountError.Error() | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | MountDevice/SetUp失敗 | IsFilesystemMismatchError(mountError) == true | operation_generator.go 667-669行目 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| PVがnil | volumeToMount.VolumeSpec.PersistentVolumeがnilの場合はスキップ |
| 非FilesystemMismatchエラー | IsFilesystemMismatchError()がfalseの場合はスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[MountVolume処理] --> B[MountDevice/SetUp実行]
    B -->|成功| C[マウント完了]
    B -->|失敗| D[checkForFailedMount呼び出し]
    D --> E{PV != nil?}
    E -->|No| F[スキップ]
    E -->|Yes| G{IsFilesystemMismatchError?}
    G -->|No| F
    G -->|Yes| H[FailedMountOnFilesystemMismatch イベント発行（PV）]
    H --> I[FailedMountVolume イベントも別途発行（Pod）]
    F --> I
    I --> J[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| PersistentVolume | イベント発行対象 | volumeToMount.VolumeSpec.PersistentVolume |
| VolumeToMount | マウント対象情報 | VolumeSpec, Pod |

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

#### PersistentVolume

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| オブジェクト全体 | イベント発行先 | volumeToMount.VolumeSpec.PersistentVolume |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Event | INSERT | FailedMountOnFilesystemMismatchイベント作成（PVに対して） |

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | Event.Reason | "FailedMountOnFilesystemMismatch" | Warningイベント |
| INSERT | Event.Message | simpleMsg | ファイルシステム不一致メッセージ |
| INSERT | Event.InvolvedObject | PersistentVolume | PodではなくPVに対して |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ファイルシステム不一致 | PVC要求FSとディスク上FSが異なる | PV設定見直し、ディスクフォーマット検討 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | operationExecutorによるリトライ（ただし設定変更なしでは復旧しない） |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | マウントエラー全般 |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間365日）

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

イベントメッセージにはPV名、Pod名、ファイルシステム情報が含まれるが、機密情報は含まれない。

## 備考

- FailedMountOnFilesystemMismatchはPVオブジェクトに対して発行される（PodやPVCではない）
- 同時にPodに対してはFailedMountVolumeイベントも発行される（eventRecorderFunc経由）
- IsFilesystemMismatchError()はmount.MountError型でType==mount.FilesystemMismatchかどうかを判定する
- errors.As()によりラップされたエラーにも対応する
- このイベントはcheckForFailedMount関数内でのみ発行される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 83行目: FailedMountOnFilesystemMismatch定数定義 |
| 1-2 | types.go | `pkg/volume/util/types/types.go` | 189-194行目: IsFilesystemMismatchError関数定義 |

**読解のコツ**: mount.MountError型のType フィールドがmount.FilesystemMismatchであるかをerrors.As()で判定する。ラップされたエラーにも対応。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 661-671行目: checkForFailedMount関数 |

**主要処理フロー**:
1. **662行目**: PVオブジェクト取得（VolumeSpec.PersistentVolume）
2. **663行目**: PV == nilチェック（nilならreturn）
3. **667行目**: IsFilesystemMismatchError(mountError)チェック
4. **668行目**: GenerateMsgでメッセージ生成
5. **669行目**: PVに対しFailedMountOnFilesystemMismatchイベント発行

#### Step 3: 呼び出し元の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 550行目: MountDevice失敗時のcheckForFailedMount呼び出し |
| 3-2 | operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | 602行目: SetUp失敗時のcheckForFailedMount呼び出し |

#### Step 4: エラー判定の詳細

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | types.go | `pkg/volume/util/types/types.go` | 189-194行目: IsFilesystemMismatchError - errors.As()によるラップエラー対応 |

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

```
operationGenerator.GenerateMountVolumeFunc()
    |
    +-- mountVolumeFunc()
            +-- MountDevice()
            |       +-- [失敗時] og.checkForFailedMount()
            |                       +-- IsFilesystemMismatchError()
            |                       +-- [一致時] og.recorder.Eventf(pv, Warning,
            |                                       FailedMountOnFilesystemMismatch, ...)
            +-- SetUp()
                    +-- [失敗時] og.checkForFailedMount()
                                    +-- IsFilesystemMismatchError()
                                    +-- [一致時] og.recorder.Eventf(pv, Warning,
                                                    FailedMountOnFilesystemMismatch, ...)
```

### データフロー図

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

mountError                checkForFailedMount()              Kubernetes Event API
(MountError型)       --> IsFilesystemMismatchError()    --> Event(Warning,
VolumeToMount            GenerateMsg()                       FailedMountOnFilesystemMismatch)
  .VolumeSpec                                                対象: PersistentVolume
  .PersistentVolume
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | FailedMountOnFilesystemMismatch定数定義（83行目） |
| operation_generator.go | `pkg/volume/util/operationexecutor/operation_generator.go` | ソース | checkForFailedMount関数（661-671行目） |
| types.go | `pkg/volume/util/types/types.go` | ソース | IsFilesystemMismatchError関数（189-194行目） |
| types_test.go | `pkg/volume/util/types/types_test.go` | テスト | IsFilesystemMismatchErrorのテストケース |
