# 機能設計書 56-DRA（Dynamic Resource Allocation）

## 概要

本ドキュメントは、KubeletにおけるDRA（Dynamic Resource Allocation）プラグインを通じた動的リソース割り当て管理の設計を記載する。

### 本機能の処理概要

KubeletのDRA管理機能は、ResourceClaimリソースのライフサイクルをKubelet側で管理する。DRAプラグインとの通信を通じて、Pod起動前にResourceClaimを準備（Prepare）し、Pod終了後に解放（Unprepare）する。従来のDevice Pluginとは異なり、スケジューラーと連携した動的なリソース割り当てを実現する。

**業務上の目的・背景**：従来のDevice Plugin APIでは、リソースの割り当てがノード単位で静的に行われ、スケジューリング時の細かな制御が困難だった。DRAにより、カスタムハードウェアリソース（GPU、FPGA、特殊メモリ等）の割り当てをスケジューラーと連携して動的に行え、より柔軟なリソース管理が可能となる。

**機能の利用シーン**：GPU等のハードウェアアクセラレーターの動的割り当て、複数Pod間でのリソース共有、ベンダー固有のリソース割り当てロジックの実装。

**主要な処理内容**：
1. DRAプラグインの登録管理（DRAPluginManager）
2. ResourceClaimのPrepare/Unprepare操作
3. ClaimInfo（割り当て情報）のキャッシュと状態永続化
4. Reconcileループによる割り当て状態の整合性維持
5. DRAドライバーのヘルス情報監視
6. ResourceSliceの管理（ドライバー登録解除時の遅延削除）

**関連システム・外部連携**：DRAプラグイン（gRPC API）、API Server（ResourceClaim/ResourceSlice）、スケジューラー（割り当て決定）、Kubelet Plugin Manager。

**権限による制御**：ResourceClaimはPodのresourceClaimsフィールドで参照し、スケジューラーが割り当てを決定する。Kubeletはノード上での準備/解放のみを担当。

## 関連画面

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

## 機能種別

リソース管理 / デバイス連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ResourceClaim | resourceapi.ResourceClaim | Yes | リソース割り当て要求 | API Serverから取得 |
| Pod | v1.Pod | Yes | ResourceClaimを参照するPod | - |
| driverName | string | Yes | DRAドライバー名 | 登録済みドライバー |

### 入力データソース

- API Server: ResourceClaimオブジェクト
- DRAプラグイン: NodePrepareResources/NodeUnprepareResources RPC
- チェックポイントファイル: 前回の割り当て状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CDIDevices | []string | コンテナに渡すCDI（Container Device Interface）デバイス名 |
| ClaimInfo | claimInfo | 割り当て情報のキャッシュ |

### 出力先

- コンテナ仕様（CDIデバイス設定）
- チェックポイントファイル（dra_manager_state）
- API Server（ResourceSliceの管理）

## 処理フロー

### 処理シーケンス

```
1. DRAプラグイン登録
   └─ Plugin Managerからの通知で登録
2. Pod起動前のPrepare
   └─ ResourceClaim取得 → NodePrepareResources RPC → ClaimInfo保存
3. コンテナ起動時のCDIデバイス設定
   └─ ClaimInfoからCDIデバイス名を取得しコンテナ仕様に追加
4. Reconcileループ
   └─ 活性Pod一覧と割り当て状態の整合性確認
5. Pod終了後のUnprepare
   └─ 最後の使用Podが終了したらNodeUnprepareResources RPC
6. DRAドライバー登録解除時
   └─ defaultWipingDelay後にResourceSlice削除
```

### フローチャート

```mermaid
flowchart TD
    A[Pod起動要求] --> B{ResourceClaim参照あり?}
    B -->|No| C[通常のPod起動]
    B -->|Yes| D[ResourceClaim取得]
    D --> E{既にPrepare済み?}
    E -->|Yes| F[ClaimInfoからCDIデバイス取得]
    E -->|No| G[NodePrepareResources RPC]
    G --> H{Prepare成功?}
    H -->|Yes| I[ClaimInfo保存・チェックポイント]
    H -->|No| J[エラー返却]
    I --> F
    F --> K[コンテナ仕様にCDIデバイス追加]
    K --> L[Pod起動続行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | Prepare必須 | Pod起動前にResourceClaimのPrepareが完了している必要がある | ResourceClaim参照Pod起動時 |
| BR-56-02 | 最終Pod解放 | ResourceClaimを使用する最後のPodが終了したらUnprepare | Pod終了時 |
| BR-56-03 | 遅延削除 | DRAドライバー登録解除後30秒（defaultWipingDelay）待ってからResourceSlice削除 | ドライバー登録解除時 |
| BR-56-04 | Reconcile周期 | 60秒（defaultReconcilePeriod）間隔で状態整合性を確認 | 定期実行 |
| BR-56-05 | チェックポイント復元 | Kubelet再起動時にdra_manager_stateから状態復元 | Kubelet起動時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ClaimInfo | claimInfoCache（インメモリ） | INSERT/UPDATE/DELETE | 割り当て情報のキャッシュ管理 |
| 状態永続化 | dra_manager_state（ファイル） | INSERT/UPDATE | チェックポイント |
| ResourceClaim | API Server（etcd） | SELECT | ResourceClaimの取得 |

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

#### claimInfoCache（インメモリ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | claimUID → ClaimInfo | Prepare結果 | NodePrepareResources成功時 |
| DELETE | claimUID | Unprepare完了 | NodeUnprepareResources成功時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PrepareError | プラグインエラー | NodePrepareResources RPC失敗 | DRAドライバーのログを確認 |
| UnprepareError | プラグインエラー | NodeUnprepareResources RPC失敗 | DRAドライバーのログを確認 |
| ClaimNotFound | 一時エラー | ResourceClaimがAPI Serverに存在しない | スケジューラーの割り当て状態を確認 |
| DriverNotRegistered | 設定エラー | DRAドライバーが登録されていない | ドライバーの起動を確認 |

### リトライ仕様

- Prepare失敗時はPod起動をブロックし、次回同期で再試行
- Reconcileループ（60秒間隔）で状態不整合を自動修復

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

ClaimInfoCacheは内部的に排他制御。チェックポイントへの書き込みは状態変更ごとに実行。

## パフォーマンス要件

- Reconcile間隔: 60秒（defaultReconcilePeriod）
- ドライバー遅延削除: 30秒（defaultWipingDelay）
- DRAプラグインとの通信はgRPCで低レイテンシー

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

- DRAプラグインとの通信はUnix Domainソケット
- ResourceClaimはRBACで保護されたAPI Serverリソース

## 備考

- DRAはKubernetes 1.26以降で導入された比較的新しい機能
- CDI（Container Device Interface）を通じてコンテナにデバイスを公開
- DRAドライバーのヘルス情報はdrahealthv1alpha1 APIで管理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `pkg/kubelet/cm/dra/types.go` | DRA管理の型定義 |
| 1-2 | claiminfo.go | `pkg/kubelet/cm/dra/claiminfo.go` | ClaimInfo構造体とキャッシュ |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | manager.go | `pkg/kubelet/cm/dra/manager.go` | Manager構造体、主要定数 |

**主要処理フロー**:
- **54行目**: draManagerStateFileName = "dra_manager_state"
- **57行目**: defaultReconcilePeriod = 60秒
- **71行目**: defaultWipingDelay = 30秒
- **83-100行目**: Manager構造体のフィールド

#### Step 3: プラグイン連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | plugin/ | `pkg/kubelet/cm/dra/plugin/` | DRAプラグインマネージャーとgRPC通信 |

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

```
Kubelet
    |
    +-- DRA Manager
    |       +-- Start() / reconcileLoop() [60秒間隔]
    |       +-- PrepareResources()
    |       |       +-- kubeClient.ResourceClaims().Get()
    |       |       +-- DRAPlugin.NodePrepareResources() [gRPC]
    |       |       +-- claimInfoCache.add()
    |       |       +-- checkpoint保存
    |       |
    |       +-- UnprepareResources()
    |       |       +-- DRAPlugin.NodeUnprepareResources() [gRPC]
    |       |       +-- claimInfoCache.delete()
    |       |       +-- checkpoint保存
    |       |
    |       +-- GetContainerClaimInfos()
    |               +-- claimInfoCache → CDIDevices
    |
    +-- PluginManager
            +-- DRAPluginManager.PluginConnected()
            +-- DRAPluginManager.PluginDisconnected()
```

### データフロー図

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

API Server               ──▶  ResourceClaim取得     ──▶  ClaimInfo
(ResourceClaim)

DRA Plugin               ──▶  NodePrepareResources  ──▶  CDIデバイス名
(gRPC)                         |
                               v
                         claimInfoCache             ──▶  コンテナ仕様
                               |
                               v
                         チェックポイント保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| manager.go | `pkg/kubelet/cm/dra/manager.go` | ソース | DRAマネージャー主実装 |
| claiminfo.go | `pkg/kubelet/cm/dra/claiminfo.go` | ソース | ClaimInfo構造体とキャッシュ |
| types.go | `pkg/kubelet/cm/dra/types.go` | ソース | 型定義 |
| healthinfo.go | `pkg/kubelet/cm/dra/healthinfo.go` | ソース | ドライバーヘルス情報管理 |
| plugin/ | `pkg/kubelet/cm/dra/plugin/` | ソース | DRAプラグインマネージャー |
| state/ | `pkg/kubelet/cm/dra/state/` | ソース | 状態管理・チェックポイント |
