# 通知設計書 14-ResizeInfeasible

## 概要

本ドキュメントは、KubernetesのkubeletがPodのインプレースリサイズ要求を実行不可能と判断した際に発行されるイベント通知「ResizeInfeasible」の設計を記述する。

### 本通知の処理概要

InPlacePodVerticalScaling機能の一部として、Podのリソースリサイズ要求が構造的な制約により実行不可能と判断された場合に、本通知を発行する。ResizeDeferredとは異なり、リソースが空いても解決しない永続的な制約に対して使用される。

**業務上の目的・背景**：インプレースリサイズが技術的に不可能な状況が存在する。例えば、Guaranteed QoSクラスのPodでCPU Managerがstaticポリシーを使用している場合のCPUリサイズ、Memory Managerがstaticポリシーを使用している場合のメモリリサイズ、スワップ対応コンテナのリサイズなどが該当する。この通知は、ユーザーに対してリサイズが実行されない理由を明確に伝え、代替手段（Podの再作成等）の検討を促す。

**通知の送信タイミング**：allocation_managerのhandlePodResourcesResize処理中、canResizePodまたはIsInPlacePodVerticalScalingAllowedがInfeasible理由を返却した場合に発行される。statusManagerのSetPodResizePendingConditionが新しい状態を設定した場合のみ発行される。

**通知の受信者**：Pod作成を要求したユーザー、Namespace管理者。Kubernetes Eventとして記録される。

**通知内容の概要**：「Pod resize Infeasible: {リソースサマリーJSON}」という形式で、不可能な理由と要求リソースの詳細が通知される。

**期待されるアクション**：ユーザーはインプレースリサイズが不可能であることを理解し、Podの再作成やリソース設定の変更等の代替手段を検討する。

## 通知種別

Kubernetes Event（クラスタ内部イベント通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（allocation_managerの処理フロー内で即時発行） |
| 優先度 | 高（Warning） |
| リトライ | なし（Infeasibleは永続的な状態のため自動リトライ対象外） |

### 送信先決定ロジック

イベントの対象オブジェクトは、リサイズが不可能と判断されたPodリソースである。

## 通知テンプレート

### Kubernetes Eventの場合

| 項目 | 内容 |
|-----|------|
| EventType | Warning |
| Reason | ResizeInfeasible |
| Regarding | 対象Pod |
| 発行元 | kubelet |

### 本文テンプレート

```
Pod resize Infeasible: {"initContainers":[...],"containers":[...],"generation":N,"error":"message"}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| reason | 不可能理由（"Infeasible"） | canResizePod/IsInPlacePodVerticalScalingAllowedの判定結果 | Yes |
| message | 不可能の詳細メッセージ | 判定関数の戻り値 | Yes |
| generation | Podのgeneration | pod.Generation | Yes |
| containers | コンテナ別のリソース要求 | pod.Spec.Containers | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | handlePodResourcesResize | canResizePodがInfeasible理由を返却 | CPUManager/MemoryManagerのstaticポリシー制約等 |
| 内部処理 | handlePodResourcesResize | IsInPlacePodVerticalScalingAllowedがfalse | インプレースリサイズ非対応の構成 |
| 内部処理 | handlePodResourcesResize | disallowResizeForSwappableContainersがtrue | スワップ対応コンテナのリサイズ制約 |
| 内部処理 | handlePodResourcesResize | IsInPlacePodLevelResourcesVerticalScalingAllowedがfalse | Pod-levelリソースのリサイズ非対応 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 既にInfeasible状態の場合 | SetPodResizePendingConditionがfalseを返す場合、イベントは発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[handlePodResourcesResize] --> B[UpdatePodFromAllocation]
    B --> C{リソース変更あり?}
    C -->|なし| D[終了]
    C -->|あり| E{IsInPlacePodVerticalScalingAllowed?}
    E -->|不可| F[SetPodResizePendingCondition Infeasible]
    E -->|可| G{スワップ制約?}
    G -->|あり| F
    G -->|なし| H{Pod-levelリソース変更あり?}
    H -->|あり & 不可| F
    H -->|なし or 可| I[canResizePod]
    I -->|Infeasible| F
    F --> J{状態が変更された?}
    J -->|Yes| K[Event発行: ResizeInfeasible]
    J -->|No| L[イベント発行スキップ]
    I -->|Deferred| M[ResizeDeferredイベント]
    I -->|fit=true| N[リサイズ実行]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| etcd (Pod) | Pod Specのリソース要求・QoSクラス確認 | リサイズ対象のリソース比較 |
| etcd (Node) | ノードの設定情報確認 | CPUManager/MemoryManagerポリシー |

### テーブル別参照項目詳細

#### Pod リソース

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.containers[].resources | リサイズ後のリソース要求 | リサイズ対象のPod |
| QoS Class | Guaranteed判定 | v1qos.GetPodQOS(pod)で算出 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| etcd (Event) | INSERT | Eventオブジェクトの作成 |
| statusManager (内部) | UPDATE | PodResizePendingConditionの設定 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | "ResizeInfeasible" | イベント理由 |
| INSERT | message | "Pod resize Infeasible: {JSON}" | リソースサマリー |
| INSERT | type | "Warning" | イベントタイプ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Guaranteed Pod + CPU Manager static | GuaranteedクラスでCPU Managerがstaticポリシーの場合のCPUリサイズ | InPlacePodVerticalScalingExclusiveCPUs機能ゲートを有効にする、またはPodを再作成 |
| Guaranteed Pod + Memory Manager static | GuaranteedクラスでMemory Managerがstaticポリシーの場合のメモリリサイズ | InPlacePodVerticalScalingExclusiveMemory機能ゲートを有効にする、またはPodを再作成 |
| スワップ対応コンテナ | スワップ再計算を伴うリサイズ | Podを再作成 |
| ノードAllocatable超過 | 要求リソースがノード容量を超過（恒常的） | リソース要求を減らすか別ノードにスケジュール |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（Infeasibleは永続的な判定） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Event Recorderのデフォルトレート制限に準拠 |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

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

- イベントメッセージにはPodのリソース要求のJSON表現が含まれる。機密性は低い。
- InfeasibleメッセージにはCPU Manager/Memory Managerのポリシー情報が含まれる場合がある。

## 備考

- InPlacePodVerticalScaling機能ゲートが有効な場合のみ本通知は発生する。
- Infeasibleと判断されたPodはpendingResizesリストから除外される（allocation_manager.go:278-279行目: リストに再追加されない）。
- メトリクス `PodInfeasibleResizes` にInfeasibleの理由別カウントが記録される（allocation_manager.go:593, 600, 607, 718, 726行目）。
- canResizePod内のInfeasible判定は以下の条件を含む（allocation_manager.go:712-728行目）:
  - Guaranteed QoS + CPU Manager staticポリシー + CPUリサイズ（ExclusiveCPUs機能ゲート無効時）
  - Guaranteed QoS + Memory Manager staticポリシー + メモリリサイズ（ExclusiveMemory機能ゲート無効時）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 38行目: `ResizeInfeasible = "ResizeInfeasible"` 定数 |
| 1-2 | resize.go | `pkg/kubelet/events/resize.go` | 58-59行目: PodResizePendingMsg関数（ResizeDeferredと共有） |

**読解のコツ**: ResizeDeferredとResizeInfeasibleはPodResizePendingMsg関数を共有しており、メッセージ生成ロジックは同一である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | allocation_manager.go | `pkg/kubelet/allocation/allocation_manager.go` | 584-646行目: handlePodResourcesResize関数 |

**主要処理フロー**:
1. **591行目**: IsInPlacePodVerticalScalingAllowedで構造的な制約をチェック
2. **593-594行目**: 不可の場合はInfeasibleとしてSetPodResizePendingCondition
3. **597-601行目**: スワップ対応コンテナのチェック
4. **637-638行目**: reason == v1.PodReasonInfeasibleの場合にeventTypeをResizeInfeasibleに設定

#### Step 3: リサイズ可否判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | allocation_manager.go | `pkg/kubelet/allocation/allocation_manager.go` | 709-728行目: canResizePod関数のInfeasible判定 |

**主要処理フロー**:
- **712行目**: GuaranteedクラスのPodのチェック開始
- **713-719行目**: CPU Manager staticポリシーとCPUリサイズの組み合わせ
- **721-728行目**: Memory Manager staticポリシーとメモリリサイズの組み合わせ
- **735行目以降**: ノードAllocatableとの比較（超過時はInfeasible）

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

```
allocation_manager.RetryPendingResizes
    |
    +-- handlePodResourcesResize (allocation_manager.go:584)
            |
            +-- UpdatePodFromAllocation
            +-- IsInPlacePodVerticalScalingAllowed
            |       +-- (構造的制約チェック)
            +-- disallowResizeForSwappableContainers
            +-- IsInPlacePodLevelResourcesVerticalScalingAllowed
            +-- canResizePod (allocation_manager.go:709)
            |       +-- v1qos.GetPodQOS
            |       +-- CPUManager/MemoryManagerポリシーチェック
            |       +-- ノードAllocatable比較
            +-- statusManager.SetPodResizePendingCondition
            +-- events.PodResizePendingMsg
            +-- recorder.Eventf
```

### データフロー図

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

Pod Spec (desired resources) -> handlePodResourcesResize -> Event (Warning/ResizeInfeasible)
Node Config (policies)      -> canResizePod判定               |
QoS Class                   ->                           statusManager更新
                                                              |
                                                         metrics.PodInfeasibleResizes
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| resize.go | `pkg/kubelet/events/resize.go` | ソース | リサイズイベントメッセージ生成 |
| allocation_manager.go | `pkg/kubelet/allocation/allocation_manager.go` | ソース | リサイズ処理のメインロジック |
| status_manager.go | `pkg/kubelet/status/status_manager.go` | ソース | PodResizePendingConditionの管理 |
