# 通知設計書 64-SandboxChanged

## 概要

本ドキュメントは、Kubernetesにおいて、Podサンドボックスが変更されたためにPodが再作成される際に発行される「SandboxChanged」イベントの設計を記述する。

### 本通知の処理概要

kubeletのランタイムマネージャがPodの同期処理（SyncPod）を実行する際、既存のサンドボックスの状態を検査し、変更が必要と判断された場合にこの通知を発行する。サンドボックス変更後、既存のPodは強制終了され、新しいサンドボックスが作成される。

**業務上の目的・背景**：Podサンドボックスはコンテナの実行環境（ネットワーク名前空間、IPアドレス等）を提供する基盤である。サンドボックスの状態がPodの仕様と不整合になった場合（ネットワーク名前空間の変更、Ready状態でないサンドボックス、IPアドレスの喪失等）、Podは安全に再作成される必要がある。この通知はその再作成をユーザーに伝え、一時的なPod停止の理由を明確にする。

**通知の送信タイミング**：kubeletのSyncPodメソッド内で、computePodActionsがサンドボックスの変更を検知し、既存のサンドボックスID（SandboxID）が存在する場合に発行される。新規Pod（SandboxIDが空）の場合は発行されない。

**通知の受信者**：Podオブジェクトに対するKubernetes Eventとして記録され、kubectl describe pod等で確認可能。アプリケーション開発者およびクラスタ管理者が対象。

**通知内容の概要**：「Pod sandbox changed, it will be killed and re-created.」という固定メッセージがPodオブジェクトに対するNormalイベントとして記録される。

**期待されるアクション**：通常、ユーザーの対応は不要。サンドボックスの変更は自動的に処理される。頻繁に発生する場合は、ノードのネットワーク設定やコンテナランタイムの状態を確認する必要がある。

## 通知種別

Kubernetes Event（EventType: Normal）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（kubelet SyncPod内で発行） |
| 優先度 | 中（Pod再作成を伴う） |
| リトライ | なし |

### 送信先決定ロジック

Podオブジェクトへの参照（ref.GetReference）を取得し、そのPodに対してEventfを発行する。

## 通知テンプレート

### メール通知の場合

本通知はKubernetes Eventとして発行されるため、メール送信は行わない。

### 本文テンプレート

```
Pod sandbox changed, it will be killed and re-created.
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定メッセージのため変数なし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| kubelet同期 | SyncPod実行 | サンドボックス変更検知かつ既存SandboxIDあり | PodSandboxChanged関数がtrue返却 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| SandboxIDが空 | 新規Podの場合はログ出力のみ |
| サンドボックス変更なし | PodSandboxChangedがfalseを返す場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[kubelet SyncPod] --> B[computePodActions]
    B --> C[PodSandboxChanged]
    C --> D{サンドボックス変更必要?}
    D -->|No| E[通常のコンテナ同期処理]
    D -->|Yes| F{既存SandboxIDあり?}
    F -->|No| G[ログ出力のみ - 新規Pod]
    F -->|Yes| H[SandboxChanged イベント発行]
    H --> I[既存Podの強制終了]
    I --> J[新サンドボックス作成]
    J --> K[コンテナ再作成]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Pod | Podの仕様確認 | SyncPodの引数 |
| PodStatus | サンドボックス状態の確認 | SandboxStatuses |

### テーブル別参照項目詳細

#### PodStatus (kubecontainer.PodStatus)

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| SandboxStatuses | サンドボックスの状態一覧 | PodSandboxChanged判定に使用 |
| SandboxStatuses[0].State | 最新サンドボックスのReady状態 | SANDBOX_READY判定 |
| SandboxStatuses[0].Linux.Namespaces.Options.Network | ネットワーク名前空間設定 | Pod仕様との比較 |
| SandboxStatuses[0].Network.Ip | サンドボックスのIPアドレス | 空文字列チェック |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Event | INSERT | Kubernetes Eventオブジェクトの作成 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | SandboxChanged | イベント理由 |
| INSERT | message | Pod sandbox changed, it will be killed and re-created. | 固定メッセージ |
| INSERT | type | Normal | イベントタイプ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Pod参照取得失敗 | ref.GetReferenceがエラーを返す | エラーログ出力、イベント発行はスキップ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | kubeletのPod同期ループにより自動的に再試行 |
| リトライ間隔 | kubeletの同期間隔に依存 |
| リトライ対象エラー | なし（イベント発行自体のエラーは無視） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Eventのデフォルトレート制限に従う |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

固定メッセージであり、機密情報を含まない。

## 備考

- PodSandboxChangedの判定条件：サンドボックスが存在しない、Ready状態のサンドボックスが複数存在、最新サンドボックスがReady状態でない、ネットワーク名前空間が変更された、サンドボックスにIPアドレスがない（HostNetworkでない場合）
- サンドボックス変更時は全コンテナ（init含む）が再作成される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | SandboxChanged定数の定義（行80） |

**読解のコツ**: kubelet/events/event.goにはkubelet固有のイベント定数が集約されている。

#### Step 2: サンドボックス変更判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | util.go | `pkg/kubelet/kuberuntime/util/util.go` | PodSandboxChanged関数（行30-69） |

**主要処理フロー**:
1. **行33-35**: サンドボックスが存在しない場合 -> 変更あり
2. **行38-43**: Ready状態のサンドボックスをカウント
3. **行47-49**: 複数のReadyサンドボックスがある場合 -> 変更あり
4. **行51-53**: 最新サンドボックスがReady状態でない場合 -> 変更あり
5. **行57-59**: ネットワーク名前空間が変更された場合 -> 変更あり
6. **行63-65**: サンドボックスにIPアドレスがない場合 -> 変更あり

#### Step 3: SyncPodでのイベント発行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kuberuntime_manager.go | `pkg/kubelet/kuberuntime/kuberuntime_manager.go` | SyncPodメソッド（行1394付近） |

**主要処理フロー**:
- **行1397**: computePodActionsでサンドボックス変更を検出
- **行1399-1409**: CreateSandboxがtrueの場合のイベント発行
- **行1404-1405**: SandboxIDが存在する場合にSandboxChangedイベント発行

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

```
kubeGenericRuntimeManager.SyncPod
    |
    +-- computePodActions
    |      |
    |      +-- runtimeutil.PodSandboxChanged (util/util.go)
    |             (サンドボックス変更判定)
    |
    +-- ref.GetReference (Pod参照取得)
    |
    +-- recorder.Eventf (SandboxChanged イベント)
    |
    +-- killPodWithSyncResult (既存Pod強制終了)
    |
    +-- createPodSandbox (新サンドボックス作成)
```

### データフロー図

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

Pod (仕様)         ───> computePodActions              ───> Kubernetes Event
PodStatus          ───> PodSandboxChanged判定          (SandboxChanged)
SandboxStatuses    ───> SyncPod                        + Pod再作成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| kuberuntime_manager.go | `pkg/kubelet/kuberuntime/kuberuntime_manager.go` | ソース | SyncPodメソッド、イベント発行 |
| util.go | `pkg/kubelet/kuberuntime/util/util.go` | ソース | PodSandboxChanged関数 |
| generate.go | `pkg/kubelet/status/generate.go` | ソース | Podステータス生成 |
