# 機能設計書 78-Conntrack管理

## 概要

本ドキュメントは、kube-proxyにおける接続追跡テーブル（conntrack）のエントリ管理機能の設計を記述する。UDPサービスの接続追跡エントリのクリーンアップによるネットワーク安定性の確保メカニズムを定義する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetes UDPサービスでは、エンドポイントの追加・削除時にLinuxカーネルのconntrackテーブルに古いエントリが残存する場合がある。これらの古いエントリは既に存在しないエンドポイントを指しているため、パケットロスや接続障害を引き起こす。本機能は、conntrackテーブルをスキャンして不要なエントリを削除することでこの問題を解決する。

**機能の利用シーン**：kube-proxyのsyncProxyRules実行後に呼び出され、現在のService/EndpointSliceの状態と一致しないconntrackエントリを自動的にクリーンアップする。

**主要な処理内容**：
1. conntrackテーブル全エントリのリスト取得（netlink経由）
2. 現在のService/Endpointマッピングとconntrackエントリの突合
3. 不要なUDP conntrackエントリの特定と一括削除
4. ClusterIP、LoadBalancerIP、ExternalIP、NodePort全てのフロントエンドに対応
5. conntrackエントリの削除結果のメトリクス記録

**関連システム・外部連携**：Linux conntrackテーブル（netlink API経由）、kube-proxyのServicePortMapおよびEndpointsMap。

**権限による制御**：conntrackテーブルの操作にroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | バックグラウンド処理のため直接の画面関連はなし |

## 機能種別

データクリーンアップ / ネットワーク管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ct | Interface | Yes | conntrackインターフェース | - |
| ipFamily | v1.IPFamily | Yes | IPv4またはIPv6 | - |
| svcPortMap | proxy.ServicePortMap | Yes | 現在のServiceポートマップ | - |
| endpointsMap | proxy.EndpointsMap | Yes | 現在のEndpointsマップ | - |

### 入力データソース

- Linux conntrackテーブル（netlink経由）
- kube-proxyのServicePortMapおよびEndpointsMap

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| entriesDeleted | int | 削除されたconntrackエントリ数 |
| メトリクス | Prometheus | ReconcileConntrackFlowsLatency, ReconcileConntrackFlowsDeletedEntriesTotal |

### 出力先

Linux conntrackテーブル（エントリ削除）、Prometheusメトリクス。

## 処理フロー

### 処理シーケンス

```
1. conntrackテーブル全エントリの取得
   └─ ct.ListEntries(ipFamily)
2. ServicePortMapからUDPサービスの抽出
   ├─ ClusterIP:Port → エンドポイントセットのマッピング
   ├─ LoadBalancerIP:Port → エンドポイントセットのマッピング
   ├─ ExternalIP:Port → エンドポイントセットのマッピング
   └─ NodePort → エンドポイントセットのマッピング
3. conntrackエントリの突合
   ├─ UDPプロトコルのエントリのみ対象
   ├─ 元の宛先IP:Port（Forward.Dst）をサービスフロントエンドと照合
   ├─ 応答元IP:Port（Reverse.Src）をサービングエンドポイントと照合
   └─ サービングエンドポイントに存在しないエントリを削除対象に追加
4. 不要エントリの一括削除
   └─ ct.DeleteEntries(ipFamily, flows)
5. メトリクス記録
   ├─ ReconcileConntrackFlowsLatency
   └─ ReconcileConntrackFlowsDeletedEntriesTotal
```

### フローチャート

```mermaid
flowchart TD
    A[CleanStaleEntries] --> B[conntrackエントリ全取得]
    B --> C[UDPサービスのエンドポイントマッピング構築]
    C --> D[conntrackエントリ走査]
    D --> E{UDPプロトコル?}
    E -->|No| D
    E -->|Yes| F{ServiceIP:Port一致?}
    F -->|No| G{NodePort一致?}
    F -->|Yes| H{ReplyがServingEndpoint?}
    G -->|No| D
    G -->|Yes| H
    H -->|Yes| D
    H -->|No| I[削除対象に追加]
    I --> D
    D -->|完了| J[一括削除実行]
    J --> K[メトリクス記録]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | UDPのみ対象 | conntrackクリーンアップはUDPプロトコルのエントリのみ対象 | 常時 |
| BR-78-02 | ServingEndpoint判定 | endpoint.IsServing()がtrueのエンドポイントのみサービング対象 | 全エンドポイント |
| BR-78-03 | エンドポイントなしスキップ | エンドポイントが0のServiceはクリーンアップ対象外 | Service毎 |
| BR-78-04 | トラフィックポリシー無視 | クリーンアップはトラフィックポリシー・トポロジー・終了状態を考慮しない | 全Service |
| BR-78-05 | EINTR再試行 | EINTRエラー発生時は部分結果で処理を継続 | netlink操作 |
| BR-78-06 | フロントエンド全対応 | ClusterIP、LoadBalancerIP、ExternalIP、NodePort全てに対応 | 全Serviceタイプ |

### 計算ロジック

conntrackエントリ突合：
- Forward.DstIP:DstPort がServiceフロントエンドに一致
- AND Reverse.SrcIP:SrcPort がサービングエンドポイントに不一致
- → 削除対象

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | conntrackテーブル | SELECT | 全エントリの読み取り |
| - | conntrackテーブル | DELETE | 不要エントリの削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EINTR | システムコール中断 | netlink操作中のシグナル | 部分結果で処理継続 |
| - | リスト取得失敗 | conntrackテーブルアクセスエラー | ログ出力、処理中断 |
| - | 削除失敗 | conntrackエントリ削除エラー | エラーログ出力 |

### リトライ仕様

netlink操作はutil.MaxAttemptsEINTRによるEINTR時の自動再試行あり。CleanStaleEntries自体はsyncProxyRulesの度に呼び出される。

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

conntrackエントリの削除はフィルターベースの一括削除。アトミック性は保証されないが、部分削除も有効。

## パフォーマンス要件

- conntrackテーブル全走査のため、テーブルサイズに比例する処理時間
- ReconcileConntrackFlowsLatencyメトリクスで処理時間を監視

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

- conntrackテーブル操作にroot権限が必要
- 誤ったエントリ削除は一時的な接続断を引き起こす可能性がある

## 備考

- TCPサービスはカーネルが自動的にconntrackエントリを管理するため、本クリーンアップの対象外
- flowKeyは9つのフィールド（Protocol, Forward Src/Dst IP:Port, Reverse Src/Dst IP:Port）の組み合わせで一意性を保証
- conntrack sysctlsの管理も本パッケージに含まれる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | conntrack.go | `pkg/proxy/conntrack/conntrack.go` | Interfaceインターフェース（32-35行目） |
| 1-2 | filter.go | `pkg/proxy/conntrack/filter.go` | flowFilter構造体とflowKey関数（30-58行目） |

**読解のコツ**: conntrack.Interfaceは2つのメソッド（ListEntries, DeleteEntries）のみを持つシンプルなインターフェース。netlinkライブラリを通じてカーネルのconntrackテーブルを操作する。

#### Step 2: エントリ操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | conntrack.go | `pkg/proxy/conntrack/conntrack.go` | conntracker.ListEntries（59-65行目） |
| 2-2 | conntrack.go | `pkg/proxy/conntrack/conntrack.go` | conntracker.DeleteEntries（69-88行目） |

**主要処理フロー**:
- **59-65行目**: ListEntries - retry.OnErrorでEINTR対応しながら全エントリ取得
- **69-88行目**: DeleteEntries - flowFilterを作成しConntrackDeleteFiltersで一括削除

#### Step 3: クリーンアップロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cleanup.go | `pkg/proxy/conntrack/cleanup.go` | CleanStaleEntries関数（45-157行目） |

**主要処理フロー**:
- **51行目**: conntrackエントリ全取得
- **63-113行目**: serviceIPEndpoints/serviceNodePortEndpointsマッピング構築
- **116-147行目**: エントリ走査と不要エントリ特定
- **150行目**: 一括削除実行
- **155-156行目**: メトリクス記録

#### Step 4: フィルター実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | filter.go | `pkg/proxy/conntrack/filter.go` | MatchConntrackFlow（61-68行目） |

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

```
Proxier.syncProxyRules
    |
    +-- conntrack.CleanStaleEntries(ct, ipFamily, svcPortMap, endpointsMap)
            |
            +-- ct.ListEntries(ipFamily)
            |       +-- handler.ConntrackTableList
            |       +-- retry.OnError (EINTR retry)
            |
            +-- [serviceIPEndpoints/serviceNodePortEndpointsマッピング構築]
            |
            +-- [conntrackエントリ走査・不要エントリ特定]
            |
            +-- ct.DeleteEntries(ipFamily, flows)
                    +-- newFlowFilter(flows)
                    +-- handler.ConntrackDeleteFilters
                    +-- retry.OnError (EINTR retry)
```

### データフロー図

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

conntrackテーブル --List--> CleanStaleEntries             conntrackテーブル（削除）
                              |
ServicePortMap ------> サービスフロントエンド抽出 ---+
                              |                      |
EndpointsMap --------> エンドポイントセット構築 ----+--> 不要エントリ特定
                                                          |
                                                    +---> DeleteEntries
                                                          |
                                                    +---> Prometheusメトリクス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| conntrack.go | `pkg/proxy/conntrack/conntrack.go` | ソース | conntrackインターフェースとnetlink操作 |
| cleanup.go | `pkg/proxy/conntrack/cleanup.go` | ソース | conntrackクリーンアップのメインロジック |
| filter.go | `pkg/proxy/conntrack/filter.go` | ソース | conntrackフローフィルター |
| fake.go | `pkg/proxy/conntrack/fake.go` | ソース | テスト用フェイク実装 |
| sysctls.go | `pkg/proxy/conntrack/sysctls.go` | ソース | conntrack関連のsysctl管理 |
| doc.go | `pkg/proxy/conntrack/doc.go` | ソース | パッケージドキュメント |
