# 機能設計書 16-EndpointSliceコントローラー

## 概要

本ドキュメントは、Kubernetes EndpointSliceコントローラーの機能設計を記述する。ServiceとPodの紐付けをEndpointSliceリソースとして管理する、Endpointコントローラーの後継。

### 本機能の処理概要

**業務上の目的・背景**：従来のEndpointsリソースは単一オブジェクトに全エンドポイントを格納するため、大規模クラスタでパフォーマンス問題が発生する。EndpointSliceは分割されたスライス単位でエンドポイントを管理することで、更新の粒度を細かくし、API Serverやkube-proxyの負荷を軽減する。

**機能の利用シーン**：Service作成時、Pod追加/削除/更新時、Nodeの追加/削除時のEndpointSlice自動更新。TopologyAwareHintsによるゾーン配慮型ルーティング。

**主要な処理内容**：
1. Service Informerからのイベント検出とEndpointSlice同期
2. Pod InformerからのPod変更検出とマッチするServiceの特定
3. Node Informerからのノード変更検出とトポロジーキャッシュ更新
4. EndpointSlice Informerからの変更検出と整合性確認
5. Reconcilerを使用したEndpointSliceの調整（作成/更新/削除）
6. TopologyCacheによるゾーン配慮型エンドポイント配分

**関連システム・外部連携**：API Server、kube-proxy（EndpointSliceを監視してルーティングルールを更新）、CoreDNS

**権限による制御**：EndpointSlice/Service/Pod/Nodeの読み取りおよびEndpointSliceの作成・更新・削除権限。

## 関連画面

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

## 機能種別

コントローラー（Reconciliation Loop） / データ同期

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| maxEndpointsPerSlice | int32 | Yes | 1スライスあたりの最大エンドポイント数 | > 0 |
| endpointUpdatesBatchPeriod | time.Duration | No | Pod変更のバッチ遅延 | - |
| Service.spec.selector | map[string]string | - | Podセレクタ | - |
| Service.spec.type | ServiceType | - | サービスタイプ | - |

### 入力データソース

- Kubernetes API Server: Service Informer
- Kubernetes API Server: Pod Informer
- Kubernetes API Server: Node Informer
- Kubernetes API Server: EndpointSlice Informer

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| EndpointSlice.endpoints | []Endpoint | エンドポイント情報リスト |
| EndpointSlice.ports | []EndpointPort | ポート定義リスト |
| EndpointSlice.addressType | AddressType | IPv4/IPv6 |
| EndpointSlice.labels | map[string]string | service名、managed-by等 |

### 出力先

- Kubernetes API Server: EndpointSliceリソースの作成・更新・削除

## 処理フロー

### 処理シーケンス

```
1. イベント受信
   a. Service Add/Update/Delete → serviceQueueにエンキュー
   b. Pod Add/Update/Delete → podQueueにエンキュー
   c. EndpointSlice Add/Update/Delete → serviceQueueにエンキュー（遅延付き）
   d. Node Add/Update/Delete → topologyQueueにエンキュー
2. podQueueWorker: Pod変更からServiceを特定、serviceQueueにバッチ遅延付きでエンキュー
3. serviceQueueWorker: serviceQueueからデキューしsyncServiceを実行
   a. Service/Pod/EndpointSlice取得
   b. staleSliceチェック
   c. Reconciler.Reconcileで調整
4. topologyQueueWorker: Nodeの変更に応じてTopologyCache更新
   └─ 過負荷Serviceをserviceキューに追加
```

### フローチャート

```mermaid
flowchart TD
    A[Service/Pod/Node/EndpointSlice イベント] --> B{イベント種別}
    B -->|Service| C[serviceQueue]
    B -->|Pod| D[podQueue → syncPod → serviceQueue]
    B -->|EndpointSlice| E[遅延付きserviceQueue]
    B -->|Node| F[topologyQueue]
    C --> G[syncService]
    D --> C
    E --> C
    F --> H[checkNodeTopologyDistribution]
    H --> C
    G --> I{Service存在?}
    I -->|No| J[EndpointSlice削除]
    I -->|Yes| K{ExternalName or セレクタなし?}
    K -->|Yes| L[スキップ]
    K -->|No| M[Pod取得 + EndpointSlice取得]
    M --> N{stale slice?}
    N -->|Yes| O[StaleInformerCacheエラー]
    N -->|No| P[Reconciler.Reconcile]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | スライス分割 | maxEndpointsPerSlice以上のエンドポイントを別スライスに分割 | 常時 |
| BR-02 | managed-byラベル | "endpointslice-controller.k8s.io"で管理者を識別 | 常時 |
| BR-03 | トポロジーキャッシュ | ゾーン間のNode/エンドポイント分布を追跡 | TopologyAwareHints有効時 |
| BR-04 | EndpointSlice変更遅延 | endpointSliceChangeMinSyncDelay = 1秒 | EndpointSlice変更時 |
| BR-05 | 削除マーク済みSlice除外 | DeletionTimestamp付きEndpointSliceは無視 | 常時 |
| BR-06 | ExternalName/セレクタなし除外 | Endpointコントローラーと同様の除外ルール | 常時 |

### 計算ロジック

- maxRetries = 15
- defaultSyncBackOff = 1秒
- maxSyncBackOff = 1000秒
- endpointSliceChangeMinSyncDelay = 1秒
- RateLimiter: 1秒～1000秒のexponential backoff、全体10qps/100バケット

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| EndpointSlice作成 | EndpointSlices (etcd) | INSERT | 新規スライス作成 |
| EndpointSlice更新 | EndpointSlices (etcd) | UPDATE | エンドポイント変更反映 |
| EndpointSlice削除 | EndpointSlices (etcd) | DELETE | 不要スライス削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FailedToListPods | Warning Event | Pod一覧取得失敗 | requeue |
| FailedToListEndpointSlices | Warning Event | EndpointSlice一覧取得失敗 | requeue |
| FailedToUpdateEndpointSlices | Warning Event | Reconcile失敗 | requeue |
| - | StaleInformerCache | キャッシュが古い | requeue（"stale"メトリクス） |

### リトライ仕様

- 最大15回リトライ後にドロップ
- exponential backoff: 1秒～1000秒

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

EndpointSliceの更新はReconcilerが一括調整する。endpointSliceTrackerにより、期待されるResourceVersionと実際のVersionを比較してキャッシュの古さを検出する。

## パフォーマンス要件

- maxEndpointsPerSlice: 設定可能（デフォルト100）
- endpointSliceChangeMinSyncDelay: 1秒（EndpointSlice変更のバッチ化）
- 3種類のキュー（service/pod/topology）で負荷分散
- メトリクス: EndpointSliceSyncs（success/error/stale）

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

- EndpointSliceにはバックエンドPodのIPアドレスが含まれる
- ManagedByControllerチェックにより、他のコントローラーが管理するEndpointSliceを更新しない

## 備考

- Endpointコントローラーの後継として推奨
- TopologyAwareHintsとPreferSameTrafficDistributionフィーチャーゲートに対応
- endpointSliceTrackerでキャッシュの整合性を管理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | endpointslice_controller.go | `pkg/controller/endpointslice/endpointslice_controller.go` | Controller構造体（192-268行目） |
| 1-2 | types.go | `staging/src/k8s.io/api/discovery/v1/types.go` | EndpointSlice, Endpoint, EndpointPortの定義 |

**読解のコツ**: 3つのキュー（serviceQueue, podQueue, topologyQueue）がそれぞれ異なる責務を持つ。serviceQueueが最終的な同期の起点になる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | endpointslice_controller.go | `pkg/controller/endpointslice/endpointslice_controller.go` | NewController（85-190行目） |
| 2-2 | endpointslice_controller.go | `pkg/controller/endpointslice/endpointslice_controller.go` | Run（271-310行目） |

**主要処理フロー**:
1. **85-190行目**: 4つのInformer（Service/Pod/Node/EndpointSlice）のハンドラ登録、Reconciler初期化
2. **271-310行目**: serviceQueueWorker, podQueueWorker, topologyQueueWorkerの起動
3. **368-451行目**: syncService: Reconciler.Reconcileの呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reconciler.go | `staging/src/k8s.io/endpointslice/reconciler.go` | Reconcile関数: EndpointSliceの作成/更新/削除 |

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

```
NewController (初期化)
    |
    +-- Run
        |
        +-- serviceQueueWorker -> syncService
        |       +-- serviceLister.Get
        |       +-- podLister.List
        |       +-- endpointSliceLister.List
        |       +-- endpointSliceTracker.StaleSlices
        |       +-- reconciler.Reconcile
        |
        +-- podQueueWorker -> syncPod
        |       +-- GetServicesToUpdate → serviceQueue.AddAfter
        |
        +-- topologyQueueWorker -> checkNodeTopologyDistribution
                +-- nodeLister.List
                +-- topologyCache.SetNodes
                +-- topologyCache.GetOverloadedServices → serviceQueue.Add
```

### データフロー図

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

Service Informer ----+
                     |
Pod Informer --------+--> serviceQueue --> syncService --> Reconciler.Reconcile
                     |                                         |
EndpointSlice Informer +                                       +--> EndpointSlice CRUD (API Server)
                     |
Node Informer -------+--> topologyQueue --> checkNodeTopologyDistribution
                                                |
                                                +--> TopologyCache更新 --> serviceQueue
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| endpointslice_controller.go | `pkg/controller/endpointslice/endpointslice_controller.go` | ソース | メインコントローラーロジック |
| reconciler.go | `staging/src/k8s.io/endpointslice/reconciler.go` | ソース | EndpointSliceの調整ロジック |
| topologycache/ | `staging/src/k8s.io/endpointslice/topologycache/` | ソース | トポロジーキャッシュ |
| util/ | `staging/src/k8s.io/endpointslice/util/` | ソース | ユーティリティ関数 |
| metrics/ | `staging/src/k8s.io/endpointslice/metrics/` | ソース | Prometheusメトリクス |
