# 機能設計書 18-Node Lifecycleコントローラー

## 概要

本ドキュメントは、Kubernetes Node Lifecycleコントローラーの機能設計を記述する。ノードのヘルスモニタリングを行い、異常ノードへのTaint付与やPodのエビクション管理を行う。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスタ内のノードは障害・ネットワーク分断・リソース枯渇など様々な理由で正常に動作しなくなる可能性がある。Node Lifecycleコントローラーはノードの健全性を継続的にモニタリングし、異常を検出した場合にTaintを付与してスケジューリング対象から除外し、必要に応じてPodのエビクションを行う。ゾーン全体の障害時にはレート制限を適用し、不必要な大規模エビクションを防止する。

**機能の利用シーン**：ノード障害検出、ネットワーク分断対応、ノードコンディション変化への自動対応、ラベル調整。

**主要な処理内容**：
1. ノードヘルスの定期監視（monitorNodeHealth）
2. NodeConditionに基づくTaint自動付与（NotReady/Unreachable等）
3. ゾーン単位の障害検出と適応的レート制限
4. Nodeラベルの調整（beta/stableラベルの同期）
5. Lease（ハートビート）に基づくノード到達性判定
6. TaintEvictionController連携（SeparateTaintEvictionController無効時）

**関連システム・外部連携**：API Server、Kubelet（NodeStatusおよびLease更新）、TaintEvictionController（Taintに基づくPodエビクション）

**権限による制御**：Node、Pod、Leaseリソースの読み取りおよびNodeの更新権限。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Node Lifecycleコントローラーは直接の画面を持たない |

## 機能種別

コントローラー / ノード管理 / ヘルスモニタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| nodeMonitorPeriod | time.Duration | Yes | ノードヘルスチェック間隔 | - |
| nodeStartupGracePeriod | time.Duration | Yes | ノード起動猶予期間 | - |
| nodeMonitorGracePeriod | time.Duration | Yes | ヘルスシグナル未受信の猶予期間 | - |
| evictionLimiterQPS | float32 | Yes | エビクションレート制限（通常時） | - |
| secondaryEvictionLimiterQPS | float32 | Yes | エビクションレート制限（障害時） | - |
| largeClusterThreshold | int32 | Yes | 大規模クラスタ判定閾値 | - |
| unhealthyZoneThreshold | float32 | Yes | ゾーン異常判定の不健全ノード割合 | - |

### 入力データソース

- Kubernetes API Server: Node Informer
- Kubernetes API Server: Pod Informer
- Kubernetes API Server: Lease Informer
- Kubernetes API Server: DaemonSet Informer

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Node.spec.taints | []Taint | NotReady/Unreachable Taint |
| Node.status.conditions | []NodeCondition | Ready=Unknownの設定 |
| Node.metadata.labels | map[string]string | beta/stableラベル調整 |

### 出力先

- Kubernetes API Server: Node更新（Taint、Condition、ラベル）
- Kubernetes Events: NodeNotReady/NodeReady等のイベント

## 処理フロー

### 処理シーケンス

```
1. コントローラー初期化
   a. Informerハンドラ登録（Pod/Node/Lease/DaemonSet）
   b. TaintEvictionController初期化（SeparateTaintEvictionController無効時）
2. Run開始
   a. taintManager.Run（Taintに基づくPodエビクション）
   b. doNodeProcessingPassWorker（ノード更新キュー処理）
   c. doPodProcessingWorker（Pod更新キュー処理）
   d. monitorNodeHealth（定期ヘルスチェック、nodeMonitorPeriod間隔）
3. monitorNodeHealth
   a. 全ノードを取得し各ノードの状態を評価
   b. Leaseとの組み合わせでヘルス判定
   c. nodeMonitorGracePeriod超過時にReady=Unknownを設定
   d. ゾーン状態の計算（Normal/PartialDisruption/FullDisruption）
   e. ゾーン状態に応じたエビクションレートの調整
4. doNodeProcessing
   a. ノードのConditionに基づくTaint付与/除去
   b. ラベル調整（beta/stableラベル同期）
```

### フローチャート

```mermaid
flowchart TD
    A[Run] --> B[taintManager.Run]
    A --> C[doNodeProcessingPassWorker]
    A --> D[doPodProcessingWorker]
    A --> E[monitorNodeHealth ループ]
    E --> F[全ノード状態評価]
    F --> G{Lease + Status チェック}
    G -->|正常| H[Taint除去]
    G -->|猶予期間超過| I[Ready=Unknown設定]
    I --> J[NotReady/Unreachable Taint付与]
    J --> K[ゾーン状態計算]
    K --> L{ゾーン状態}
    L -->|Normal| M[通常エビクションレート]
    L -->|PartialDisruption| N[低速エビクションレート]
    L -->|FullDisruption| O[全速エビクションレート]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | NotReady Taint | NodeReady=FalseのノードにNotReady Taint付与 | 常時 |
| BR-02 | Unreachable Taint | NodeReady=UnknownのノードにUnreachable Taint付与 | 常時 |
| BR-03 | ゾーン適応レート | 部分障害時はsecondaryEvictionLimiterQPSに低下 | PartialDisruption |
| BR-04 | 全障害停止 | ゾーン全障害時はエビクション停止 | FullDisruption（大規模クラスタ） |
| BR-05 | ラベル調整 | beta/stableラベルの値を同期 | 常時 |
| BR-06 | Lease併用判定 | NodeStatus + Leaseの両方でヘルス判定 | 常時 |

### 計算ロジック

- ゾーン状態判定: ゾーン内の(不健全ノード数 / 全ノード数) >= unhealthyZoneThreshold → PartialDisruption
- FullDisruption: 不健全ノード数 == 全ノード数
- retrySleepTime = 20ms
- podUpdateWorkerSize = 4
- nodeUpdateWorkerSize = 8

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Node更新 | Nodes (etcd) | UPDATE | Taint/Condition/ラベル更新 |
| Event作成 | Events (etcd) | INSERT | NodeNotReady等のイベント |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Node更新失敗 | Taint/Condition更新失敗 | nodesToRetryに追加して次回monitorNodeHealthでリトライ |
| - | API通信エラー | Lease取得失敗等 | 次回monitorNodeHealthでリトライ |

### リトライ仕様

- monitorNodeHealth: nodeMonitorPeriod間隔で定期実行
- nodesToRetry: 失敗ノードを記録し次回のmonitorNodeHealthで再処理

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

各ノードの更新は独立して行われる。一部のノード更新が失敗しても他のノードの処理は継続される。

## パフォーマンス要件

- nodeMonitorPeriod: 通常5秒間隔
- nodeUpdateWorkerSize: 8（並列処理数）
- podUpdateWorkerSize: 4（Pod更新並列処理数）
- エビクションレート制限によるAPI Server負荷管理

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

- Taint/Conditionの更新はクラスタ全体のワークロード配置に影響する
- 誤ったNodeCondition判定はサービス断を引き起こす可能性がある
- nodeMonitorGracePeriodの設定が重要（HTTP2ヘルスチェックタイムアウトとの整合性）

## 備考

- SeparateTaintEvictionControllerフィーチャーゲート: TaintEvictionControllerを分離するか、Node Lifecycleに内蔵するかを制御
- ZoneState: Initial → Normal → PartialDisruption → FullDisruptionの遷移
- nodeConditionToTaintKeyStatusMap: NodeConditionTypeからTaintKeyへのマッピング定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | 定数・変数定義（69-114行目）: Taintテンプレート、nodeConditionToTaintKeyStatusMap |
| 1-2 | node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | Controller構造体（218-303行目）、nodeHealthData/nodeHealthMap（168-210行目） |

**読解のコツ**: ZoneState（Initial/Normal/PartialDisruption/FullDisruption）の遷移がエビクションレートを制御する中核概念。nodeConditionToTaintKeyStatusMapにより、どのConditionにどのTaintを付与するかが定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | NewNodeLifecycleController（306-444行目）: 各種Informerハンドラ登録 |
| 2-2 | node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | Run（447行目以降）: ワーカーとmonitorNodeHealthの起動 |

**主要処理フロー**:
1. **306-444行目**: Pod/Node/Lease/DaemonSet Informerのハンドラ登録、TaintEvictionController初期化
2. **447行目以降**: taintManager.Run、doNodeProcessingPassWorker、doPodProcessingWorker、monitorNodeHealthの起動

#### Step 3: monitorNodeHealthを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | monitorNodeHealth: 定期的にノード状態を評価しTaint/Conditionを更新 |

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

```
NewNodeLifecycleController (初期化)
    |
    +-- Run
        |
        +-- taintManager.Run (TaintEviction)
        +-- doNodeProcessingPassWorker (nodeUpdateQueue処理)
        |       +-- doNoScheduleTaintingPass (Taint付与)
        |       +-- reconcileNodeLabels (ラベル調整)
        |
        +-- doPodProcessingWorker (podUpdateQueue処理)
        |
        +-- monitorNodeHealth (定期ヘルスチェック)
                +-- tryUpdateNodeHealth (ノードヘルス判定)
                +-- computeZoneState (ゾーン状態計算)
                +-- handleDisruption (エビクションレート調整)
```

### データフロー図

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

Node Informer ---+
                 |
Lease Informer --+--> monitorNodeHealth --> tryUpdateNodeHealth
                 |                              |
Pod Informer ----+                              +--> Taint付与/除去 (API Server)
                 |                              +--> Condition更新 (API Server)
DaemonSet Informer                              +--> Event記録 (API Server)
                                                +--> computeZoneState → エビクションレート調整
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node_lifecycle_controller.go | `pkg/controller/nodelifecycle/node_lifecycle_controller.go` | ソース | メインコントローラーロジック |
| scheduler/ | `pkg/controller/nodelifecycle/scheduler/` | ソース | RateLimitedTimedQueue |
| metrics.go | `pkg/controller/nodelifecycle/metrics.go` | ソース | Prometheusメトリクス |
| tainteviction/ | `pkg/controller/tainteviction/` | ソース | TaintEvictionController |
| config/ | `pkg/controller/nodelifecycle/config/` | 設定 | コントローラー設定構造体 |
