# 機能設計書 73-RuntimeClass管理

## 概要

本ドキュメントは、KubeletにおけるRuntimeClass管理機能の設計を記述する。RuntimeClassリソースに基づくコンテナランタイムハンドラーの選択とキャッシュ管理を定義する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターでは、異なるコンテナランタイム（runc、kata-containers、gVisor等）を同一ノード上で使い分ける需要がある。RuntimeClassリソースにより、Podごとにどのランタイムハンドラーを使用するかを宣言的に指定でき、セキュリティ要件やパフォーマンス要件に応じたランタイムの選択が可能になる。

**機能の利用シーン**：KubeletがPodを起動する際に、Pod.Spec.RuntimeClassNameを参照してRuntimeClassリソースからランタイムハンドラー名を解決する。解決されたハンドラー名はCRI経由でコンテナランタイムに渡される。

**主要な処理内容**：
1. SharedInformerFactoryによるRuntimeClassリソースのキャッシュ管理
2. RuntimeClassListerを通じたRuntimeClassの検索
3. RuntimeClassName からランタイムハンドラー名への名前解決
4. RuntimeClassが未指定（nil/空文字）の場合のデフォルトハンドラー解決

**関連システム・外部連携**：API Serverからの RuntimeClass リソースの監視（Informer）、CRI経由でのランタイムハンドラー指定。

**権限による制御**：RuntimeClassはクラスターレベルのリソースであり、作成・変更にはクラスター管理者権限が必要。

## 関連画面

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

## 機能種別

データ参照 / キャッシュ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| runtimeClassName | *string | No | Pod.Spec.RuntimeClassNameの値 | nil可、空文字可 |
| client | clientset.Interface | Yes | Kubernetes APIクライアント（Informer初期化用） | - |

### 入力データソース

- API ServerのRuntimeClassリソース（Informer経由でキャッシュ）
- Pod.Spec.RuntimeClassName

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| handler | string | ランタイムハンドラー名（空文字はデフォルト） |
| error | error | NotFoundエラー等 |

### 出力先

Kubeletの内部処理に返却され、CRI RunPodSandboxリクエストのRuntimeHandlerフィールドに設定される。

## 処理フロー

### 処理シーケンス

```
1. Manager初期化（NewManager）
   ├─ SharedInformerFactory作成（resyncPeriod=0）
   └─ RuntimeClassLister取得
2. キャッシュ開始（Start）
   └─ InformerFactory.Start(stopCh)
3. キャッシュ同期待ち（WaitForCacheSync）
4. ハンドラー名解決（LookupRuntimeHandler）
   ├─ runtimeClassName == nil || "" → ""（デフォルト）を返却
   └─ lister.Get(name) でRuntimeClass取得
       ├─ NotFound → NotFoundエラー返却
       └─ 成功 → rc.Handler を返却
```

### フローチャート

```mermaid
flowchart TD
    A[LookupRuntimeHandler] --> B{runtimeClassName nil or empty?}
    B -->|Yes| C["return '' (default handler)"]
    B -->|No| D[lister.Get name]
    D --> E{NotFound?}
    E -->|Yes| F[return NotFound error]
    E -->|No| G{Other error?}
    G -->|Yes| H[return wrapped error]
    G -->|No| I[return rc.Handler]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | デフォルトハンドラー | RuntimeClassName未指定の場合、空文字列のデフォルトハンドラーを使用 | runtimeClassName == nil or "" |
| BR-73-02 | RuntimeClass解決 | RuntimeClass名からHandlerフィールドを取得 | runtimeClassNameが指定されている場合 |
| BR-73-03 | NotFoundエラー | 指定されたRuntimeClassが存在しない場合はエラー | lister.GetがNotFoundを返す場合 |
| BR-73-04 | キャッシュ同期 | resyncPeriod=0でInformerが初期化される | Manager初期化時 |

### 計算ロジック

特になし。名前解決のみ。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | RuntimeClass | SELECT（キャッシュ参照） | Informerキャッシュからの読み取りのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | リソース不存在 | 指定のRuntimeClassがクラスターに存在しない | RuntimeClassリソースを作成 |
| - | 内部エラー | lister.Getで予期しないエラー | ログ出力、再試行 |

### リトライ仕様

Informerのキャッシュは自動的に再同期される。LookupRuntimeHandlerのエラー時はKubeletのSync Loopで再試行される。

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

トランザクションの概念はなし。読み取り専用操作。

## パフォーマンス要件

- Informerキャッシュからの参照のため、O(1)のアクセス速度
- API Serverへの負荷はInformerのWatch接続のみ

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

- RuntimeClassの作成・変更にはクラスター管理者権限が必要
- 不適切なランタイムハンドラーの指定はコンテナのセキュリティ境界に影響する

## 備考

- resyncPeriod=0はInformerがWatch APIのみでキャッシュを維持することを意味する
- RuntimeClassのOverheadフィールドによるリソースオーバーヘッド計算は本パッケージの範囲外で処理される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | runtimeclass_manager.go | `pkg/kubelet/runtimeclass/runtimeclass_manager.go` | Manager構造体（29-32行目） |

**読解のコツ**: Manager構造体は`informerFactory`と`lister`の2つのフィールドのみを持つシンプルな構造。SharedInformerFactoryがキャッシュの基盤を提供する。

#### Step 2: 初期化フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | runtimeclass_manager.go | `pkg/kubelet/runtimeclass/runtimeclass_manager.go` | NewManager関数（35-45行目） |

**主要処理フロー**:
1. **36行目**: `resyncPeriod = 0`定数定義
2. **38行目**: `informers.NewSharedInformerFactory`でInformerファクトリー作成
3. **39行目**: `factory.Node().V1().RuntimeClasses().Lister()`でLister取得

#### Step 3: ライフサイクル管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | runtimeclass_manager.go | `pkg/kubelet/runtimeclass/runtimeclass_manager.go` | Start/WaitForCacheSync（48-56行目） |

#### Step 4: 名前解決ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | runtimeclass_manager.go | `pkg/kubelet/runtimeclass/runtimeclass_manager.go` | LookupRuntimeHandler（61-78行目） |

**主要処理フロー**:
- **62-65行目**: nil/空文字チェック、デフォルトハンドラー返却
- **69行目**: `lister.Get(name)`でキャッシュからRuntimeClass取得
- **71-74行目**: NotFoundエラーのハンドリング
- **77行目**: `rc.Handler`の返却

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

```
Kubelet
    |
    +-- runtimeclass.NewManager(client)
    |       +-- informers.NewSharedInformerFactory(client, 0)
    |       +-- factory.Node().V1().RuntimeClasses().Lister()
    |
    +-- Manager.Start(stopCh)
    |       +-- informerFactory.Start(stopCh)
    |
    +-- Manager.WaitForCacheSync(stopCh)
    |       +-- informerFactory.WaitForCacheSync(stopCh)
    |
    +-- Manager.LookupRuntimeHandler(runtimeClassName)
            +-- lister.Get(name)
```

### データフロー図

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

API Server ----Watch----> SharedInformerFactory ----> キャッシュ
                                                         |
Pod.Spec.RuntimeClassName -> LookupRuntimeHandler -----+-> RuntimeHandler (string)
                                 |                          |
                                 +-- lister.Get() ---------+-> error (NotFound等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| runtimeclass_manager.go | `pkg/kubelet/runtimeclass/runtimeclass_manager.go` | ソース | RuntimeClass管理のメインロジック |
| runtimeclass_manager_test.go | `pkg/kubelet/runtimeclass/runtimeclass_manager_test.go` | テスト | ユニットテスト |
| testing/ | `pkg/kubelet/runtimeclass/testing/` | テスト | テスト用ヘルパー |
