# 機能設計書 47-DynamicResourcesプラグイン

## 概要

本ドキュメントは、Kubernetesスケジューラーの`DynamicResources`プラグインの機能設計を記述する。本プラグインはDynamic Resource Allocation（DRA）APIに基づき、ResourceClaimのアロケーション（割当）とスケジューリングを統合管理する。

### 本機能の処理概要

**業務上の目的・背景**：GPU、FPGA、NIC等の特殊なハードウェアリソースを動的に割り当てるために、DRA（Dynamic Resource Allocation）APIが導入された。本プラグインはPodが参照するResourceClaimの状態を管理し、構造化パラメータ（Structured Parameters）に基づいてリソースの割当とノード選択を行う。

**機能の利用シーン**：PodがResourceClaimを参照している場合に動作する。DeviceClass定義のリソースの割当、ノードのリソーススライスの評価、CEL式によるデバイス選択等を実行する。

**主要な処理内容**：
1. PreFilter: Podが参照するResourceClaimの状態を取得し、stateDataを構築。構造化パラメータ用のAllocatorを初期化
2. Filter: 各ノードで利用可能なリソーススライスを評価し、割当可能性を判定
3. PostFilter: Filter失敗時に割当済みClaimの情報をクリア
4. PreScore/Score: 割当結果に基づくスコアリング
5. Reserve: 割当結果を仮定し、ClaimのStatusを更新
6. PreBind: ClaimのAllocation結果をAPIサーバーに永続化
7. Unreserve: 仮定の取消

**関連システム・外部連携**：ResourceClaim API、ResourceSlice API、DeviceClass API、CEL式評価エンジン。

**権限による制御**：フィーチャーゲート（DRAExtendedResource等）により動作が制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | スケジューラー内部プラグインとして自動実行 |

## 機能種別

リソース割当 / フィルタリング / スコアリング / バインディング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| DynamicResourcesArgs | config.DynamicResourcesArgs | Yes | OperationTimeout等の設定 | ValidateDynamicResourcesArgs |
| Pod | v1.Pod | Yes | スケジュール対象Pod（ResourceClaims参照含む） | - |
| NodeInfo | fwk.NodeInfo | Yes | ノード情報 | - |

### 入力データソース

- Pod.Spec.ResourceClaims
- ResourceClaim API（resource.k8s.io/v1）
- ResourceSlice API（resource.k8s.io/v1）
- DeviceClass API（resource.k8s.io/v1）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FilterStatus | fwk.Status | フィルタリング結果 |
| Score | int64 | リソース割当ベースのスコア |
| AllocationResult | resourceapi.AllocationResult | リソース割当結果 |

## 処理フロー

### 処理シーケンス

```
1. PreFilter: ResourceClaimの取得とAllocator初期化
   ├─ Pod.Spec.ResourceClaimsの各参照を解決
   ├─ 各ClaimのAllocationStatus確認
   ├─ DRAExtendedResource有効時: 拡張リソース用の特別Claim生成
   └─ structured.NewAllocator でCEL式評価器を含むAllocatorを初期化

2. Filter: ノード上のリソース可用性評価
   └─ Allocator.Allocate でノード上の利用可能リソースを評価
   └─ 割当不可の場合はUnschedulable

3. PostFilter: Filter失敗後のクリーンアップ
   └─ 割当済みClaim情報をクリア

4. PreScore/Score: 割当結果に基づくスコアリング

5. Reserve: 割当結果の仮定
   └─ Claim.Status.Allocationの更新

6. PreBind: 割当結果のAPIサーバーへの永続化
   └─ Claim更新APIの呼び出し
   └─ タイムアウト付きリトライ

7. Unreserve: 仮定の取消
   └─ Claim.Status.Allocationのリバート
```

### フローチャート

```mermaid
flowchart TD
    A[PreFilter: ResourceClaim解決] --> B{Claim全バインド済み?}
    B -->|Yes| C[Skip]
    B -->|No| D[Allocator初期化]
    D --> E[Filter: ノードリソース評価]
    E --> F{割当可能?}
    F -->|No| G[Unschedulable]
    F -->|Yes| H[Score: 割当結果スコアリング]
    H --> I[Reserve: 割当仮定]
    I --> J[PreBind: API永続化]
    J --> K{成功?}
    K -->|No| L[Unreserve: 仮定取消]
    K -->|Yes| M[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Claimなしスキップ | ResourceClaimを参照しないPodは処理スキップ | 常時 |
| BR-02 | 構造化パラメータ | 全てのClaimはStructured Parametersで処理 | 常時 |
| BR-03 | CEL式評価 | DeviceClassのSelectorにCEL式が使用可能 | DeviceClass定義時 |
| BR-04 | ノードリソーススライス | ノードに公開されたResourceSliceからデバイスを選択 | 常時 |
| BR-05 | DRAExtendedResource | 拡張リソースをDRA経由で割り当てる特別Claim | フィーチャーゲート有効時 |
| BR-06 | 割当タイムアウト | PreBind操作にタイムアウトを設定 | OperationTimeout設定時 |

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

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

| 操作 | 対象 | 内容 |
|------|------|------|
| Update | ResourceClaim | Allocation結果の設定 |
| Update | ResourceClaim | ReservedFor（予約Pod）の設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnschedulableAndUnresolvable | Claim不存在 | 参照ClaimがAPI上に存在しない | Pod設定の修正 |
| Unschedulable | リソース不足 | ノード上に利用可能デバイスがない | 別ノード検索 |
| Error | API更新失敗 | PreBind時のAPI更新がタイムアウト | リトライ |

### リトライ仕様

PreBindでのAPI更新はretry.OnErrorを使用してリトライ。

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

Reserve-PreBind-Unreserveパターンで管理。

## パフォーマンス要件

- Allocator内のCEL式評価にはキャッシュを使用
- 割当不可能クラスターの追跡（unavailableClaims）によりFilter不要ノードを事前スキップ

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

- ResourceClaimはNamespaceスコープ
- CEL式の実行環境は制限されたサンドボックス

## 備考

- DRAはv1.31でGAだが、一部機能（DRAExtendedResource）はまだAlpha/Beta

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dynamicresources.go | `pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go` | stateData構造体（67-100行目）、claimStore、draExtendedResource |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dynamicresources.go | 同上 | New関数、Plugin構造体のインターフェース実装 |

#### Step 3: 処理フローを理解する

PreFilter → Filter → Reserve → PreBind の順でResourceClaimのライフサイクルを追跡。Allocatorの初期化とノード毎のリソース評価がコアロジック。

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

```
New (初期化)
    │
    ├─ PreFilter
    │      ├─ ResourceClaim取得
    │      ├─ claimStore構築
    │      └─ structured.NewAllocator
    │
    ├─ Filter
    │      └─ Allocator.Allocate
    │
    ├─ PostFilter
    │      └─ 割当情報クリア
    │
    ├─ Reserve
    │      └─ Claim.Status.Allocation更新
    │
    ├─ PreBind
    │      └─ ResourceClaim API Update (リトライ付き)
    │
    └─ Unreserve
           └─ Allocation取消
```

### データフロー図

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

Pod.Spec.ResourceClaims  ───▶  PreFilter                    ───▶  stateData (CycleState)
ResourceClaim API               (Claim取得+Allocator初期化)

stateData                ───▶  Filter                       ───▶  FilterStatus
ResourceSlice API               (ノードリソース評価)                 AllocationResult per node

AllocationResult         ───▶  Reserve                      ───▶  Claim仮定更新
                                (仮定)

Claim仮定                ───▶  PreBind                      ───▶  API永続化完了
                                (API更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dynamicresources.go | `pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go` | ソース | プラグイン全機能の実装 |
| structured/ | `staging/src/k8s.io/dynamic-resource-allocation/structured/` | ソース | Allocator実装 |
| cel/ | `staging/src/k8s.io/dynamic-resource-allocation/cel/` | ソース | CEL式評価 |
