# 機能設計書 65-ConfigMap/Secret配信

## 概要

本ドキュメントは、KubeletにおけるConfigMapおよびSecretリソースのキャッシュ管理と配信機能の設計を記述する。

### 本機能の処理概要

KubeletのConfigMap/Secret配信機能は、Podが参照するConfigMapおよびSecretリソースをAPI Serverから取得し、ローカルキャッシュで管理して、Volume MountやEnvironment変数として各コンテナに配信するコンポーネントである。

**業務上の目的・背景**：Kubernetesにおいて、ConfigMapは設定情報、Secretは機密情報を外部化するためのリソースである。Kubeletは各ノードで実行されるPodが必要とするConfigMapとSecretを効率的に取得・キャッシュし、各コンテナに確実に配信する必要がある。

**機能の利用シーン**：(1) Podのボリュームとして ConfigMap/Secretをマウントする場合、(2) 環境変数としてConfigMap/Secretの値を注入する場合、(3) imagePullSecretsとしてSecretを使用する場合。

**主要な処理内容**：
1. Pod登録時に参照されるConfigMap/Secret名を抽出する
2. 3つの実装方式（Simple/Caching/Watching）でAPI Serverからリソースを取得する
3. キャッシュの鮮度管理（TTLベースまたはWatchベース）を行う
4. Immutableフラグが設定されたリソースはWatch解除してメモリ効率を向上させる

**関連システム・外部連携**：API Server（ConfigMap/Secret API）、Volume Manager（Volume Mountの管理元）。

**権限による制御**：KubeletはNodeAuthorizationにより、自ノード上のPodが参照するConfigMap/Secretのみ取得可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLI画面との直接的な関連はなく、Kubelet内部コンポーネントとして動作する |

## 機能種別

データキャッシュ・配信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| namespace | string | Yes | ConfigMap/Secretの名前空間 | 有効なNamespace名 |
| name | string | Yes | ConfigMap/Secretの名前 | 有効なリソース名 |
| pod | *v1.Pod | Yes (Register/Unregister) | 登録/解除するPod | 有効なPodオブジェクト |
| resyncInterval | time.Duration | Yes (Watching) | Watch再同期間隔 | 正の値 |

### 入力データソース

- API Server: ConfigMap/Secret APIからのリソース取得
- Pod Spec: VisitPodConfigmapNames/VisitPodSecretNamesによる参照名の抽出

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| *v1.ConfigMap | ConfigMap | 取得したConfigMapオブジェクト |
| *v1.Secret | Secret | 取得したSecretオブジェクト |

### 出力先

- Kubelet内部キャッシュ: Volume ManagerやenvVarリゾルバに提供
- コンテナ: ボリュームマウントまたは環境変数として注入

## 処理フロー

### 処理シーケンス

```
1. Pod登録 (RegisterPod)
   └─ PodSpecからConfigMap/Secret名を抽出 → キャッシュに登録
2. リソース取得 (GetConfigMap/GetSecret)
   └─ キャッシュから取得（キャッシュミス時はAPI Serverから取得）
3. Pod解除 (UnregisterPod)
   └─ 他のPodから参照されていないリソースをキャッシュから解除
```

### フローチャート

```mermaid
flowchart TD
    A[Pod登録] --> B[PodSpecから参照名を抽出]
    B --> C[manager.RegisterPod]
    D[GetConfigMap/GetSecret] --> E{キャッシュにあるか?}
    E -->|Yes, 有効| F[キャッシュから返却]
    E -->|No or 期限切れ| G[API Serverから取得]
    G --> H[キャッシュ更新]
    H --> F
    I[Pod解除] --> J[manager.UnregisterPod]
    J --> K{他のPodが参照?}
    K -->|Yes| L[キャッシュ維持]
    K -->|No| M[キャッシュ/Watch解除]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-65-01 | 3方式サポート | Simple（直接API呼び出し）、Caching（TTLベース）、Watching（Watchベース）の3方式 | Kubelet設定による |
| BR-65-02 | デフォルトTTL | CachingモードのデフォルトTTLは1分 | Cachingモード |
| BR-65-03 | Immutableリソース最適化 | Immutableフラグが設定されたConfigMap/SecretはWatch解除される | Watchingモード |
| BR-65-04 | 参照カウント | 複数Podから参照されるリソースは、全てのPodが解除されるまでキャッシュを維持 | 常時 |
| BR-65-05 | 非ブロッキング登録 | RegisterPod/UnregisterPodはネットワーク操作をブロックしてはならない | 常時 |

### 計算ロジック

- ConfigMap参照名の抽出: `podutil.VisitPodConfigmapNames(pod, callback)`
- Secret参照名の抽出: `podutil.VisitPodSecretNames(pod, callback)`
- デフォルトTTL: `defaultTTL = time.Minute`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リソース取得 | etcd (configmaps/secrets) | GET | 名前空間+名前で個別取得 |
| リソース一覧 | etcd (configmaps/secrets) | LIST | WatchingモードでのList操作 |
| リソース監視 | etcd (configmaps/secrets) | WATCH | WatchingモードでのWatch操作 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NotFound | API応答 | ConfigMap/Secretが存在しない | エラー返却（Pod起動失敗） |
| Forbidden | API応答 | NodeAuthorizationによるアクセス拒否 | エラー返却 |
| 型アサーションエラー | 内部エラー | 予期しないオブジェクト型 | エラーメッセージ返却 |

### リトライ仕様

- Cachingモード: TTL期限切れ時に再取得
- Watchingモード: Watch切断時にListerWatcherが自動再接続

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

該当なし（読み取り専用キャッシュ操作）。

## パフォーマンス要件

- Cachingモード: TTLベースのキャッシュによりAPI呼び出しを削減
- Watchingモード: Watchによるリアルタイム更新で鮮度を維持しつつ、Listの頻度を削減
- Immutableリソース: Watchを解除することでAPI Server負荷とメモリ使用量を削減

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

- SecretはPodSpecで参照されたもののみ取得可能（NodeAuthorizationによる制限）
- ConfigMap/Secretのキャッシュはプロセスメモリ上に保持され、ディスクには保存されない
- Secretの値はボリュームマウント時にtmpfs上に配置される（Kubelet外の仕組み）

## 備考

- ConfigMapManagerとSecretManagerは同一のmanager.Managerインフラストラクチャ（`pkg/kubelet/util/manager/`）を共有する
- WatchingモードではWatchListSemanticsが利用される

---

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

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

### 推奨読解順序

#### Step 1: インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | Managerインターフェース（39-52行目）: GetConfigMap/RegisterPod/UnregisterPod |
| 1-2 | secret_manager.go | `pkg/kubelet/secret/secret_manager.go` | Managerインターフェース（40-53行目）: GetSecret/RegisterPod/UnregisterPod |

**読解のコツ**: ConfigMapManagerとSecretManagerはほぼ同一のアーキテクチャで、内部のmanager.Managerに処理を委譲する。一方を理解すればもう一方も容易に把握できる。

#### Step 2: Simple実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | simpleConfigMapManager（56-73行目）: API直接呼び出し |
| 2-2 | secret_manager.go | `pkg/kubelet/secret/secret_manager.go` | simpleSecretManager（57-74行目）: API直接呼び出し |

#### Step 3: Caching実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | NewCachingConfigMapManager（123-131行目）: TTLベースキャッシュ |
| 3-2 | secret_manager.go | `pkg/kubelet/secret/secret_manager.go` | NewCachingSecretManager（124-132行目）: TTLベースキャッシュ |

#### Step 4: Watching実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | NewWatchingConfigMapManager（139-162行目）: Watchベースキャッシュ |
| 4-2 | configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | isImmutable関数（149-153行目）: Immutable最適化 |

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

```
ConfigMap/Secret Manager
    │
    ├─ SimpleManager
    │      └─ kubeClient.CoreV1().ConfigMaps/Secrets().Get()
    │
    ├─ CachingManager
    │      └─ manager.CacheBasedManager
    │             └─ ObjectStore (TTLベースキャッシュ)
    │                    └─ kubeClient.CoreV1().ConfigMaps/Secrets().Get()
    │
    └─ WatchingManager
           └─ manager.WatchBasedManager
                  ├─ ListWatch (初回取得)
                  ├─ Watch (リアルタイム更新)
                  └─ isImmutable() → Watch解除
```

### データフロー図

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

Pod Spec ──────────────▶ RegisterPod() ──────────▶ 参照名をキャッシュに登録
                              │
GetConfigMap/GetSecret ───▶  キャッシュ検索 ─────────▶ キャッシュHit → 返却
                              │
                              └─ キャッシュMiss ─────▶ API Server GET → キャッシュ更新 → 返却

API Server Watch ──────▶ Watch更新 ─────────────▶ キャッシュ更新（Watchingモード）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| configmap_manager.go | `pkg/kubelet/configmap/configmap_manager.go` | ソース | ConfigMap管理 |
| secret_manager.go | `pkg/kubelet/secret/secret_manager.go` | ソース | Secret管理 |
| manager.go | `pkg/kubelet/util/manager/manager.go` | ソース | 共通Manager基盤 |
| cache_based_manager.go | `pkg/kubelet/util/manager/cache_based_manager.go` | ソース | TTLベースキャッシュ |
| watch_based_manager.go | `pkg/kubelet/util/manager/watch_based_manager.go` | ソース | Watchベースキャッシュ |
