# 通知設計書 81-FailedComputeMetricsReplicas

## 概要

本ドキュメントは、Kubernetes HorizontalPodAutoscaler (HPA) コントローラがメトリクスからレプリカ数の計算に失敗した際に発行される `FailedComputeMetricsReplicas` イベント通知の設計を記載する。

### 本通知の処理概要

HPA コントローラがスケーリング対象リソースのメトリクスを取得し、それに基づいて希望レプリカ数を計算する処理において、全てのメトリクスが無効であるか、一部のメトリクスが無効かつスケールダウンが求められる場合にこの通知が発行される。

**業務上の目的・背景**：HPAは自動スケーリングの中核機能であり、メトリクス計算の失敗はオートスケーリングが正常に動作しないことを意味する。運用者はこの通知を受けてメトリクス設定の不備やメトリクスサーバの障害を速やかに検知し、サービス品質を維持する必要がある。

**通知の送信タイミング**：HPAコントローラの reconcileAutoscaler 処理中に computeReplicasForMetrics が全メトリクスの計算に失敗し metricDesiredReplicas が -1 を返した場合に発行される。具体的には、全てのメトリクスソース（Object, Pods, Resource, ContainerResource, External）が無効であるか、一部無効かつスケールダウンが求められるケースで発生する。

**通知の受信者**：HPA オブジェクトに関連付けられた Kubernetes Event として記録される。kubectl describe hpa コマンドや Event ウォッチャー、外部モニタリングシステム（Prometheus, Datadog 等）を通じて運用者・SRE が受信する。

**通知内容の概要**：エラーメッセージにはどのメトリクスが無効であったか、全メトリクス数のうち何個が無効であったかの情報が含まれる。例：「invalid metrics (2 invalid out of 3), first error is: ...」

**期待されるアクション**：運用者はメトリクスサーバの稼働状態、HPA のメトリクス定義（spec.metrics）の正確性、対象リソースのセレクタ設定を確認し、問題を修正する必要がある。

## 通知種別

Kubernetes Event（EventType: Warning）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（reconcile ループ内で即座に発行） |
| 優先度 | 高（Warning イベント） |
| リトライ | 自動リトライあり（HPA は resyncPeriod ごとに再試行） |

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

HPA オブジェクト自体に対する Kubernetes Event として記録される。送信先は HPA リソースの Namespace/Name に紐づく。

## 通知テンプレート

### メール通知の場合

本通知は Kubernetes Event として発行されるため、直接的なメール通知は行わない。外部のイベント監視ツール（AlertManager, PagerDuty 等）と連携してメール通知を構成する。

### 本文テンプレート

```
failed to compute desired number of replicas based on listed metrics for %s/%s/%s: %v
```

フォーマット: `{Kind}/{Namespace}/{Name}: {error details}`

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| reference | スケール対象リソースの参照文字列 | hpa.Spec.ScaleTargetRef.Kind + hpa.Namespace + hpa.Spec.ScaleTargetRef.Name | Yes |
| err | エラー詳細メッセージ | computeReplicasForMetrics の戻り値 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コントローラ同期 | HPA reconcile ループ | computeReplicasForMetrics が metricDesiredReplicas == -1 を返した場合 | 全メトリクス無効または一部無効かつスケールダウン条件 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| currentReplicas == 0 かつ minReplicas != 0 | オートスケーリングが無効化されている場合はメトリクス計算自体が行われない |
| currentReplicas が MaxReplicas 超過または MinReplicas 未満 | 境界調整が優先されメトリクス計算はスキップ |
| 一部のメトリクスが有効でスケールアップが可能 | metricDesiredReplicas > 0 の場合はこの通知は発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[HPA reconcile 開始] --> B[スケール情報取得]
    B -->|成功| C[computeReplicasForMetrics]
    B -->|失敗| D[FailedGetScale イベント]
    C --> E{全メトリクス計算結果}
    E -->|全無効 or 一部無効+スケールダウン| F[FailedComputeMetricsReplicas イベント発行]
    E -->|一部有効+スケールアップ可能| G[スケーリング処理継続]
    F --> H[ステータス更新]
    H --> I[終了 - エラー返却]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| HorizontalPodAutoscaler | HPA スペック・ステータス取得 | Informer キャッシュ経由 |
| Scale subresource | スケール対象のレプリカ数取得 | API サーバ直接問い合わせ |
| Pod | メトリクス計算用 Pod 一覧 | Informer キャッシュ経由 |

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

#### HorizontalPodAutoscaler

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.metrics | メトリクス定義 | HPA の名前と Namespace |
| spec.scaleTargetRef | スケール対象の参照 | 同上 |
| spec.minReplicas | 最小レプリカ数 | 同上 |
| spec.maxReplicas | 最大レプリカ数 | 同上 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| HorizontalPodAutoscaler.Status | UPDATE | currentReplicas と conditions の更新 |
| Event | INSERT | Warning イベントの記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| メトリクス取得失敗 | メトリクスサーバ不通 | resyncPeriod 後に自動リトライ |
| セレクタ無効 | HPA spec.metrics のセレクタが不正 | InvalidSelector イベントが別途発行 |
| メトリクスソース種別不明 | 不明なメトリクス種別 | API バリデーションでフィルタされるが万一の場合はエラー |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 無制限（resyncPeriod ごとに自動再試行） |
| リトライ間隔 | resyncPeriod（デフォルト 15 秒） |
| リトライ対象エラー | 全てのメトリクス計算エラー |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間365日）

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

- エラーメッセージにメトリクス名やリソース名が含まれるが、秘匿情報は含まない
- Event は RBAC により閲覧権限が制御される

## 備考

- この通知は HPA の ScalingActive condition を False に設定する副作用を持つ
- HPAConfigurableTolerance feature gate が有効な場合、tolerance の設定が計算に影響する

---

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

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

### 推奨読解順序

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

HPA の API 型定義とメトリクス関連の型を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `staging/src/k8s.io/api/autoscaling/v2/types.go` | HorizontalPodAutoscaler, MetricSpec, MetricStatus の構造を理解 |

**読解のコツ**: autoscalingv2 パッケージでは MetricSpec に5種類のメトリクスソース（Object, Pods, Resource, ContainerResource, External）が定義されている。

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

HPA コントローラの reconcile ループがエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | horizontal.go | `pkg/controller/podautoscaler/horizontal.go` | reconcileAutoscaler が主要な reconcile 関数 |

**主要処理フロー**:
1. **行 759**: reconcileAutoscaler 関数の開始
2. **行 854**: computeReplicasForMetrics の呼び出し
3. **行 857-858**: metricDesiredReplicas == -1 の場合のエラーハンドリング
4. **行 862**: FailedComputeMetricsReplicas イベントの発行

#### Step 3: メトリクス計算ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | horizontal.go | `pkg/controller/podautoscaler/horizontal.go` | computeReplicasForMetrics (行 313-361) で全メトリクスのループ処理 |
| 3-2 | horizontal.go | `pkg/controller/podautoscaler/horizontal.go` | computeReplicasForMetric (行 439-509) で個別メトリクスの計算 |
| 3-3 | horizontal.go | `pkg/controller/podautoscaler/horizontal.go` | getUnableComputeReplicaCountCondition (行 1088-1096) でエラー時の condition 生成 |

**主要処理フロー**:
- **行 329-345**: 各メトリクスのループ処理、エラーカウント
- **行 347-349**: 無効メトリクス数の集計とエラーメッセージ生成
- **行 354-357**: 全メトリクス無効または一部無効+スケールダウン条件の判定

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

```
HorizontalController.reconcileAutoscaler (行 759)
    |
    +-- scaleForResourceMappings (行 807) ... スケール情報取得
    |
    +-- computeReplicasForMetrics (行 854)
    |      |
    |      +-- validateAndParseSelector (行 316) ... セレクタ検証
    |      |
    |      +-- computeReplicasForMetric (行 330) ... 各メトリクスの計算
    |             |
    |             +-- computeStatusForObjectMetric
    |             +-- computeStatusForPodsMetric
    |             +-- computeStatusForResourceMetric
    |             +-- computeStatusForContainerResourceMetric
    |             +-- computeStatusForExternalMetric
    |
    +-- eventRecorder.Event (行 862) ... FailedComputeMetricsReplicas 発行
    |
    +-- updateStatusIfNeeded (行 859) ... ステータス更新
```

### データフロー図

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

HPA Spec.Metrics -------> computeReplicasForMetrics ---> Event: FailedComputeMetricsReplicas
Scale Subresource -------> (メトリクス計算)              HPA Status (conditions 更新)
Metrics Server ----------> (レプリカ数算出)              エラーログ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| horizontal.go | `pkg/controller/podautoscaler/horizontal.go` | ソース | HPA コントローラのメインロジック |
| replica_calculator.go | `pkg/controller/podautoscaler/replica_calculator.go` | ソース | レプリカ数計算ロジック |
| metrics_client.go | `pkg/controller/podautoscaler/metrics/client.go` | ソース | メトリクス取得クライアント |
| types.go | `staging/src/k8s.io/api/autoscaling/v2/types.go` | ソース | HPA API 型定義 |
| monitor.go | `pkg/controller/podautoscaler/monitor/monitor.go` | ソース | HPA モニタリング |
