# 通知設計書 67-Unhealthy

## 概要

本ドキュメントは、Kubernetesにおいて、コンテナのヘルスチェック（Probe）に失敗した際に発行される「Unhealthy」イベントの設計を記述する。

### 本通知の処理概要

kubeletのプローバ（prober）がコンテナに対してLiveness Probe、Readiness Probe、またはStartup Probeを実行し、プローブが失敗（Failure）またはエラーを返した場合にこの通知を発行する。プローブの種別と失敗の詳細がイベントメッセージに含まれる。

**業務上の目的・背景**：Kubernetesのプローブ機能は、コンテナの健全性を監視する重要な機構である。Liveness Probeの失敗はコンテナの再起動を引き起こし、Readiness Probeの失敗はServiceのエンドポイントからの除外を引き起こし、Startup Probeの失敗はコンテナが起動完了していないことを示す。この通知によりユーザーはプローブ失敗の原因を特定し、アプリケーションの問題を修正できる。

**通知の送信タイミング**：プローバが定期的にProbeを実行し、結果がFailureまたはエラーの場合に発行される。プローブの実行間隔はPod仕様のperiodSecondsで定義される。

**通知の受信者**：Podオブジェクト（対象コンテナ）に対するKubernetes Eventとして記録され、kubectl describe pod等で確認可能。アプリケーション開発者が対象。

**通知内容の概要**：「{probeType} probe failed: {output}」または「{probeType} probe errored and resulted in {result} state: {error}」というメッセージがPodオブジェクトに対するWarningイベントとして記録される。probeTypeはLiveness/Readiness/Startupのいずれか。

**期待されるアクション**：プローブの出力内容を確認し、アプリケーションの問題を特定する。ヘルスチェックエンドポイントの実装、ネットワーク設定、タイムアウト設定等を見直す。

## 通知種別

Kubernetes Event（EventType: Warning）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（prober.probe内で発行） |
| 優先度 | 高（コンテナ健全性に直結） |
| リトライ | なし（プローブの定期実行により繰り返される） |

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

recordContainerEventメソッドにより、Pod内の対象コンテナに対するEventとして記録される。

## 通知テンプレート

### メール通知の場合

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

### 本文テンプレート

```
# プローブ失敗時
{probeType} probe failed: {output}

# プローブエラー時
{probeType} probe errored and resulted in {result} state: {error}
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| probeType | プローブ種別（liveness/readiness/startup） | probeメソッドの引数 | Yes |
| output | プローブの出力結果 | runProbeWithRetriesの戻り値 | Yes（Failure時） |
| result | プローブ結果の状態 | probe.Result | Yes（Error時） |
| error | エラーの詳細 | runProbeWithRetriesのエラー | Yes（Error時） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 定期プローブ | Liveness Probe失敗 | probe結果がFailureまたはエラー | コンテナ再起動を伴う可能性 |
| 定期プローブ | Readiness Probe失敗 | probe結果がFailureまたはエラー | Serviceエンドポイントから除外 |
| 定期プローブ | Startup Probe失敗 | probe結果がFailureまたはエラー | コンテナ起動未完了 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| プローブ成功（Success） | プローブが成功した場合はイベント発行されない |
| プローブ結果がUnknown | Unknown時はFailure結果を返すがイベントは発行されない |
| プローブ結果がWarning | Warning時はProbeWarning（No.68）が代わりに発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[prober.probe実行] --> B[runProbeWithRetries]
    B --> C{エラー発生?}
    C -->|Yes| D[Unhealthy イベント発行 - エラーメッセージ]
    C -->|No| E{結果判定}
    E -->|Success| F[成功 - イベントなし]
    E -->|Warning| G[ProbeWarning イベント発行]
    E -->|Failure| H[Unhealthy イベント発行 - 失敗メッセージ]
    E -->|Unknown| I[Failure返却 - イベントなし]
    D --> J[results.Failure返却]
    H --> J
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Pod | Pod仕様の確認 | プローブ定義の参照 |
| Container | コンテナのプローブ仕様 | LivenessProbe/ReadinessProbe/StartupProbe |

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

#### Container (v1.Container)

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| livenessProbe | Liveness Probe仕様 | probeType == liveness |
| readinessProbe | Readiness Probe仕様 | probeType == readiness |
| startupProbe | Startup Probe仕様 | probeType == startup |

### 更新テーブル一覧

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

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

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | reason | Unhealthy | イベント理由 |
| INSERT | message | {probeType} probe failed/errored: ... | プローブ種別と結果含む |
| INSERT | type | Warning | イベントタイプ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| プローブエラー | runProbeWithRetriesがエラーを返す | エラー内容をイベントに記録 |
| プローブ失敗 | probe結果がFailure | 失敗出力をイベントに記録 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | maxProbeRetries（プローブ実行内でのリトライ） |
| リトライ間隔 | periodSeconds（プローブ定義に基づく定期実行） |
| リトライ対象エラー | 全てのプローブエラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Eventのデフォルトレート制限に従う |
| 1日あたり上限 | 制限なし（Eventの自動集約による） |

### 配信時間帯

制限なし（プローブの定期実行に依存）

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

プローブの出力（output）にはアプリケーションからのHTTPレスポンスボディや、コマンド実行の標準出力が含まれる可能性がある。アプリケーションの実装によっては機密情報がプローブ出力に含まれる場合があるため、ヘルスチェックエンドポイントでは機密情報を出力しないよう注意が必要。

## 備考

- runProbeWithRetriesはmaxProbeRetries回のリトライを行った後に最終結果を返す
- Liveness Probeの失敗はfailureThreshold回連続で失敗した場合にコンテナ再起動を引き起こす
- Readiness Probeの失敗はPodのReady Conditionをfalseにし、Serviceエンドポイントから除外する
- Startup Probeの失敗中はLiveness/Readiness Probeは実行されない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | event.go | `pkg/kubelet/events/event.go` | ContainerUnhealthy定数の定義（行97）- 値は「Unhealthy」 |

**読解のコツ**: Go定数名はContainerUnhealthyだが、イベントReason文字列は「Unhealthy」。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | prober.go | `pkg/kubelet/prober/prober.go` | probeメソッド（行83-134） |

**主要処理フロー**:
1. **行84-94**: probeType（readiness/liveness/startup）に基づくProbeSpec取得
2. **行102**: runProbeWithRetriesでプローブ実行
3. **行104-108**: エラー発生時のUnhealthyイベント発行
4. **行116-118**: Warning時のProbeWarningイベント発行
5. **行121-124**: Failure時のUnhealthyイベント発行

#### Step 3: プローブ実行の詳細を理解する

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

**主要処理フロー**:
- maxProbeRetries回のリトライループ
- 各回のプローブ実行と結果判定

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

```
prober.probe
    |
    +-- probeSpec取得（container.LivenessProbe等）
    |
    +-- runProbeWithRetries
    |      |
    |      +-- runProbe (実際のプローブ実行)
    |             |
    |             +-- HTTP GET / TCP / Exec / gRPC
    |
    +-- [エラー時] recordContainerEvent (Unhealthy)
    |
    +-- [Failure時] recordContainerEvent (Unhealthy)
    |
    +-- [Warning時] recordContainerEvent (ProbeWarning)
```

### データフロー図

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

Pod (仕様)         ───> prober.probe                    ───> Kubernetes Event
Container          ───> runProbeWithRetries              (Unhealthy)
ProbeSpec          ───> HTTP GET / TCP / Exec / gRPC     + results.Failure
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| event.go | `pkg/kubelet/events/event.go` | ソース | イベント理由定数の定義 |
| prober.go | `pkg/kubelet/prober/prober.go` | ソース | プローバ本体、プローブ実行とイベント発行 |
| prober_test.go | `pkg/kubelet/prober/prober_test.go` | テスト | プローバのテスト |
