# 機能設計書 125-HostPathボリューム

## 概要

本ドキュメントは、HostPathボリュームプラグインの設計を記述する。HostPathボリュームは、ホストノードのファイルシステム上のファイルまたはディレクトリをPodに直接マウントする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ホストノードのファイルシステムにPodから直接アクセスする手段を提供する。システムデーモンの設定ファイルへのアクセス、Docker内部ファイルへのアクセス、cAdvisor用のsysファイルシステムアクセスなど、ノードレベルの操作が必要な場面で使用される。

**機能の利用シーン**：DaemonSetで動作するシステムコンポーネントがホストの設定ファイルやソケットにアクセスする場合。開発環境でのテスト用途。PersistentVolume経由でのホストパスの利用。

**主要な処理内容**：
1. ホストパスの検証とタイプチェック（Directory、File、Socket、CharDev、BlockDev等）
2. DirectoryOrCreate/FileOrCreateによる自動作成
3. Recycle（PVのリサイクル）
4. Provision/Delete（PVの動的プロビジョニング/削除 - テスト用途のみ）

**関連システム・外部連携**：ホストファイルシステム、SELinux。

**権限による制御**：HostPathボリュームはセキュリティリスクが高く、PodSecurityPolicyまたはPodSecurityStandard(PSS)で制限することが推奨される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | HostPathはCLI画面を持たないkubelet内部処理 |

## 機能種別

ボリュームプラグイン / ホストファイルシステムアクセス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | ホスト上のパス | バックステップ（..）の排除、パスタイプ検証 |
| type | *HostPathType | No | パスタイプ（Unset, DirectoryOrCreate, Directory, FileOrCreate, File, Socket, CharDev, BlockDev） | 列挙値チェック、パス実在とタイプ一致の検証 |

### 入力データソース

- Pod Spec（Volume.HostPath）
- PersistentVolume Spec（HostPath）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| マウントパス | パス文字列 | ホストの指定パスがそのままコンテナ内に公開される |
| PV | PersistentVolume | Provision時に作成されるPV（テスト用途） |

## 処理フロー

### 処理シーケンス（SetUp）

```
1. パスバリデーション（バックステップ排除）
2. pathType判定
   ├─ Unset: 検証なし（即完了）
   ├─ DirectoryOrCreate: 存在しなければディレクトリ作成 → Directory検証
   ├─ Directory: ディレクトリであること検証
   ├─ FileOrCreate: 存在しなければファイル作成 → File検証
   ├─ File: ファイルであること検証
   ├─ Socket: ソケットであること検証
   ├─ CharDev: キャラクタデバイスであること検証
   └─ BlockDev: ブロックデバイスであること検証
```

### フローチャート

```mermaid
flowchart TD
    A[SetUp開始] --> B[ValidatePathNoBacksteps]
    B --> C{パス正常?}
    C -->|No| D[エラー返却]
    C -->|Yes| E{pathType?}
    E -->|Unset| F[完了]
    E -->|DirectoryOrCreate| G{存在する?}
    G -->|No| H[MakeDir]
    G -->|Yes| I[IsDir検証]
    H --> I
    E -->|Directory| I
    E -->|FileOrCreate| J{存在する?}
    J -->|No| K[MakeFile]
    J -->|Yes| L[IsFile検証]
    K --> L
    E -->|File| L
    E -->|Socket/CharDev/BlockDev| M[対応タイプ検証]
    I --> N[完了]
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-125-1 | バックステップ禁止 | パスに".."を含むことができない | 全SetUp時 |
| BR-125-2 | タイプ未設定時 | pathTypeがUnsetの場合、タイプ検証を行わない | pathType=Unset |
| BR-125-3 | 自動作成 | DirectoryOrCreate/FileOrCreateは存在しない場合に自動作成する | 該当タイプ指定時 |
| BR-125-4 | ディレクトリ作成パーミッション | MakeDirは0755パーミッションで作成 | DirectoryOrCreate |
| BR-125-5 | ファイル作成パーミッション | MakeFileは0644パーミッションで作成 | FileOrCreate |
| BR-125-6 | TearDownは何もしない | HostPathのTearDownは空操作 | アンマウント時 |
| BR-125-7 | Provision制限 | /tmp/配下にのみPVを動的プロビジョニング可能（テスト用途） | Provision時 |
| BR-125-8 | Delete制限 | /tmp/配下のパスのみ削除可能 | Delete時 |
| BR-125-9 | SELinuxラベル | Provision時にSELinux有効環境ではラベルを設定 | SELinux有効環境 |

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

| 操作 | 対象リソース | 操作種別 | 概要 |
|-----|-------------|---------|------|
| PV作成 | PersistentVolume | INSERT | Provision時のPV作成（テスト用途） |
| PV削除 | PersistentVolume | DELETE | Delete時のPV削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | パスにバックステップを含む | Pod設定の修正 |
| - | タイプ不一致 | 指定パスが期待するタイプと異なる | パスまたはタイプ指定の修正 |
| - | 不正タイプ | 未知のHostPathTypeが指定された | 正しいタイプの指定 |
| - | ブロック非対応 | ブロックボリュームプロビジョニング要求 | HostPathではブロックボリュームは非対応 |

### リトライ仕様

本プラグイン自体にリトライ機構はない。

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

ファイルシステム操作であり、トランザクション管理は行われない。

## パフォーマンス要件

ホストファイルシステムへの直接アクセスのため、パフォーマンスはホストストレージに依存する。マウント処理自体は軽量（パス検証のみ）。

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

- HostPathは最もセキュリティリスクの高いボリュームタイプの一つ
- ホストのルートファイルシステムへのアクセスを許可する可能性がある
- PodSecurityStandard(PSS)のBaselineおよびRestrictedプロファイルでは禁止される
- Provisioner/Deleterは/tmp/配下に限定されるが、これはテスト用途のみ
- SELinuxラベルの設定はProvisioner経由の場合のみ

## 備考

- HostPathの使用は本番環境では推奨されない（セキュリティリスク、マルチノードでのデータ共有不可）
- Provisioner/Deleterはシングルノードクラスタでのテスト用途のみ

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | host_path.go | `pkg/volume/hostpath/host_path.go` | hostPathPlugin構造体（64-68行目）: VolumeConfig保持 |
| 1-2 | host_path.go | `pkg/volume/hostpath/host_path.go` | hostPath構造体（212-216行目）: path、pathType |
| 1-3 | host_path.go | `pkg/volume/hostpath/host_path.go` | hostPathMounter構造体（222-228行目）: hostPath + readOnly、mounter、hu |
| 1-4 | host_path.go | `pkg/volume/hostpath/host_path.go` | インターフェース実装宣言（70-74行目）: VolumePlugin、PersistentVolumePlugin、RecyclableVolumePlugin、DeletableVolumePlugin、ProvisionableVolumePlugin |

**読解のコツ**: hostPathPluginは5つのボリュームインターフェースを実装しており、これは他のプラグインに比べて多い。ProvisionableVolumePluginとDeletableVolumePluginはテスト用途であることに注意。

#### Step 2: マウント処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | host_path.go | `pkg/volume/hostpath/host_path.go` | NewMounter()（121-145行目）: pathType判定、hostPathMounter構築 |
| 2-2 | host_path.go | `pkg/volume/hostpath/host_path.go` | SetUp()（241-255行目）: パスバリデーションとタイプチェック |
| 2-3 | host_path.go | `pkg/volume/hostpath/host_path.go` | checkTypeInternal()（462-499行目）: 8種類のpathTypeに対する検証ロジック |
| 2-4 | host_path.go | `pkg/volume/hostpath/host_path.go` | makeDir()（504-512行目）: ディレクトリ作成（0755） |
| 2-5 | host_path.go | `pkg/volume/hostpath/host_path.go` | makeFile()（516-527行目）: ファイル作成（0644） |

#### Step 3: Provisioner/Deleterを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | host_path.go | `pkg/volume/hostpath/host_path.go` | Provision()（293-336行目）: /tmp/配下にPV作成 |
| 3-2 | host_path.go | `pkg/volume/hostpath/host_path.go` | Delete()（354-360行目）: /tmp/配下のパスのみ削除 |
| 3-3 | host_path.go | `pkg/volume/hostpath/host_path.go` | Recycle()（156-171行目）: リサイクルPod起動 |

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

```
kubelet volume manager
    |
    ├─ hostPathPlugin.NewMounter(spec, pod)
    |      └─ getVolumeSource(spec)
    |      └─ hostPathMounter{} 構築
    |
    ├─ hostPathMounter.SetUp()
    |      ├─ validation.ValidatePathNoBacksteps()
    |      └─ checkType(path, pathType, hu)
    |             └─ checkTypeInternal(ftc, pathType)
    |                    ├─ [DirectoryOrCreate] ftc.MakeDir() → fallthrough
    |                    ├─ [Directory] ftc.IsDir()
    |                    ├─ [FileOrCreate] ftc.MakeFile() → fallthrough
    |                    ├─ [File] ftc.IsFile()
    |                    ├─ [Socket] ftc.IsSocket()
    |                    ├─ [CharDev] ftc.IsChar()
    |                    └─ [BlockDev] ftc.IsBlock()
    |
    ├─ hostPathUnmounter.TearDown()  [空操作]
    |
    ├─ hostPathProvisioner.Provision()
    |      └─ os.MkdirAll()
    |      └─ selinux.SetFileLabel()  [SELinux有効時]
    |
    └─ hostPathDeleter.Delete()
           └─ regexp.MatchString("/tmp/.+")
           └─ os.RemoveAll()
```

### データフロー図

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

HostPathVolumeSource ─────▶ NewMounter() ──────▶ hostPathMounter
  path ────────────────────▶    │
  type ────────────────────▶    │
                                │
hostPathMounter ──────────▶ SetUp()
                                ├──▶ パス検証結果
                                └──▶ [OrCreate] ファイル/ディレクトリ作成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| host_path.go | `pkg/volume/hostpath/host_path.go` | ソース | メイン実装（プラグイン、マウンター、Provisioner、Deleter） |
| validation/ | `pkg/volume/validation/` | ソース | パスバリデーション（ValidatePathNoBacksteps） |
| hostutil/ | `pkg/volume/util/hostutil/` | ソース | ホストファイルシステムユーティリティ |
| recyclerclient/ | `pkg/volume/util/recyclerclient/` | ソース | リサイクルPod管理 |
