# 機能設計書 28-StorageVersionGCコントローラー

## 概要

本ドキュメントは、KubernetesのStorageVersionGCコントローラーの機能設計を記述する。不要なStorageVersionリソースのガベージコレクションを行う。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターでは、各API Serverインスタンスがリソースの保存形式（StorageVersion）を記録する。API Serverインスタンスがスケールダウンや障害で消失した場合、そのインスタンスに紐づくStorageVersionエントリが残存する。これらの陳腐化したエントリを自動的にクリーンアップし、正確なStorageVersion情報を維持する。

**機能の利用シーン**：kube-apiserver Podがスケールダウンされた場合、削除されたインスタンスのIdentity Leaseが失効し、対応するStorageVersionエントリが自動削除される。また、StorageVersionに存在しないAPI ServerのIDが含まれる場合にも自動クリーンアップされる。

**主要な処理内容**：
1. kube-apiserver Identity Leaseの削除イベントを監視する
2. StorageVersionの追加・更新イベントを監視する
3. Lease削除時: 全StorageVersionから該当API ServerのエントリをクリーンアップするLeaseワーカー
4. StorageVersion変更時: 存在しないAPI ServerのエントリをクリーンアップするStorageVersionワーカー
5. 全エントリが削除されたStorageVersionオブジェクトは完全削除する

**関連システム・外部連携**：API Server（Lease/StorageVersionの取得・更新・削除）

**権限による制御**：StorageVersionGCコントローラーはkube-system Namespaceのkube-apiserver Identity Leaseを監視する権限と、StorageVersionリソースの読み取り・更新・削除権限を持つ。

## 関連画面

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

## 機能種別

ガベージコレクション（バックグラウンド自動処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 固定パラメータで動作 | - |

### 入力データソース

- Lease Informer: kube-system Namespaceのkube-apiserver Identity Leaseの削除イベント
- StorageVersion Informer: StorageVersionの追加・更新イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| StorageVersion.Status.StorageVersions | []ServerStorageVersion | クリーンアップ後のエントリ一覧 |
| StorageVersion削除 | DELETE API | エントリが0件になったStorageVersionの完全削除 |

### 出力先

- API Server: StorageVersionのステータス更新および削除

## 処理フロー

### 処理シーケンス

```
1. Run()で2つのワーカーを起動する
   └─ leaseWorkerとstorageVersionWorkerを各1つ
2. Lease削除イベント: onDeleteLease()でleaseQueueに投入
   └─ kube-system NSかつIdentityLeaseComponentLabel=kube-apiserverの場合のみ
3. processDeletedLease(): 全StorageVersionから該当API Serverエントリを除去
   └─ 該当APIServerIDのServerStorageVersionを除去
4. StorageVersion追加/更新: 存在しないAPI Serverエントリを検出しstorageVersionQueueに投入
   └─ enqueueStorageVersion()でLeaseキャッシュを確認
5. syncStorageVersion(): 存在しないAPI Serverのエントリを除去
   └─ 各エントリのAPIServerIDに対応するLeaseをGETで確認
6. updateOrDeleteStorageVersion(): エントリ0件なら削除、あればステータス更新
```

### フローチャート

```mermaid
flowchart TD
    A[Lease削除イベント] --> B{kube-apiserver Lease?}
    B -->|Yes| C[leaseQueueに投入]
    B -->|No| D[スキップ]
    C --> E[processDeletedLease]
    E --> F[全StorageVersionから該当ID除去]
    F --> G{エントリ残存?}
    G -->|Yes| H[StorageVersion StatusUpdate]
    G -->|No| I[StorageVersion Delete]

    J[StorageVersion追加/更新] --> K[enqueueStorageVersion]
    K --> L{無効なAPIServerID?}
    L -->|Yes| M[storageVersionQueueに投入]
    L -->|No| N[スキップ]
    M --> O[syncStorageVersion]
    O --> P[無効IDのエントリ除去]
    P --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-01 | kube-apiserver Leaseフィルタ | kube-system Namespaceかつラベル"apiserver.kubernetes.io/identity"=kube-apiserverのLeaseのみ監視 | onDeleteLease |
| BR-28-02 | エントリ除去 | 対応するIdentity Leaseが存在しないServerStorageVersionエントリを除去 | processDeletedLease/syncStorageVersion |
| BR-28-03 | 完全削除 | ServerStorageVersionsが空になったStorageVersionオブジェクトは完全削除 | updateOrDeleteStorageVersion |
| BR-28-04 | CommonEncodingVersion更新 | エントリ更新時にCommonEncodingVersionを再計算 | updateOrDeleteStorageVersion |

### 計算ロジック

- **CommonEncodingVersion**: storageversion.SetCommonEncodingVersion()で全ServerStorageVersionのEncodingVersionが一致する場合に設定

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Lease取得 | Lease（etcd） | SELECT（Get） | Identity Lease存在確認 |
| StorageVersion一覧 | StorageVersion（etcd） | SELECT（List） | 全StorageVersionの取得 |
| StorageVersionステータス更新 | StorageVersion（etcd） | UPDATE | ServerStorageVersionsの更新 |
| StorageVersion削除 | StorageVersion（etcd） | DELETE | エントリ0件のSV完全削除 |

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

#### StorageVersion（etcd経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status.storageVersions | 無効エントリ除去後のリスト | UpdateStatusサブリソース |
| UPDATE | status.commonEncodingVersion | SetCommonEncodingVersion()の結果 | UpdateStatusサブリソース |
| DELETE | - | storageVersions が空の場合 | オブジェクト完全削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | API応答 | StorageVersionが削除済み | 正常終了 |
| Lease取得失敗 | API応答 | Leaseの確認GET失敗 | エントリを無効と判定 |
| StorageVersion更新失敗 | API応答 | ステータス更新の競合 | RateLimitingキューでリトライ |

### リトライ仕様

- leaseQueue/storageVersionQueue: RateLimitingキューでリトライ
- 成功時: queue.Forget()でバックオフリセット
- Identity Leaseの再削除は低頻度のため、2つのワーカーの競合は許容

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

StorageVersionのステータス更新はUpdateStatusサブリソースAPIで行われ、ResourceVersionによる楽観的並行性制御が適用される。leaseWorkerとstorageVersionWorkerが同時に同じStorageVersionを更新する可能性があるが、API Serverが競合を検出する。

## パフォーマンス要件

- leaseWorkerとstorageVersionWorkerは各1つずつ（低頻度イベントのため）
- processDeletedLease()は全StorageVersionをリストするが、Lease削除は低頻度
- enqueueStorageVersion()はLeaseキャッシュ（Lister）を使用し、API呼び出しを最小化

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

- kube-system NamespaceのLeaseへのアクセス権限が必要
- StorageVersionの更新・削除権限が必要
- 不正なLease削除によるStorageVersion破壊を防ぐため、ラベルフィルタで対象を限定

## 備考

- StorageVersionはAPI Serverの内部管理用リソースであり、通常ユーザーが直接操作することはない
- StorageVersion Migrationと連携して、ストレージバージョンの整合性を維持する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | Controller構造体（47-57行目）。kubeclientset、leaseLister、leaseQueue（RateLimiting）、storageVersionQueue（RateLimiting）を保持 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | NewStorageVersionGC（60-92行目）。Lease InformerのDeleteハンドラ、StorageVersion InformerのAdd/Updateハンドラを登録 |
| 2-2 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | Run（95-126行目）。キャッシュ同期後、leaseWorkerとstorageVersionWorkerを各1つ起動 |

**主要処理フロー**:
1. **76-80行目**: Lease InformerにDeleteハンドラ登録
2. **82-89行目**: StorageVersion InformerにAdd/Updateハンドラ登録
3. **119-124行目**: 2ワーカーをgoroutineで起動

#### Step 3: Lease削除処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | onDeleteLease（265-286行目）。kube-system NS + IdentityLeaseComponentLabelKey確認 |
| 3-2 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | processDeletedLease（174-209行目）。全SV一覧取得、該当APIServerIDのエントリ除去、updateOrDeleteStorageVersion |

#### Step 4: StorageVersion同期処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | enqueueStorageVersion（252-263行目）。Leaseキャッシュで各エントリのAPIServerIDを確認 |
| 4-2 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | syncStorageVersion（211-239行目）。各エントリのLeaseをAPI Server GETで確認 |
| 4-3 | gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | updateOrDeleteStorageVersion（292-302行目）。エントリ0件ならDelete、あればSetCommonEncodingVersion + UpdateStatus |

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

```
Controller.Run()
    │
    ├─ runLeaseWorker()
    │      └─ processNextLease()
    │             └─ processDeletedLease()
    │                    ├─ StorageVersions.List() ── 全SV取得
    │                    ├─ 該当APIServerIDのエントリ除去
    │                    └─ updateOrDeleteStorageVersion()
    │
    └─ runStorageVersionWorker()
           └─ processNextStorageVersion()
                  └─ syncStorageVersion()
                         ├─ StorageVersions.Get() ── SV取得
                         ├─ Leases.Get() ── 各エントリのLease確認
                         └─ updateOrDeleteStorageVersion()
                                ├─ StorageVersions.Delete() (0件時)
                                └─ StorageVersions.UpdateStatus() (残存時)
```

### データフロー図

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

Lease削除イベント ──────▶ processDeletedLease()
(kube-apiserver)           │ 全SV走査、エントリ除去
                          ▼
                    updateOrDeleteStorageVersion()
                          │
                          ├─▶ API Server Delete (0件時)
                          └─▶ API Server UpdateStatus (残存時)

SV追加/更新イベント ────▶ syncStorageVersion()
                          │ Lease確認、無効エントリ除去
                          ▼
                    updateOrDeleteStorageVersion()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gc_controller.go | `pkg/controller/storageversiongc/gc_controller.go` | ソース | StorageVersionGCの全ロジック |
