# 機能設計書 31-ServiceCIDRsコントローラー

## 概要

本ドキュメントは、Kubernetes kube-controller-managerに含まれるServiceCIDRsコントローラーの機能設計を記述する。ServiceCIDRリソースのライフサイクル管理およびIP割り当て範囲の保護を担う。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターでは、Serviceに割り当てるIPアドレスの範囲（CIDR）を管理する必要がある。ServiceCIDRリソースはこのCIDR範囲を定義し、ServiceCIDRsコントローラーはその作成・削除時のライフサイクルを管理する。特に、削除時にIPアドレスが孤立しないようFinalizerによる保護機構を提供する。

**機能の利用シーン**：クラスター管理者がServiceのIPアドレス範囲を拡張・縮小する際に使用される。新しいServiceCIDRの追加、不要になったServiceCIDRの削除、既存CIDRの状態確認などの場面で本コントローラーが自動的に動作する。

**主要な処理内容**：
1. ServiceCIDRリソースの作成時にFinalizer（`networking.k8s.io/service-cidr-finalizer`）を付与する
2. ServiceCIDRリソースのReady条件をステータスに反映する
3. ServiceCIDR削除時に、そのCIDR範囲に属するIPAddressリソースが存在しないことを確認してからFinalizerを除去する
4. 重複するCIDR範囲を持つServiceCIDR間の依存関係を管理する
5. IPAddressリソースの追加・削除イベントを監視し、関連するServiceCIDRの状態を再評価する

**関連システム・外部連携**：Kubernetes API Server（Networking API v1）、IPAddressリソース、ipallocatorモジュールと連携する。

**権限による制御**：ServiceCIDRリソースおよびIPAddressリソースに対するGet、List、Patch権限が必要。kube-controller-managerのサービスアカウントで実行される。

## 関連画面

本機能はCLI/API経由で操作されるバックエンドコントローラーであり、直接的な画面関連はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | kubectl get servicecidrs | 参照画面 | ServiceCIDRリソースの一覧・状態確認 |

## 機能種別

CRUD操作（ServiceCIDRリソースのステータス更新・Finalizer管理）/ バリデーション（削除可否判定）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ServiceCIDR.Name | string | Yes | ServiceCIDRリソースの名前 | Kubernetesリソース名の規則に従う |
| ServiceCIDR.Spec.CIDRs | []string | Yes | CIDR範囲のリスト（例: "10.96.0.0/16"） | 有効なCIDR表記であること |
| workers | int | Yes | 並列ワーカー数 | 正の整数 |

### 入力データソース

- ServiceCIDR Informer: ServiceCIDRリソースの変更イベント
- IPAddress Informer: IPAddressリソースの追加・削除イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ServiceCIDR.Status.Conditions | []metav1.Condition | ServiceCIDRの状態条件（Ready=True/False） |
| ServiceCIDR.Metadata.Finalizers | []string | Finalizerの追加・削除 |

### 出力先

- Kubernetes API Server（ServiceCIDRリソースのステータス更新、メタデータパッチ）
- Kubernetes Eventリソース（エラーイベントの記録）

## 処理フロー

### 処理シーケンス

```
1. ServiceCIDR/IPAddressの変更イベントを受信
   └─ Informerのイベントハンドラが発火し、対象キーをワークキューに追加
2. ワーカーがキューからキーを取得
   └─ processNext()でキューからデキュー
3. ServiceCIDRリソースをキャッシュから取得
   └─ 存在しない場合はスキップ
4. 削除中（DeletionTimestamp != nil）の場合
   └─ canDeleteCIDR()で削除可否を判定
      ├─ 親CIDRが存在する場合 → 安全に削除可能
      └─ 孤立IPが存在する場合 → 削除をブロック（Terminating条件を設定）
   └─ 削除可能な場合、猶予期間（10秒）経過後にFinalizerを除去
5. 作成・更新の場合
   └─ Finalizerが未付与であれば追加
   └─ Ready=True条件をステータスに設定
```

### フローチャート

```mermaid
flowchart TD
    A[イベント受信] --> B[キューからキーを取得]
    B --> C{ServiceCIDR存在?}
    C -->|No| D[スキップ]
    C -->|Yes| E{削除中?}
    E -->|Yes| F{削除可能?}
    F -->|Yes| G{猶予期間経過?}
    G -->|Yes| H[Finalizer除去]
    G -->|No| I[遅延再キューイング]
    F -->|No| J[Terminating条件設定]
    E -->|No| K[Finalizer追加]
    K --> L[Ready=True条件設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | Finalizer保護 | ServiceCIDR作成時に`networking.k8s.io/service-cidr-finalizer`を付与する | ServiceCIDR作成・更新時 |
| BR-31-02 | 孤立IP防止 | CIDRに属するIPAddressが他のServiceCIDRでカバーされない場合、削除をブロックする | ServiceCIDR削除時 |
| BR-31-03 | 削除猶予期間 | 削除可能と判定されてから10秒の猶予期間を設ける | ServiceCIDR削除時 |
| BR-31-04 | 最大リトライ | 最大15回のリトライ後にキューからドロップする | sync失敗時 |
| BR-31-05 | 親CIDR判定 | 削除対象CIDRを包含する別のServiceCIDRが存在すれば安全に削除可能 | ServiceCIDR削除時 |

### 計算ロジック

- CIDR重複判定: `servicecidr.OverlapsPrefix()`を使用してCIDR範囲の重複を検出
- IP包含判定: `servicecidr.ContainsAddress()`を使用してIPアドレスがCIDR範囲内か判定
- CIDR包含判定: `servicecidr.ContainsPrefix()`を使用してCIDR範囲が別のCIDRに包含されるか判定

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Finalizer追加 | ServiceCIDR | PATCH | メタデータにFinalizerを追加 |
| Finalizer除去 | ServiceCIDR | PATCH | メタデータからFinalizerを除去 |
| ステータス更新 | ServiceCIDR | APPLY (Status) | Ready条件の更新 |
| IPAddress一覧取得 | IPAddress | LIST | ラベルセレクタによるIPAddress取得 |

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

#### ServiceCIDR

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| PATCH | metadata.finalizers | `networking.k8s.io/service-cidr-finalizer`の追加/削除 | Strategic Merge Patch使用 |
| APPLY | status.conditions | Ready条件（Type, Status, Reason, Message, LastTransitionTime） | Server-Side Apply、FieldManager=service-cidr-controller |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | リソース不在 | ServiceCIDRが既に削除されている | スキップ（正常終了扱い） |
| Conflict | 競合エラー | 同時更新によるパッチ失敗 | レートリミット付きリトライ |
| - | リトライ上限超過 | 15回のリトライ失敗 | キューからドロップし、エラーログ出力 |

### リトライ仕様

- 最大リトライ回数: 15回
- バックオフ: 指数バックオフ（5ms * 2^(retry-1)）
- 最大遅延: 約82秒

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

etcdへのAPI操作は個別のHTTPリクエストとして実行される。Finalizer追加とステータス更新は別々のAPI呼び出しで行われるため、中間状態が発生しうるが、リトライにより最終的に一貫性が保たれる。

## パフォーマンス要件

- ワーカーループ周期: 1秒
- 削除猶予期間: 10秒
- IPAddress一覧取得はラベルセレクタを使用して効率化

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

- kube-controller-managerのサービスアカウント権限で動作
- ServiceCIDRリソースはクラスタースコープのリソースであり、クラスター管理者レベルの権限が必要
- IPAddressリソースは`networking.k8s.io/managed-by`ラベルで管理元を識別し、kube-apiserverが管理するもののみ対象とする

## 備考

- ServiceCIDRsコントローラーはKubernetes 1.29でAlpha、1.31でBetaとして導入された
- デフォルトのServiceCIDR（kubernetes）は kube-apiserver 起動時に自動作成される

---

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

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

### 推奨読解順序

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

ServiceCIDRリソースとIPAddressリソースの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | servicecidrs_controller.go | `pkg/controller/servicecidrs/servicecidrs_controller.go` | Controller構造体（110-125行目）でフィールドを確認 |

**読解のコツ**: Controller構造体は`workqueue.TypedRateLimitingInterface[string]`を使用しており、キーはServiceCIDRの名前（string）である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | servicecidrs_controller.go | `pkg/controller/servicecidrs/servicecidrs_controller.go` | NewController関数（70-107行目）でInformerのイベントハンドラ登録を確認 |

**主要処理フロー**:
1. **70-107行目**: NewController - ServiceCIDR/IPAddressのInformerにイベントハンドラを登録
2. **128-155行目**: Run - キャッシュ同期待ち後にワーカーを起動
3. **256-259行目**: worker - processNextを繰り返し呼び出す

#### Step 3: sync処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | servicecidrs_controller.go | `pkg/controller/servicecidrs/servicecidrs_controller.go` | sync関数（285-354行目）が中核ロジック |

**主要処理フロー**:
- **303-333行目**: 削除処理 - canDeleteCIDR判定、猶予期間、Finalizer除去
- **336-353行目**: 作成・更新処理 - Finalizer追加、Ready条件設定
- **357-416行目**: canDeleteCIDR - 親CIDR確認、孤立IP確認

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

```
NewController (70行目)
    │
    ├─ addServiceCIDR (157行目) → queue.Add
    ├─ updateServiceCIDR (168行目) → queue.Add
    ├─ deleteServiceCIDR (176行目) → queue.Add
    ├─ addIPAddress (184行目) → containingServiceCIDRs → queue.Add
    └─ deleteIPAddress (196行目) → containingServiceCIDRs → queue.Add

Run (128行目)
    └─ worker (256行目)
        └─ processNext (261行目)
            └─ sync (285行目)
                ├─ canDeleteCIDR (357行目)
                │   ├─ servicecidr.ContainsPrefix
                │   └─ servicecidr.ContainsAddress
                ├─ removeServiceCIDRFinalizerIfNeeded (443行目)
                ├─ addServiceCIDRFinalizerIfNeeded (418行目)
                └─ updateConditionIfNeeded (472行目)
```

### データフロー図

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

ServiceCIDR変更イベント ──▶ addServiceCIDR/          ──▶ ServiceCIDR Status更新
                            updateServiceCIDR/              (Ready条件)
                            deleteServiceCIDR
                                  │
                                  ▼
                            workqueue (string key)
                                  │
                                  ▼
IPAddress変更イベント  ──▶  sync()                   ──▶ ServiceCIDR Finalizer
                            ├─ canDeleteCIDR()              (追加/削除)
                            ├─ addFinalizer()
                            └─ updateCondition()     ──▶ Kubernetes Events
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| servicecidrs_controller.go | `pkg/controller/servicecidrs/servicecidrs_controller.go` | ソース | コントローラー本体 |
| servicecidrs_controller_test.go | `pkg/controller/servicecidrs/servicecidrs_controller_test.go` | テスト | ユニットテスト |
| servicecidr | `pkg/api/servicecidr/` | ソース | CIDR操作ユーティリティ（OverlapsPrefix, ContainsAddress等） |
| ipallocator | `pkg/registry/core/service/ipallocator/` | ソース | IP割り当て管理（ControllerName定数） |
