# 機能設計書 19-TTLコントローラー

## 概要

本ドキュメントは、Kubernetes TTLコントローラーの機能設計を記述する。クラスタサイズに基づいてNodeにTTLアノテーションを設定し、Kubeletのキャッシュ有効期間を制御する。

### 本機能の処理概要

**業務上の目的・背景**：KubeletはAPI Serverからsecret/configmap等のオブジェクトを取得し、ローカルにキャッシュする。クラスタが小さい場合は頻繁にリフレッシュしても問題ないが、大規模クラスタではAPI Serverへの負荷が増大する。TTLコントローラーはクラスタサイズに基づいて適切なTTL（Time To Live）値をNodeにアノテーションとして設定し、Kubeletのキャッシュ期間を動的に調整する。

**機能の利用シーン**：クラスタのスケールアップ/ダウン時、ノード追加/削除時に自動的にTTL値が調整される。

**主要な処理内容**：
1. クラスタ内のノード数の追跡
2. ノード数に基づくTTL境界値の決定
3. 各ノードへのTTLアノテーション（`node.alpha.kubernetes.io/ttl`）の設定
4. ノード追加/削除に応じたTTL境界のシフト

**関連システム・外部連携**：API Server（NodeアノテーションのPatch更新）、Kubelet（TTLアノテーションの読み取りとキャッシュ制御）

**権限による制御**：NodeのPatch権限。

## 関連画面

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

## 機能種別

コントローラー（Reconciliation Loop） / アノテーション管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | コントローラー固有の入力パラメータなし | - |

### 入力データソース

- Kubernetes API Server: Node Informer

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Node.metadata.annotations[`node.alpha.kubernetes.io/ttl`] | string | TTL値（秒、整数文字列） |

### 出力先

- Kubernetes API Server: Nodeアノテーションの更新（Strategic Merge Patch）

## 処理フロー

### 処理シーケンス

```
1. ノードイベント受信
   a. Add: nodeCount++、boundaryStep調整、ノードをキューに追加
   b. Update: ノードをキューに追加
   c. Delete: nodeCount--、boundaryStep調整
2. workerがデキューしupdateNodeIfNeededを実行
   a. NodeListerからノード取得
   b. 現在のTTLアノテーション値を取得
   c. desiredTTLSecondsと比較
   d. 異なる場合のみPatch更新
```

### フローチャート

```mermaid
flowchart TD
    A[Node Add] --> B[nodeCount++]
    B --> C{sizeMax超過?}
    C -->|Yes| D[boundaryStep++, desiredTTL更新]
    C -->|No| E[エンキュー]
    D --> E

    F[Node Delete] --> G[nodeCount--]
    G --> H{sizeMin未満?}
    H -->|Yes| I[boundaryStep--, desiredTTL更新]
    H -->|No| J[処理終了]

    K[Node Update] --> L[エンキュー]

    E --> M[updateNodeIfNeeded]
    L --> M
    M --> N{現在TTL == desiredTTL?}
    N -->|Yes| O[スキップ]
    N -->|No| P[Patch更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | TTL境界0 | 0-100ノード: TTL=0秒（キャッシュなし） | nodeCount <= 100 |
| BR-02 | TTL境界1 | 90-500ノード: TTL=15秒 | 90 <= nodeCount <= 500 |
| BR-03 | TTL境界2 | 450-1000ノード: TTL=30秒 | 450 <= nodeCount <= 1000 |
| BR-04 | TTL境界3 | 900-2000ノード: TTL=60秒 | 900 <= nodeCount <= 2000 |
| BR-05 | TTL境界4 | 1800-MaxInt32ノード: TTL=300秒 | nodeCount >= 1800 |
| BR-06 | ヒステリシス | sizeMin/sizeMaxにオーバーラップを設けて振動を防止 | 常時 |
| BR-07 | 冪等更新 | 現在のTTL値と同じ場合はPatch更新しない | 常時 |

### 計算ロジック

TTL境界テーブル（ttlBoundaries）:

| boundaryStep | sizeMin | sizeMax | ttlSeconds |
|-------------|---------|---------|------------|
| 0 | 0 | 100 | 0 |
| 1 | 90 | 500 | 15 |
| 2 | 450 | 1000 | 30 |
| 3 | 900 | 2000 | 60 |
| 4 | 1800 | MaxInt32 | 300 |

- ノード追加時: nodeCountがcurrent boundaryのsizeMaxを超えるとboundaryStep++
- ノード削除時: nodeCountがcurrent boundaryのsizeMinを下回るとboundaryStep--
- sizeMin/sizeMaxのオーバーラップにより、境界付近での頻繁なTTL変更を防止

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Node更新 | Nodes (etcd) | PATCH | TTLアノテーションの設定 |

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

#### Nodes (etcd)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| PATCH | metadata.annotations[`node.alpha.kubernetes.io/ttl`] | desiredTTLSeconds（文字列） | Strategic Merge Patch |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NotFound | ノードが削除済み | 正常としてスキップ |
| - | Patch失敗 | API更新の通信エラー | RateLimited requeue |

### リトライ仕様

- Patch失敗時: RateLimited requeue

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

Strategic Merge Patchにより、アノテーションのみを更新する。ResourceVersionベースのconflict検出は暗黙的に行われる。

## パフォーマンス要件

- ワーカー数: 起動時に指定
- nodeCountとdesiredTTLSecondsはRWMutexで保護
- TTLアノテーションの更新は値が変わった場合のみ

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

- TTL値はKubeletのキャッシュ期間に影響するため、Secretの更新がKubeletに反映されるまでの遅延に直接影響する
- TTLが長すぎるとセキュリティ更新の反映が遅れる

## 備考

- alpha機能: アノテーションキーに"alpha"が含まれる
- 将来的にはKubeletがwatchベースでsecretを取得する方式に移行し、このコントローラーは不要になる予定
- Kubeletは10秒間隔でノードステータスを更新するため、TTLアノテーションはその間隔で更新される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | Controller構造体（56-78行目）、ttlBoundary構造体（106-110行目）、ttlBoundaries変数（112-120行目） |

**読解のコツ**: ttlBoundariesのsizeMin/sizeMaxにオーバーラップ（ヒステリシス）がある点が重要。これにより、ノード数が境界付近で変動してもTTLが頻繁に切り替わることを防止している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | NewTTLController（81-104行目）: Node Informerハンドラ登録 |
| 2-2 | ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | Run（123-146行目）: ワーカー起動 |

**主要処理フロー**:
1. **81-104行目**: NewTTLController: Informerハンドラ登録（Add/Update/Delete）
2. **123-146行目**: Run: キャッシュ同期後にワーカー起動
3. **148-165行目**: addNode: nodeCount++、boundaryStep調整
4. **167-178行目**: updateNode: ノードをキューに追加
5. **181-206行目**: deleteNode: nodeCount--、boundaryStep調整
6. **295-311行目**: updateNodeIfNeeded: TTLアノテーション更新

#### Step 3: 更新処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | updateNodeIfNeeded（295-311行目）: TTL比較とPatch更新 |
| 3-2 | ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | patchNodeWithAnnotation（271-293行目）: Strategic Merge Patchの実行 |

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

```
NewTTLController (初期化)
    |
    +-- Run (ワーカー起動)
        |
        +-- worker -> processItem -> updateNodeIfNeeded
                |
                +-- nodeStore.Get (ノード取得)
                +-- getDesiredTTLSeconds (desiredTTL取得)
                +-- getIntFromAnnotation (現在TTL取得)
                +-- patchNodeWithAnnotation (Patch更新)
                        +-- strategicpatch.CreateTwoWayMergePatch
                        +-- kubeClient.CoreV1().Nodes().Patch
```

### データフロー図

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

Node Informer (Add) --> addNode --> nodeCount++
                        enqueueNode --> queue --> updateNodeIfNeeded --> Node Patch (API Server)
Node Informer (Update) --> updateNode --> enqueueNode --> queue
Node Informer (Delete) --> deleteNode --> nodeCount--
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ttl_controller.go | `pkg/controller/ttl/ttl_controller.go` | ソース | メインコントローラーロジック |
