# 機能設計書 30-ResourceClaimコントローラー

## 概要

本ドキュメントは、KubernetesのResourceClaimコントローラーの機能設計を記述する。Dynamic Resource Allocation（DRA）のResourceClaimのライフサイクルを管理する。

### 本機能の処理概要

**業務上の目的・背景**：GPU、FPGA等のカスタムハードウェアリソースを動的に割り当てるDRA（Dynamic Resource Allocation）フレームワークにおいて、ResourceClaimのライフサイクル管理を自動化する。PodのResourceClaim要求に基づいてResourceClaimの作成、予約、割り当て解除、削除を行う。

**機能の利用シーン**：PodがResourceClaimTemplate経由でハードウェアリソースを要求した際に、ResourceClaimを自動作成する。Podの完了後にResourceClaimの予約解除やリソースの割り当て解除を行う。孤立したResourceClaimの自動削除。

**主要な処理内容**：
1. Pod、ResourceClaim、ResourceClaimTemplateの変更を監視する
2. syncPod: PodのResourceClaim要求からResourceClaimを作成し、割り当て済みClaimを予約する
3. syncClaim: 完了Pod/削除PodのReservedFor解除、未使用Claimの割り当て解除、孤立Claimの削除
4. MutationCacheで最近作成/更新したオブジェクトのキャッシュ遅延を補完する
5. deletedObjects LRUキャッシュで削除済みオブジェクトの追跡を行う

**関連システム・外部連携**：API Server（Pod/ResourceClaim/ResourceClaimTemplateの読み取り・作成・更新・削除）、DRAドライバー（リソース割り当ての実行はドライバー側）

**権限による制御**：system:controller:resource-claim-controllerサービスアカウントで動作し、Pod/ResourceClaim/ResourceClaimTemplateの読み取りおよびResourceClaimの作成・更新・削除権限を持つ。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本コントローラーに直接関連する画面はない |

## 機能種別

リソース管理 / ライフサイクル管理（バックグラウンド自動処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| workers | int | Yes | 同時実行ワーカー数 | 正の整数 |

### 入力データソース

- Pod Informer: Podのadd/update/deleteイベント
- ResourceClaim Informer: ResourceClaimのadd/update/deleteイベント
- ResourceClaimTemplate Informer: ResourceClaimTemplateの変更イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ResourceClaim作成 | CREATE API | テンプレートからのResourceClaim自動作成 |
| Pod.Status.ResourceClaimStatuses | SSA Patch | Claim名とPodClaimの紐付け |
| ResourceClaim.Status.ReservedFor | UPDATE API | Pod予約情報の更新 |
| ResourceClaim.Spec.Allocation | UPDATE API | 割り当て解除 |
| ResourceClaim削除 | DELETE API | 孤立Claimの削除 |

### 出力先

- API Server: ResourceClaimの作成・更新・削除、Podステータスの更新

## 処理フロー

### 処理シーケンス

```
1. NewController()でコントローラーを初期化する
   └─ Pod/Claim/Template Informer登録、MutationCache初期化、インデクサー設定
2. Run()でワーカーを起動する
   └─ EventBroadcaster開始、workers個のワーカー起動
3. syncHandler()でキープレフィックスに基づきディスパッチする
   └─ "pod:" → syncPod()、"claim:" → syncClaim()
4. syncPod(): ResourceClaimの作成と予約を行う
   └─ テンプレートからClaim作成、Pod StatusにClaimStatuses設定、割り当て済みClaimの予約
5. syncClaim(): ClaimのReservedFor管理、割り当て解除、削除を行う
   └─ 完了/削除PodのReservedFor除去、未予約Claimの割り当て解除、孤立Claimの削除
```

### フローチャート

```mermaid
flowchart TD
    A[イベント検知] --> B{キープレフィックス}
    B -->|pod:| C[syncPod]
    B -->|claim:| D[syncClaim]

    C --> E[PodのResourceClaim要求を確認]
    E --> F{既存Claim?}
    F -->|No| G[handleClaim: テンプレートからClaim作成]
    F -->|Yes| H[Claim名をステータスに記録]
    G --> H
    H --> I[割り当て済みClaimをPod用に予約]

    D --> J[ReservedForの各Podを検証]
    J --> K{Pod完了/削除?}
    K -->|Yes| L[ReservedForから除去]
    K -->|No| M[維持]
    L --> N{ReservedFor空?}
    N -->|Yes| O[割り当て解除]
    N -->|No| P[維持]
    O --> Q{孤立Claim?}
    Q -->|Yes| R[Claim削除]
    Q -->|No| S[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-01 | テンプレートからの自動作成 | PodのResourceClaim要求がResourceClaimTemplateを参照する場合、自動的にResourceClaimを作成する | syncPod/handleClaim |
| BR-30-02 | Pod OwnerReference | 作成されたResourceClaimはPodをOwnerReferenceとして持つ | handleClaim |
| BR-30-03 | 名前生成 | ResourceClaim名はPod名+ResourceClaim名+ランダムサフィックスで生成（63文字制限） | handleClaim |
| BR-30-04 | MutationCache | 作成直後のResourceClaimはMutationCacheで追跡し、Informerキャッシュ遅延を補完 | handleClaim |
| BR-30-05 | ReservedFor管理 | 完了/削除済みPodのReservedForエントリを自動除去 | syncClaim |
| BR-30-06 | 3段階Pod存在確認 | ReservedFor検証時にInformerキャッシュ→deletedObjects LRU→API Server GETの3段階で確認 | syncClaim |
| BR-30-07 | 割り当て解除 | ReservedForが空かつAllocatedの場合、Allocationをnilに設定 | syncClaim |
| BR-30-08 | 孤立Claim削除 | OwnerPodが完了済みかつFinalizer除去可能な場合、ResourceClaimを削除 | syncClaim |
| BR-30-09 | maxUIDCacheEntries | deletedObjects LRUキャッシュは最大500エントリ | Controller初期化時 |

### 計算ロジック

- **名前生成**: `pod.Name + "-" + claimName` を最大63文字に制限（サフィックス追加の余地を残す）
- **Pod完了判定**: `isPodDone()` = PodSucceeded || PodFailed

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Pod取得 | Pod（etcd） | SELECT | Pod情報の取得 |
| Claim取得 | ResourceClaim（etcd） | SELECT | ResourceClaim情報の取得 |
| Template取得 | ResourceClaimTemplate（etcd） | SELECT | テンプレート情報の取得 |
| Claim作成 | ResourceClaim（etcd） | INSERT | テンプレートからの自動作成 |
| Podステータス更新 | Pod（etcd） | UPDATE（SSA Patch） | ResourceClaimStatusesの設定 |
| Claim更新 | ResourceClaim（etcd） | UPDATE | ReservedFor/Allocationの更新 |
| Claim削除 | ResourceClaim（etcd） | DELETE | 孤立Claimの削除 |

### テーブル別操作詳細

#### ResourceClaim（etcd経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | spec, metadata.ownerReferences | テンプレートから生成、Pod OwnerRef設定 | GenerateNameで名前生成 |
| UPDATE | status.reservedFor | Pod予約情報の追加/除去 | |
| UPDATE | status.allocation | nil（割り当て解除） | ReservedFor空時 |
| DELETE | - | OwnerPod完了時 | 孤立Claim削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | API応答 | Pod/Claim/Templateが削除済み | 正常終了またはスキップ |
| AlreadyExists | API応答 | ResourceClaimが既に存在 | MutationCacheから取得を試行 |
| Conflict | API応答 | ResourceVersion不一致 | RateLimitingキューでリトライ |

### リトライ仕様

- syncHandler失敗時: RateLimitingキューでリトライ
- 成功時: queue.Forget()でバックオフリセット
- MutationCacheのTTLは1時間

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

ResourceClaimの作成とPodステータス更新は2段階で行われる。MutationCacheにより、Informerキャッシュ遅延による不整合を最小化する。deletedObjects LRUキャッシュにより、削除済みPodの再確認のためのAPI呼び出しを削減する。

## パフォーマンス要件

- MutationCache（TTL 1時間）で最近の作成/更新オブジェクトをキャッシュ
- deletedObjects LRU（max 500エントリ）で削除済みPodのAPI呼び出しを削減
- キープレフィックス（"pod:"/""claim:"）でディスパッチし、不要な処理を回避
- Pod/Claim/TemplateのInformerインデクサーで高速な関連オブジェクト検索

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

- ResourceClaimの作成時にPodのOwnerReferenceを設定し、Pod削除時の自動GCを有効化
- AdminAccess/PrioritizedList機能フラグで追加機能を制御
- DRAドライバーとの連携はResourceClaimのStatus.Allocationフィールドを通じて行われる

## 備考

- DRA（Dynamic Resource Allocation）はKubernetes 1.26で導入されたアルファ機能
- ResourceClaimTemplateはPodごとにユニークなResourceClaimを生成するための仕組み
- MutationCacheはclient-goのライブラリで、API Server書き込みとInformerキャッシュの遅延を補完する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | controller.go | `pkg/controller/resourceclaim/controller.go` | 定数定義（56-77行目）。podResourceClaimIndex、claimPodOwnerIndex、fieldManager、maxUIDCacheEntries=500 |
| 1-2 | controller.go | `pkg/controller/resourceclaim/controller.go` | Controller構造体（80-121行目）。kubeClient、podLister、claimLister、templateLister、claimCache（MutationCache）、deletedObjects（LRUキャッシュ）、queueを保持 |
| 1-3 | controller.go | `pkg/controller/resourceclaim/controller.go` | キープレフィックス: claimKeyPrefix="claim:"、podKeyPrefix="pod:"（123-126行目） |
| 1-4 | controller.go | `pkg/controller/resourceclaim/controller.go` | Features構造体（129-132行目）。AdminAccess、PrioritizedList |

**読解のコツ**: キューに投入されるキーはプレフィックス付き（"pod:namespace/name" or "claim:namespace/name"）。syncHandler()でプレフィックスを見てsyncPod/syncClaimにディスパッチする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | controller.go | `pkg/controller/resourceclaim/controller.go` | NewController（135-237行目）。3つのInformer登録、2つのPodインデクサー、Claimオーナーインデクサー、MutationCache初期化 |
| 2-2 | controller.go | `pkg/controller/resourceclaim/controller.go` | Run（477-506行目）。EventBroadcaster開始、キャッシュ同期、ワーカー起動 |

**主要処理フロー**:
1. **135-237行目**: Pod/Claim/Template InformerにAdd/Update/Deleteハンドラ登録
2. **477-506行目**: EventBroadcaster開始、キャッシュ同期待機、ワーカー起動

#### Step 3: ディスパッチとPod同期を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | controller.go | `pkg/controller/resourceclaim/controller.go` | syncHandler（534-554行目）。キープレフィックスでsyncPod/syncClaimにディスパッチ |
| 3-2 | controller.go | `pkg/controller/resourceclaim/controller.go` | syncPod（556-636行目）。ResourceClaim要求の確認、handleClaim呼び出し、Podステータス更新（SSA）、割り当て済みClaimの予約 |
| 3-3 | controller.go | `pkg/controller/resourceclaim/controller.go` | handleClaim（638-764行目）。テンプレートからのClaim作成、OwnerReference設定、MutationCache登録 |

#### Step 4: Claim同期を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | controller.go | `pkg/controller/resourceclaim/controller.go` | syncClaim（832-1013行目）。ReservedFor検証（3段階Pod存在確認）、割り当て解除、孤立Claim削除 |
| 4-2 | controller.go | `pkg/controller/resourceclaim/controller.go` | reserveForPod（818-830行目）。Pod予約情報の追加 |

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

```
Controller.Run()
    │
    └─ syncHandler()
           │
           ├─ syncPod() ── "pod:" プレフィックス
           │      ├─ handleClaim() ── テンプレートからClaim作成
           │      │      ├─ ResourceClaim.Create() + MutationCache
           │      │      └─ Pod OwnerReference設定
           │      ├─ Pod Status SSA Patch ── ResourceClaimStatuses
           │      └─ reserveForPod() ── 割り当て済みClaimの予約
           │
           └─ syncClaim() ── "claim:" プレフィックス
                  ├─ ReservedFor検証
                  │      ├─ Informerキャッシュ確認
                  │      ├─ deletedObjects LRU確認
                  │      └─ API Server GET確認
                  ├─ ReservedFor除去（完了/削除Pod）
                  ├─ Allocation解除（ReservedFor空時）
                  ├─ Finalizer除去
                  └─ 孤立Claim削除（OwnerPod完了時）
```

### データフロー図

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

Podイベント ──────────▶ syncPod()
(Informer)                 │
                          ├─ handleClaim() ──▶ ResourceClaim Create
                          │   (テンプレートから)       + MutationCache
                          ├─ Pod Status SSA ──▶ ResourceClaimStatuses
                          └─ reserveForPod() ──▶ Claim ReservedFor更新

Claimイベント ─────────▶ syncClaim()
(Informer)                 │
                          ├─ ReservedFor検証 ──▶ 3段階Pod存在確認
                          ├─ ReservedFor除去 ──▶ Claim Status更新
                          ├─ Allocation解除 ──▶ Claim Spec更新
                          └─ 孤立Claim削除 ──▶ Claim Delete

Templateイベント ──────▶ enqueueResourceClaimTemplate()
(Informer)                 └─ 関連Podをpod:キーでエンキュー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| controller.go | `pkg/controller/resourceclaim/controller.go` | ソース | ResourceClaimコントローラーの全ロジック |
| metrics.go | `pkg/controller/resourceclaim/metrics.go` | ソース | Prometheusメトリクスの定義（存在する場合） |
