# 通知設計書 19-Pulling

## 概要

本ドキュメントは、Kubernetesのkubeletがコンテナイメージのプルを開始した際に発行されるイベント通知「Pulling」の設計を記述する。

### 本通知の処理概要

kubeletのimageManagerがPodのコンテナに必要なイメージをコンテナレジストリからプルする際に、プル開始を通知するイベントを発行する。イメージプルの進行状況を可視化するための重要な通知である。

**業務上の目的・背景**：コンテナイメージのプルはPod起動の最も時間のかかるステップの一つであり、特に大きなイメージや遅いレジストリの場合に顕著である。この通知はPod起動の進行状況をユーザーに伝え、イメージプルが進行中であることを可視化する。Pod起動の遅延原因がイメージプルにあることを特定する手助けとなる。

**通知の送信タイミング**：imageManagerのpullImage関数内で、バックオフチェック通過後、実際のイメージプルを開始する直前に発行される。

**通知の受信者**：Pod作成を要求したユーザー、Namespace管理者。Kubernetes Eventとして記録される。

**通知内容の概要**：「Pulling image "{イメージ名}"」という形式で、プル対象のイメージ名が通知される。

**期待されるアクション**：通常は情報通知であり、ユーザーの介入は不要。長時間Pullingが続く場合は、レジストリの接続性やイメージサイズを確認する。

## 通知種別

Kubernetes Event（クラスタ内部イベント通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（pullImage処理フロー内で即時発行） |
| 優先度 | 低（Normal） |
| リトライ | なし（情報通知のため。プル自体はバックオフ付きリトライあり） |

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

イベントの対象オブジェクトは、イメージプルを必要とするコンテナの参照オブジェクト（ObjectReference）である。通常はPod内の特定コンテナを指す。

## 通知テンプレート

### Kubernetes Eventの場合

| 項目 | 内容 |
|-----|------|
| EventType | Normal |
| Reason | Pulling |
| Regarding | 対象コンテナのObjectReference |
| 発行元 | kubelet |

### 本文テンプレート

```
Pulling image "{image}"
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| image | プル対象のコンテナイメージ名（タグ/ダイジェスト付き） | EnsureImageExistsのimage引数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | pullImage実行 | バックオフ中でない かつ イメージプルが必要 | イメージプル開始時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| バックオフ中 | IsInBackOffSinceUpdateがtrueの場合、BackOffイベントが代わりに発行される |
| イメージがローカルに存在 | pullPolicy=IfNotPresentでイメージが既に存在する場合、プルは行われない |
| pullPolicy=Never | イメージプルが実行されないため通知も発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[EnsureImageExists] --> B[imagePullPrecheck]
    B --> C{プルが必要?}
    C -->|No, イメージ存在| D[Pulledイベント発行]
    C -->|Yes| E[pullImage]
    E --> F{バックオフ中?}
    F -->|Yes| G[BackOffイベント発行]
    F -->|No| H[RecordImageStartedPulling]
    H --> I[Event発行: Pulling]
    I --> J[puller.pullImage実行]
    J --> K{プル成功?}
    K -->|Yes| L[RecordImageFinishedPulling]
    L --> M[Pulledイベント発行]
    K -->|No| N[FailedToPullImageイベント発行]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| コンテナランタイム | イメージ存在確認 | GetImageRef呼び出し |
| etcd (Pod) | Pod annotations | imagePullCredentials取得用 |
| etcd (Secret) | イメージプルシークレット | レジストリ認証用 |

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

#### Pod リソース

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.containers[].image | プル対象イメージ名 | syncPod対象のPod |
| spec.imagePullSecrets | レジストリ認証情報 | プル認証時 |

### 更新テーブル一覧

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

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | "Pulling" | イベント理由 |
| INSERT | message | "Pulling image \"...\"" | イメージ名 |
| INSERT | type | "Normal" | イベントタイプ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | Pullingイベント自体はプル開始の通知であり、エラーは発生しない | - |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（Pulling通知はプル開始の情報通知） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし。

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

- イベントメッセージにはコンテナイメージ名が含まれる。プライベートレジストリのURL情報が含まれる可能性がある。
- イメージプル用の認証情報（シークレット）はメッセージに含まれない。

## 備考

- imageManager.go:355行目にイベント発行コードがある。
- イメージプルにはシリアルモードとパラレルモードがあり（image_manager.go:91-95行目）、モードによりプルの同時実行数が異なる。
- podPullingTimeRecorder.RecordImageStartedPulling（354行目）でプル開始時刻が記録され、メトリクス用に使用される。
- logIt関数（image_manager.go:139-145行目）を通じてイベント記録とログ出力が同時に行われる。
- objRefがnilの場合はイベント記録はスキップされ、ログ出力のみ行われる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | 47行目: `PullingImage = "Pulling"` 定数 |

**読解のコツ**: イベント定数名はPullingImageだが、Reason文字列は "Pulling" である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | image_manager.go | `pkg/kubelet/images/image_manager.go` | 164行目: EnsureImageExists関数（イメージプルのエントリーポイント） |
| 2-2 | image_manager.go | `pkg/kubelet/images/image_manager.go` | 317行目: pullImage関数 |

**主要処理フロー**:
1. **176行目**: applyDefaultImageTagでデフォルトタグを適用
2. **197行目**: imagePullPrecheckでプリチェック
3. **240-266行目**: イメージが既に存在する場合の処理
4. **281行目**: pullImage呼び出し

#### Step 3: イベント発行ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | image_manager.go | `pkg/kubelet/images/image_manager.go` | 336-356行目: バックオフチェックとPullingイベント発行 |

**主要処理フロー**:
- **337行目**: `m.backOff.IsInBackOffSinceUpdate` でバックオフ確認
- **354行目**: `RecordImageStartedPulling` でプル開始記録
- **355行目**: `m.logIt(objRef, v1.EventTypeNormal, events.PullingImage, logPrefix, ...)` でPullingイベント発行
- **359行目**: `m.puller.pullImage` で実際のプル実行

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

```
imageManager.EnsureImageExists (image_manager.go:164)
    |
    +-- applyDefaultImageTag
    +-- imagePullPrecheck
    |       +-- imageService.GetImageRef
    |
    +-- pullImage (image_manager.go:317)
            |
            +-- backOff.IsInBackOffSinceUpdate
            +-- podPullingTimeRecorder.RecordImageStartedPulling
            +-- logIt (Pulling イベント発行)
            +-- puller.pullImage
            |       +-- (コンテナランタイムへのプル要求)
            +-- logIt (Pulled / FailedToPullImage)
```

### データフロー図

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

Pod Spec (image) ----------> EnsureImageExists
imagePullSecrets ----------> pullCredentials取得
                                |
                                +-- imagePullPrecheck --> (イメージ存在チェック)
                                |
                                +-- pullImage
                                    |
                                    +-- logIt --> Event (Normal/Pulling)
                                    +-- puller.pullImage --> コンテナランタイム
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| image_manager.go | `pkg/kubelet/images/image_manager.go` | ソース | イメージプル処理とイベント発行 |
