# 通知設計書 18-FailedNodeDeclaredFeaturesCheck

## 概要

本ドキュメントは、KubernetesのkubeletがPodの要求するノード機能がノード上で利用不可であることを検出した際に発行されるイベント通知「FailedNodeDeclaredFeaturesCheck」の設計を記述する。

### 本通知の処理概要

NodeDeclaredFeatures機能の一部として、PodがPod更新時に要求するノード機能（Node Declared Features）がノード上で利用できない場合に本通知を発行する。ノードが宣言した機能セットとPodが要求する機能セットを照合し、不一致がある場合に警告する。

**業務上の目的・背景**：NodeDeclaredFeatures機能は、ノードが提供する機能をPodが明示的に要求できるようにする仕組みである。Pod更新時にPodが新たに要求する機能がノード上で利用できない場合、この通知によりユーザーに問題を報告する。これにより、互換性のない機能要求による予期しない動作を早期に検知できる。

**通知の送信タイミング**：kubeletのHandlePodUpdates処理中、NodeDeclaredFeatures機能ゲートが有効で、Pod更新時にInferForPodUpdateが要求する機能セットを推論し、MatchNodeFeatureSetがマッチしない場合に発行される。

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

**通知内容の概要**：「Pod requires node features that are not available: {不足機能リスト}」という形式で、ノード上で利用できない機能の一覧が通知される。

**期待されるアクション**：ユーザーはPodが要求する機能がノード上で利用可能か確認し、必要に応じてPodの機能要求を修正するか、要求する機能を提供するノードへPodを再スケジュールする。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（HandlePodUpdates処理フロー内で即時発行） |
| 優先度 | 高（Warning） |
| リトライ | なし（Pod更新ごとにチェックされる） |

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

イベントの対象オブジェクトは、機能チェックに失敗したPodリソースである。

## 通知テンプレート

### Kubernetes Eventの場合

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

### 本文テンプレート

```
Pod requires node features that are not available: {missingNodeDeclaredFeatures}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| missingNodeDeclaredFeatures | 不足しているノード機能のカンマ区切りリスト | matchResult.UnsatisfiedRequirements | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | HandlePodUpdates | NodeDeclaredFeatures機能ゲート有効 かつ InferForPodUpdateが機能要件を返却 かつ MatchNodeFeatureSetがIsMatch=false | ノード機能の不一致 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| NodeDeclaredFeatures機能ゲート無効 | 機能ゲートが無効の場合、チェック自体が実行されない |
| oldPodがnil | oldPodがnilの場合、チェックがスキップされる |
| 要件が空 | InferForPodUpdateが空の要件セットを返す場合、チェックがスキップされる |
| 全機能がマッチ | MatchNodeFeatureSetがIsMatch=trueの場合、イベントは発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[HandlePodUpdates] --> B{NodeDeclaredFeatures有効?}
    B -->|No| C[スキップ]
    B -->|Yes| D{oldPod != nil?}
    D -->|No| C
    D -->|Yes| E[InferForPodUpdate]
    E --> F{要件あり?}
    F -->|No| C
    F -->|Yes| G[MatchNodeFeatureSet]
    G --> H{IsMatch?}
    H -->|Yes| C
    H -->|No| I[不足機能リスト生成]
    I --> J[Event発行: FailedNodeDeclaredFeaturesCheck]
    J --> K[podWorkers.UpdatePod実行]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| etcd (Pod) | 旧Pod/新PodのSpec/Status | 機能要件の推論 |
| ノード内部状態 | nodeDeclaredFeaturesSet | ノードが宣言している機能セット |

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

#### Pod リソース

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec | 旧Pod/新PodのSpec比較 | Pod更新イベント |
| status | 旧Pod/新PodのStatus比較 | Pod更新イベント |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| etcd (Event) | INSERT | Eventオブジェクトの作成 |

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | "FailedNodeDeclaredFeaturesCheck" | イベント理由 |
| INSERT | message | "Pod requires node features..." | 不足機能リスト |
| INSERT | type | "Warning" | イベントタイプ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 機能推論失敗 | InferForPodUpdateがエラーを返却 | ログ出力されるが、Pod更新処理は継続される |
| マッチング失敗 | MatchNodeFeatureSetがエラーを返却 | ログ出力されるが、Pod更新処理は継続される |
| ノード機能不足 | 要求機能がノード上で利用不可 | Podの機能要求を修正するか、別ノードへ再スケジュール |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（Pod更新ごとにチェック） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし。

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

- イベントメッセージにはノードが不足している機能名が含まれる。これはノードの能力情報であり、機密性は中程度。

## 備考

- NodeDeclaredFeatures機能ゲートが有効な場合のみ本通知は発生する。
- kubelet.go:2829-2848行目にチェックとイベント発行コードがある。
- このチェックはPod更新時（HandlePodUpdates内）のみ実行され、Pod作成時には別のチェックパスが存在する可能性がある。
- InferForPodUpdateやMatchNodeFeatureSetのエラーは、Pod更新処理をブロックしない（エラーログ出力後に処理が継続される）。
- 不足機能のリストはstrings.Joinでカンマ区切りに結合される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 42行目: `FailedNodeDeclaredFeaturesCheck = "FailedNodeDeclaredFeaturesCheck"` 定数 |

**読解のコツ**: この機能はNodeDeclaredFeatures機能ゲートに依存しており、比較的新しい機能である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kubelet.go | `pkg/kubelet/kubelet.go` | 2829-2848行目: HandlePodUpdates内のノード機能チェック |

**主要処理フロー**:
1. **2829行目**: `utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures)` で機能ゲートチェック
2. **2830-2831行目**: 旧Pod/新PodのPodInfo構造体を作成
3. **2832行目**: `kl.nodeDeclaredFeaturesFramework.InferForPodUpdate` で要求機能を推論
4. **2836行目**: `reqs.Len() != 0` で要件の有無を確認
5. **2837行目**: `ndf.MatchNodeFeatureSet(reqs, kl.nodeDeclaredFeaturesSet)` でマッチング
6. **2842行目**: `!matchResult.IsMatch` で不一致を判定
7. **2843行目**: `strings.Join(matchResult.UnsatisfiedRequirements, ", ")` で不足機能リスト生成
8. **2845行目**: `recorder.Eventf` でイベント発行

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

```
Kubelet.HandlePodUpdates (kubelet.go:2829)
    |
    +-- features.NodeDeclaredFeatures 機能ゲートチェック
    |
    +-- ndf.PodInfo構造体作成 (oldPod, newPod)
    |
    +-- nodeDeclaredFeaturesFramework.InferForPodUpdate
    |       +-- (要求機能セットの推論)
    |
    +-- ndf.MatchNodeFeatureSet
    |       +-- (ノード機能セットとのマッチング)
    |
    +-- strings.Join(UnsatisfiedRequirements)
    |
    +-- recorder.Eventf
```

### データフロー図

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

oldPod Spec/Status -------> InferForPodUpdate
newPod Spec/Status -------> (要求機能推論)
                                |
nodeDeclaredFeaturesSet --> MatchNodeFeatureSet
                                |
                                +-- UnsatisfiedRequirements --> Event (Warning/FailedNodeDeclaredFeaturesCheck)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| kubelet.go | `pkg/kubelet/kubelet.go` | ソース | HandlePodUpdates内のノード機能チェックとイベント発行 |
