# 機能設計書 32-Taint Evictionコントローラー

## 概要

本ドキュメントは、Kubernetes kube-controller-managerに含まれるTaint Evictionコントローラー（NoExecuteTaintManager）の機能設計を記述する。NoExecute Taintが付与されたノードからPodを退避する処理を担当する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesではノードに対してTaintを付与することで、特定のPodのスケジューリングや実行を制御できる。NoExecute効果のTaintがノードに付与された場合、そのTaintをTolerationで許容していないPodは退避（削除）される必要がある。本コントローラーはこの退避処理を自動的に実行する。

**機能の利用シーン**：ノードの障害検出時（Node Lifecycleコントローラーが`node.kubernetes.io/unreachable`等のTaintを付与）、メンテナンス時のドレイン操作、ユーザーがkubectl taintコマンドでNoExecute Taintを手動付与した場合に動作する。

**主要な処理内容**：
1. ノードのNoExecute Taintの変更を監視し、taintedNodesマップを更新する
2. PodのTolerationの変更を監視し、退避判定を行う
3. Taintに対応するTolerationがないPodを即座に退避対象とする
4. TolerationSecondsが設定されたTolerationの場合、指定時間後に退避をスケジュールする
5. Pod削除前にDisruptionTarget条件を設定し、退避理由を記録する

**関連システム・外部連携**：Node Lifecycleコントローラー、kubectl taintコマンド、Kubernetes API Server

**権限による制御**：Pod/Nodeに対するGet、List、Watch、Delete、Patch権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | kubectl taint | 主機能 | NoExecute Taint追加後にTaint EvictionコントローラーがPod退避を実行する |

## 機能種別

イベント駆動処理 / Pod退避（削除）操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Node.Spec.Taints | []v1.Taint | Yes | ノードのTaintリスト | Effect=NoExecuteのTaintが対象 |
| Pod.Spec.Tolerations | []v1.Toleration | No | PodのTolerationリスト | TolerationSecondsが設定可能 |
| Pod.Spec.NodeName | string | Yes | Podが割り当てられたノード名 | 空でないこと |

### 入力データソース

- Pod Informer: Podの追加・更新・削除イベント
- Node Informer: ノードの追加・更新・削除イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Pod削除 | - | NoExecute Taintを許容しないPodの削除 |
| Pod.Status.Conditions | []v1.PodCondition | DisruptionTarget条件の追加 |
| Events | Event | TaintManagerEvictionイベントの記録 |

### 出力先

- Kubernetes API Server（Pod削除、ステータスパッチ、イベント記録）

## 処理フロー

### 処理シーケンス

```
1. ノード変更イベント受信
   └─ NodeUpdated()でノードのNoExecute Taintを抽出
   └─ nodeUpdateQueueに追加
2. Pod変更イベント受信
   └─ PodUpdated()でTolerationまたはNodeNameの変更を検出
   └─ podUpdateQueueに追加
3. ワーカーがノード更新を優先的に処理
   └─ handleNodeUpdate: taintedNodesマップ更新、該当ノードの全Podを評価
4. Pod個別の退避判定（processPodOnNode）
   └─ Taintなし → 退避キャンセル
   └─ 全Taintが許容されていない → 即座に退避スケジュール
   └─ TolerationSeconds付きで許容 → 指定時間後に退避スケジュール
   └─ 無期限Toleration → 退避キャンセル
5. TimedWorkerQueueが指定時刻にPod削除を実行
   └─ DisruptionTarget条件を追加
   └─ Pod削除APIを呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[Node Taint変更] --> B[taintedNodes更新]
    B --> C[該当ノードの全Podを取得]
    C --> D{Taintあり?}
    D -->|No| E[全退避キャンセル]
    D -->|Yes| F[各Podを評価]
    F --> G{全Taint許容?}
    G -->|No| H[即座に退避]
    G -->|Yes| I{TolerationSeconds?}
    I -->|無期限| J[退避キャンセル]
    I -->|有限| K[指定時間後に退避スケジュール]
    H --> L[DisruptionTarget条件追加]
    K --> L
    L --> M[Pod削除]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-01 | NoExecute Taint退避 | NoExecute TaintをTolerationで許容しないPodを退避する | ノードにNoExecute Taintが存在する場合 |
| BR-32-02 | TolerationSeconds | TolerationSecondsが設定されている場合、その秒数後に退避する | Tolerationが存在しTolerationSecondsが設定されている場合 |
| BR-32-03 | 無期限Toleration | TolerationSecondsがnilの場合は無期限に許容する | Tolerationが存在しTolerationSecondsがnil |
| BR-32-04 | ノード更新優先 | ノード更新をPod更新よりも優先して処理する | ワーカーのイベント処理時 |
| BR-32-05 | ハッシュベース分散 | ノード名のハッシュでワーカーを分散し、同一ノードの処理を直列化する | ワーカー割り当て時 |

### 計算ロジック

- 最小Toleration時間: `getMinTolerationTime()` - 全TolerationSecondsの最小値を取得
- ワーカーハッシュ: `hash(nodeName, UpdateWorkerSize)` - FNV-1aハッシュで分散

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Pod退避 | Pod | DELETE | 退避対象Podの削除 |
| 条件追加 | Pod | PATCH (Status) | DisruptionTarget条件の追加 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | Pod不在 | 削除対象Podが既に存在しない | 正常終了扱い |
| - | 削除失敗 | API Server通信エラー | 最大5回リトライ（10ms間隔） |

### リトライ仕様

- Pod削除: 最大5回リトライ、10ミリ秒間隔
- ワーカー数: UpdateWorkerSize = 8

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

DisruptionTarget条件のパッチとPod削除は別々のAPI呼び出しで実行される。条件追加後にPod削除が失敗した場合、条件のみが残る可能性がある。

## パフォーマンス要件

- NodeUpdateChannelSize: 10
- UpdateWorkerSize: 8
- podUpdateChannelSize: 1

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

- Pod削除前にDisruptionTarget条件を記録し、監査証跡を残す
- イベントとして退避の開始・キャンセルを記録

## 備考

- ノード更新の優先処理により、Taint変更時の応答性を確保している
- PodとNodeの更新が同一ワーカーで処理されるため、taintedNodesマップのレース条件を回避している

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | taint_eviction.go | `pkg/controller/tainteviction/taint_eviction.go` | Controller構造体（83-105行目）、nodeUpdateItem/podUpdateItem（62-70行目） |
| 1-2 | timed_workers.go | `pkg/controller/tainteviction/timed_workers.go` | WorkArgs構造体（31-34行目）、TimedWorker構造体（53-59行目） |

**読解のコツ**: ワーカー分散にFNV-1aハッシュを使用し、同一ノード名のイベントが同一ワーカーで処理される設計。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | taint_eviction.go | `pkg/controller/tainteviction/taint_eviction.go` | New関数（185-276行目）でInformerのイベントハンドラ登録 |

**主要処理フロー**:
1. **185-276行目**: New - Pod/Nodeのインデクサーとイベントハンドラを設定
2. **279-355行目**: Run - キャッシュ同期、チャネル作成、ワーカー起動

#### Step 3: ワーカー処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | taint_eviction.go | `pkg/controller/tainteviction/taint_eviction.go` | worker関数（357-386行目）でノード更新優先の処理ロジック |

**主要処理フロー**:
- **533-588行目**: handleNodeUpdate - taintedNodes更新と全Pod評価
- **492-531行目**: handlePodUpdate - 個別Pod再評価
- **451-490行目**: processPodOnNode - 退避判定の中核ロジック

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

```
New (185行目)
    ├─ PodUpdated (389行目) → podUpdateQueue.Add
    └─ NodeUpdated (421行目) → nodeUpdateQueue.Add

Run (279行目)
    └─ worker (357行目)
        ├─ handleNodeUpdate (533行目)
        │   ├─ taintedNodes更新
        │   ├─ getPodsAssignedToNode
        │   └─ processPodOnNode (451行目)
        │       ├─ getMatchingTolerations
        │       ├─ getMinTolerationTime (161行目)
        │       └─ taintEvictionQueue.AddWork
        └─ handlePodUpdate (492行目)
            └─ processPodOnNode (451行目)

deletePodHandler (107行目)
    └─ addConditionAndDeletePod (129行目)
        ├─ PatchPodStatus (DisruptionTarget条件)
        └─ Pods().Delete
```

### データフロー図

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

Node Taint変更  ──▶  nodeUpdateQueue ──▶ worker   ──▶  Pod削除
                          │              (優先処理)      │
Pod Toleration  ──▶  podUpdateQueue  ──▶ worker   ──▶  DisruptionTarget条件
  変更                    │                              │
                     taintedNodes Map                    Events
                          │
                     processPodOnNode
                          │
                     TimedWorkerQueue ──▶ deletePodHandler
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| taint_eviction.go | `pkg/controller/tainteviction/taint_eviction.go` | ソース | コントローラー本体 |
| timed_workers.go | `pkg/controller/tainteviction/timed_workers.go` | ソース | 時間指定ワーカーキュー |
| namespacedobject.go | `pkg/controller/tainteviction/namespacedobject.go` | ソース | NamespacedObject型定義 |
| metrics/ | `pkg/controller/tainteviction/metrics/` | ソース | メトリクス（PodDeletionsTotal等） |
| doc.go | `pkg/controller/tainteviction/doc.go` | ソース | パッケージドキュメント |
