# 機能設計書 17-Node IPAMコントローラー

## 概要

本ドキュメントは、Kubernetes Node IPAMコントローラーの機能設計を記述する。各ノードにPod CIDR（サブネット）を割り当て、クラスタ全体のIPアドレス管理を行う。

### 本機能の処理概要

**業務上の目的・背景**：KubernetesではPodにIPアドレスを割り当てる必要がある。Node IPAMコントローラーはクラスタCIDRから各ノードにPod CIDRを自動割り当てし、ノード間のIPアドレス重複を防止する。これにより、CNIプラグインがノードに配置されるPodに正しいIPアドレスを割り当てることができる。

**機能の利用シーン**：ノードのクラスタ参加時、クラスタ初期化時、デュアルスタック（IPv4/IPv6）環境でのアドレス管理。

**主要な処理内容**：
1. クラスタCIDRの管理とノードへのサブネット割り当て
2. 複数のCIDRアロケータタイプのサポート
3. デュアルスタック対応（IPv4/IPv6の両方のCIDR割り当て）
4. Service CIDRとの重複回避
5. クラウドプロバイダ連携によるCIDR割り当て

**関連システム・外部連携**：API Server（Nodeリソースのspec.podCIDRs更新）、クラウドプロバイダ（CloudAllocatorType使用時）、CNIプラグイン（割り当てられたCIDRに基づきPod IPを管理）

**権限による制御**：Node IPAMコントローラーはNodeリソースのspec.podCIDRsフィールドを更新する権限を持つ。

## 関連画面

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

## 機能種別

コントローラー / IPアドレス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| clusterCIDRs | []*net.IPNet | Yes* | クラスタ全体のCIDR | CloudAllocatorType以外で必須 |
| serviceCIDR | *net.IPNet | No | ServiceのCIDR（重複回避用） | - |
| secondaryServiceCIDR | *net.IPNet | No | セカンダリServiceのCIDR | - |
| nodeCIDRMaskSizes | []int | Yes* | ノードに割り当てるサブネットマスクサイズ | CloudAllocatorType以外で必須 |
| allocatorType | CIDRAllocatorType | Yes | アロケータタイプ | RangeAllocator/CloudAllocator/IPAMFromCluster/IPAMFromCloud |

### 入力データソース

- Kubernetes API Server: Node Informer
- クラウドプロバイダAPI（CloudAllocatorType使用時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Node.spec.podCIDR | string | ノードに割り当てられたプライマリPod CIDR |
| Node.spec.podCIDRs | []string | ノードに割り当てられた全Pod CIDR（デュアルスタック対応） |

### 出力先

- Kubernetes API Server: Nodeリソースの更新

## 処理フロー

### 処理シーケンス

```
1. コントローラー初期化
   a. allocatorTypeに応じたCIDRアロケータの作成
   b. クラスタCIDRのバリデーション（maskSize <= nodeCIDRMaskSize確認）
   c. 既存ノードのCIDR割り当て状態の復元
2. Run開始
   a. キャッシュ同期待ち
   b. CIDRアロケータまたはlegacyIPAMの実行
3. 新規ノード検出
   a. ノードのspec.podCIDRsが未設定の場合
   b. CIDRアロケータがサブネットを割り当て
   c. Nodeリソースを更新（spec.podCIDR、spec.podCIDRs）
4. ノード削除検出
   a. 割り当て済みCIDRの解放
```

### フローチャート

```mermaid
flowchart TD
    A[コントローラー初期化] --> B{allocatorType}
    B -->|IPAMFromCluster/Cloud| C[legacyIPAM作成]
    B -->|RangeAllocator/Cloud| D[CIDRAllocator作成]
    C --> E[Run]
    D --> E
    E --> F[キャッシュ同期]
    F --> G{legacyIPAM?}
    G -->|Yes| H[legacyIPAM.Run]
    G -->|No| I[cidrAllocator.Run]
    I --> J[新規ノード検出]
    J --> K{podCIDRs未設定?}
    K -->|Yes| L[CIDR割り当て]
    K -->|No| M[既存CIDR記録]
    L --> N[Node更新: spec.podCIDRs]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | CIDRバリデーション | clusterCIDRのmaskSizeがnodeCIDRMaskSize以下であること | 非CloudAllocatorType |
| BR-02 | CIDR重複回避 | ServiceCIDRと重複しないCIDRを割り当て | serviceCIDR設定時 |
| BR-03 | デュアルスタック | IPv4とIPv6の両方のCIDRを割り当て可能 | 複数clusterCIDRs指定時 |
| BR-04 | CIDR復元 | 既存ノードの割り当て済みCIDRをビットマップに記録 | コントローラー起動時 |

### 計算ロジック

- ノードあたりのCIDR: clusterCIDRからnodeCIDRMaskSizeのサブネットを切り出し
- 最大ノード数: 2^(nodeCIDRMaskSize - clusterCIDRMaskSize)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Node更新 | Nodes (etcd) | UPDATE | spec.podCIDR/podCIDRsの設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CIDR枯渇 | 全サブネットが割り当て済み | エラーログ出力、リトライ |
| - | 初期化エラー | 無効なクラスタCIDR設定 | fatal error（起動失敗） |
| - | API更新失敗 | Node更新の通信エラー | リトライ |

### リトライ仕様

- CIDRアロケータ固有のリトライ仕様に依存

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

CIDRの割り当てはインメモリのビットマップとAPI Server上のNodeリソースの両方で管理される。ビットマップ更新後にAPI Server更新が失敗した場合は、次回sync時に再試行される。

## パフォーマンス要件

- ノード追加時のCIDR割り当ては即座に行われる
- ビットマップによるO(1)のCIDR割り当て

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

- Pod CIDRの変更は権限のあるコントローラーのみが行える
- CIDRの重複は深刻なネットワーク障害を引き起こすため、割り当ての一意性が重要

## 備考

- CIDRAllocatorType: "RangeAllocator"（デフォルト）、"CloudAllocator"（クラウド連携）、"IPAMFromCluster"、"IPAMFromCloud"（レガシー）
- RunWithMetrics: コントローラーマネージャのメトリクスに開始/停止を報告

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node_ipam_controller.go | `pkg/controller/nodeipam/node_ipam_controller.go` | Controller構造体（44-59行目） |

**読解のコツ**: allocatorTypeフィールドにより、使用するCIDRアロケータが決定される。legacyIPAMとcidrAllocatorの2つのパスがある点に注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node_ipam_controller.go | `pkg/controller/nodeipam/node_ipam_controller.go` | NewNodeIpamController（66-132行目）: バリデーションとアロケータ初期化 |
| 2-2 | node_ipam_controller.go | `pkg/controller/nodeipam/node_ipam_controller.go` | Run（135-154行目）: キャッシュ同期後にアロケータ起動 |

**主要処理フロー**:
1. **66-93行目**: パラメータバリデーション（クラスタCIDR、マスクサイズ）
2. **95-103行目**: Controller構造体初期化
3. **106-126行目**: allocatorTypeに応じてlegacyIPAMまたはcidrAllocatorを作成
4. **135-154行目**: キャッシュ同期後、legacyIPAM.RunまたはcidrAllocator.Runを実行

#### Step 3: CIDRアロケータを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ipam/ | `pkg/controller/nodeipam/ipam/` | CIDRAllocatorインターフェースと各実装 |

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

```
NewNodeIpamController (初期化)
    |
    +-- パラメータバリデーション
    +-- ipam.New (CIDRAllocator作成) or createLegacyIPAM
    |
    +-- Run
        |
        +-- cache.WaitForNamedCacheSyncWithContext
        +-- cidrAllocator.Run or legacyIPAM.Run
            |
            +-- Node Informerイベント処理
            +-- CIDR割り当て → Node更新
```

### データフロー図

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

Node Informer --> CIDRAllocator --> CIDR割り当て --> Node.spec.podCIDRs更新 (API Server)
                      |
クラスタCIDR設定 ------+
ServiceCIDR設定 ------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node_ipam_controller.go | `pkg/controller/nodeipam/node_ipam_controller.go` | ソース | メインコントローラーロジック |
| ipam/ | `pkg/controller/nodeipam/ipam/` | ソース | CIDRアロケータ実装 |
| config/ | `pkg/controller/nodeipam/config/` | 設定 | コントローラー設定構造体 |
