# 通知設計書 1-Created

## 概要

本ドキュメントは、Kubernetesのkubeletがコンテナを正常に作成した際に発行する「Created」イベント通知の設計を記述する。

### 本通知の処理概要

kubeletのコンテナランタイムマネージャがCRI（Container Runtime Interface）を通じてコンテナの作成に成功した後、Kubernetes Event APIを用いて「Created」イベントを記録する通知である。

**業務上の目的・背景**：Kubernetesクラスタにおいて、Podのライフサイクル管理は運用上極めて重要である。コンテナの作成成功を明示的にイベントとして記録することで、オペレータや監視システムがPodの起動状況をリアルタイムに把握できる。特に、デプロイメントのロールアウトや障害調査時に、コンテナが正しく作成されたかどうかを確認する手段として不可欠である。

**通知の送信タイミング**：kubeletがCRIのCreateContainer RPCを呼び出し、コンテナランタイムからコンテナIDが返却された直後に発行される。具体的には、`startContainer`関数内でPreStartContainerフックの実行後、StartContainer呼び出し前のタイミングである。

**通知の受信者**：Kubernetes Event APIを通じて記録されるため、kubectl eventsやモニタリングツール（Prometheus、Datadog等）、またはEvent Watcherを利用するすべてのクラスタ管理者やオートメーションシステムが受信者となる。

**通知内容の概要**：イベントにはコンテナの参照情報（Pod名、Namespace、コンテナ名）、EventType（Normal）、Reason（Created）、メッセージ（"Container created"）が含まれる。

**期待されるアクション**：通常運用時は特にアクションは不要であるが、デバッグ時にはコンテナ作成の正常完了を確認する指標として利用される。コンテナ作成イベントが記録されていない場合、作成プロセスの途中で障害が発生している可能性がある。

## 通知種別

Kubernetes Eventオブジェクト（API内部通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（Event APIへの書き込み） |
| 優先度 | 中（Normal Event） |
| リトライ | Event API書き込み失敗時はkubelet内部でリトライ |

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

kubeletが管理するPodに属するコンテナの参照（ObjectReference）を生成し、Kubernetes Event APIサーバへ送信する。送信先はkube-apiserverであり、イベントは対象Podの属するNamespaceに記録される。

## 通知テンプレート

### メール通知の場合

本通知はKubernetes Event APIオブジェクトとして発行されるため、メール通知は該当しない。外部通知が必要な場合は、Event Watcherやアラートマネージャの設定により対応する。

### 本文テンプレート

```
Container created
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| Pod名 | 対象Podの名前 | Pod.ObjectMeta.Name | Yes |
| Namespace | 対象PodのNamespace | Pod.ObjectMeta.Namespace | Yes |
| コンテナ名 | 対象コンテナの名前 | Container.Name | Yes |
| コンテナID | CRIから返却されたコンテナID | CreateContainer RPC応答 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API（CRI） | CreateContainer RPC成功 | CRIからのコンテナID返却およびPreStartContainerフック成功 | kubeletがコンテナランタイムに対してコンテナ作成を要求し、正常応答を受信した場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| コンテナ作成失敗 | CRI CreateContainer RPCがエラーを返した場合はCreatedイベントではなくFailedイベントが発行される |
| ObjectReference生成失敗 | コンテナの参照生成に失敗した場合はイベントが記録されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[startContainer呼び出し] --> B[イメージプル]
    B --> C[コンテナ設定生成]
    C --> D[PreCreateContainerフック]
    D --> E[CRI CreateContainer RPC]
    E --> F{作成成功?}
    F -->|成功| G[PreStartContainerフック]
    G --> H[recordContainerEvent: Created]
    H --> I[CRI StartContainer RPC]
    F -->|失敗| J[recordContainerEvent: Failed]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| etcd（Podオブジェクト） | Pod・コンテナのメタデータ参照 | kube-apiserver経由 |

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

#### Podオブジェクト

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| ObjectMeta.Name | イベントの対象Pod特定 | kubeletが管理するPod |
| ObjectMeta.Namespace | イベントの記録先Namespace | kubeletが管理するPod |
| Spec.Containers[].Name | コンテナ参照生成 | startContainer呼び出し時 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| etcd（Eventオブジェクト） | INSERT | Createdイベントオブジェクトの作成 |

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | Event.Reason | "Created" | イベント理由 |
| INSERT | Event.Type | "Normal" | 正常イベント |
| INSERT | Event.Message | "Container created" | イベントメッセージ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ObjectReference生成失敗 | コンテナ情報からの参照生成エラー | エラーログ出力、イベント記録スキップ |
| Event API書き込み失敗 | kube-apiserverとの通信障害 | kubelet内部のEventRecorderによるリトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | EventRecorder内部のキューイングによる自動リトライ |
| リトライ間隔 | EventRecorderのバッチ送信間隔に依存 |
| リトライ対象エラー | kube-apiserver接続エラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | EventRecorderのバースト制限に依存（デフォルト25 QPS） |
| 1日あたり上限 | 明示的な上限なし（ただし同一イベントは集約される） |

### 配信時間帯

制限なし。kubeletの動作中は常時送信可能。

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

- イベントにはコンテナIDが含まれるが、`recordContainerEvent`関数内でコンテナIDをコンテナ名に置換することで、イベントの重複排除を支援しつつ、内部IDの外部露出を軽減している。
- Event APIへのアクセスはRBACにより制御される。

## 備考

- 本イベントはkubelet内の`kubeGenericRuntimeManager.startContainer`関数（`kuberuntime_container.go` 288行目）で発行される。
- イベント定数は`pkg/kubelet/events/event.go` 21行目で`CreatedContainer = "Created"`として定義されている。

---

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

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

### 推奨読解順序

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

まず、イベント定数の定義とKubernetes Eventオブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 21行目: `CreatedContainer = "Created"` の定数定義を確認 |
| 1-2 | types.go | `staging/src/k8s.io/api/core/v1/types.go` | Event構造体の定義（Type, Reason, Message等） |

**読解のコツ**: イベント定数はGoのconst宣言でグループ化されている。Container event reason listというコメントブロック内にある。

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

処理の起点となるstartContainer関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kuberuntime_container.go | `pkg/kubelet/kuberuntime/kuberuntime_container.go` | 199行目: `startContainer`関数の全体構造を把握 |

**主要処理フロー**:
1. **214行目**: イメージプル（EnsureImageExists）
2. **276行目**: CRI CreateContainer RPC呼び出し
3. **282行目**: PreStartContainerフック実行
4. **288行目**: `recordContainerEvent`でCreatedイベント発行
5. **291行目**: CRI StartContainer RPC呼び出し

#### Step 3: イベント記録関数を理解する

recordContainerEvent関数の内部処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kuberuntime_container.go | `pkg/kubelet/kuberuntime/kuberuntime_container.go` | 84行目: `recordContainerEvent`関数の実装 |

**主要処理フロー**:
- **86行目**: GenerateContainerRefでコンテナのObjectReference生成
- **98-100行目**: containerIDをコンテナ名に置換（イベント重複排除対策）
- **101行目**: recorder.Eventでイベント記録

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

```
kubeGenericRuntimeManager.SyncPod()
    |
    +-- startContainer()                    [kuberuntime_container.go:199]
           |
           +-- imagePuller.EnsureImageExists()
           +-- generateContainerConfig()
           +-- internalLifecycle.PreCreateContainer()
           +-- runtimeService.CreateContainer()  [CRI RPC]
           +-- internalLifecycle.PreStartContainer()
           +-- recordContainerEvent()            [kuberuntime_container.go:288]
           |      |
           |      +-- GenerateContainerRef()
           |      +-- recorder.Event()           [Event APIへ送信]
           |
           +-- runtimeService.StartContainer()   [CRI RPC]
```

### データフロー図

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

Pod Spec          ------>  startContainer()               ------>  Kubernetes Event
(Container定義)              |                                      (Type: Normal,
                             +-- CRI CreateContainer               Reason: Created,
                             +-- recordContainerEvent              Message: "Container created")
                             |
Container ID      <------  CRI Response
(ランタイムから)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| kuberuntime_container.go | `pkg/kubelet/kuberuntime/kuberuntime_container.go` | ソース | コンテナ作成・起動処理およびイベント記録 |
| kuberuntime_manager.go | `pkg/kubelet/kuberuntime/kuberuntime_manager.go` | ソース | Pod同期処理の全体管理 |
| kubelet.go | `pkg/kubelet/kubelet.go` | ソース | kubelet本体、Pod同期のトリガー |
