# 機能設計書 151-メトリクスサーバー連携

## 概要

本ドキュメントは、Kubernetes Metrics APIを通じたリソースメトリクスの収集と公開を行う「メトリクスサーバー連携」機能の設計について記述する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターにおいて、Podやノードのリソース使用量（CPU、メモリ等）をリアルタイムに把握することは、オートスケーリング（HPA）やリソース監視において不可欠である。Metrics APIは、Metrics Serverなどのメトリクス収集コンポーネントが収集したデータを標準化されたAPIとして公開するためのインターフェースを提供する。

**機能の利用シーン**：HPAコントローラーがPodのCPU/メモリ使用率に基づいてレプリカ数を自動調整する際、`kubectl top`コマンドでノードやPodのリソース使用量を確認する際、およびカスタムメトリクスや外部メトリクスに基づくスケーリング判断を行う際に利用される。

**主要な処理内容**：
1. NodeMetrics/PodMetrics APIリソースの型定義とスキーマ管理
2. Resource Metrics API（v1alpha1/v1beta1）によるノード・Pod単位のCPU/メモリメトリクス提供
3. Custom Metrics API（v1beta1/v1beta2）による任意のKubernetesオブジェクトに紐づくカスタムメトリクスの取得
4. External Metrics API（v1beta1）による外部システムのメトリクス取得
5. Clientset、Informer等のクライアントライブラリによるメトリクスデータへのプログラマティックなアクセス

**関連システム・外部連携**：Metrics Server（クラスター内にデプロイされるメトリクス収集コンポーネント）、Prometheus Adapter（カスタムメトリクスプロバイダー）、HPAコントローラー、kubectlなどがMetrics APIのクライアントとなる。

**権限による制御**：Metrics APIへのアクセスはRBACにより制御される。NodeMetricsはクラスタースコープ、PodMetricsはNamespaceスコープでアクセス制御が行われる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | kubectl autoscale | API連携 | HPAがスケーリング判断のためにMetrics APIからリソースメトリクスを取得する |
| 14 | kubectl top | API連携 | Metrics APIを通じてCPU/メモリ使用量のメトリクスを取得する |

## 機能種別

データ連携 / API提供

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| namespace | string | No（Nodeは不要） | メトリクス取得対象のNamespace | 有効なNamespace名 |
| name | string | No | 特定リソースのメトリクス取得時の名前 | 有効なリソース名 |
| labelSelector | string | No | ラベルセレクターによるフィルタリング | 有効なラベルセレクター構文 |
| metricName | string | Yes（Custom/External） | 取得するメトリクス名 | 空でないこと |
| metricSelector | labels.Selector | No | メトリクスのフィルタリング条件 | 有効なラベルセレクター |

### 入力データソース

Metrics Server等のメトリクス収集コンポーネントがKubeletのSummary APIから収集したリソース使用量データ。API Aggregation経由でAPI Serverに統合される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| NodeMetrics | struct | ノードのCPU/メモリ使用量、タイムスタンプ、ウィンドウ |
| PodMetrics | struct | Pod内各コンテナのCPU/メモリ使用量 |
| MetricValue | struct | カスタムメトリクスの値（オブジェクト参照、メトリクス名、値） |
| ExternalMetricValue | struct | 外部メトリクスの値（メトリクス名、ラベル、値） |

### 出力先

API Serverのエンドポイント（`/apis/metrics.k8s.io/`）経由でクライアントに返却

## 処理フロー

### 処理シーケンス

```
1. クライアント（HPA/kubectl等）がMetrics APIにリクエスト送信
   └─ API Serverがリクエストを受け付け、API Aggregation経由でMetrics Serverに転送
2. Metrics Serverがメトリクスデータを返却
   └─ 収集済みのNodeMetrics/PodMetricsをレスポンスとして返す
3. クライアントがレスポンスを処理
   └─ HPAの場合はスケーリング判断に使用、kubectlの場合は表示
```

### フローチャート

```mermaid
flowchart TD
    A[クライアントリクエスト] --> B{APIリソースタイプ}
    B -->|NodeMetrics| C[Metrics Server: ノードメトリクス取得]
    B -->|PodMetrics| D[Metrics Server: Podメトリクス取得]
    B -->|CustomMetrics| E[カスタムメトリクスプロバイダー]
    B -->|ExternalMetrics| F[外部メトリクスプロバイダー]
    C --> G[レスポンス返却]
    D --> G
    E --> G
    F --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-151-1 | メトリクスウィンドウ | メトリクスは[Timestamp-Window, Timestamp]の時間区間で収集されたデータを表す | 全メトリクスリクエスト |
| BR-151-2 | 読み取り専用 | Metrics APIは読み取り専用であり、メトリクスの作成・更新・削除は不可 | 全操作 |
| BR-151-3 | レート制限 | Clientsetはtoken bucket方式のレート制限をサポートする | QPS > 0の場合 |

### 計算ロジック

メモリ使用量はworking setメモリとして計算される。CPUはコア単位で報告される。

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メトリクス取得 | N/A（インメモリ） | SELECT相当 | Metrics Serverはインメモリストアからデータを取得 |

### テーブル別操作詳細

Metrics APIは永続化ストレージを持たない。Metrics Serverがインメモリにメトリクスデータを保持し、APIリクエストに応じて返却する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | NotFound | 指定されたノード/Podが存在しない | リソース名を確認 |
| 503 | ServiceUnavailable | Metrics Serverが未デプロイまたは異常 | Metrics Serverの状態を確認 |
| 429 | TooManyRequests | レート制限超過 | リトライ間隔を空ける |

### リトライ仕様

Clientsetのレート制限はToken Bucket方式（QPS/Burst設定可能）。HPAコントローラーは定期的にメトリクスをポーリングするため、自動リトライされる。

## トランザクション仕様

Metrics APIは読み取り専用のため、トランザクション管理は不要。

## パフォーマンス要件

Metrics Serverは数千ノード規模のクラスターで低レイテンシなメトリクス提供が求められる。メトリクスは通常15秒間隔で更新される。

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

- RBACによるアクセス制御が適用される
- メトリクスデータは機密情報を含まないが、リソース使用パターンの露出を防ぐためNamespaceスコープのアクセス制御が重要
- TLS通信によるデータ保護

## 備考

- Metrics APIはAPI Aggregation Layer経由で提供される拡張APIである
- metrics.k8s.io APIグループに属する
- v1alpha1とv1beta1の2つのバージョンが存在する

---

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

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

### 推奨読解順序

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

メトリクスAPIの中心となる型定義を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `staging/src/k8s.io/metrics/pkg/apis/metrics/types.go` | NodeMetrics、PodMetrics、ContainerMetricsの内部型定義 |
| 1-2 | types.go (v1beta1) | `staging/src/k8s.io/metrics/pkg/apis/metrics/v1beta1/types.go` | v1beta1バージョンの型定義 |
| 1-3 | types.go (custom) | `staging/src/k8s.io/metrics/pkg/apis/custom_metrics/types.go` | カスタムメトリクスの型定義 |
| 1-4 | types.go (external) | `staging/src/k8s.io/metrics/pkg/apis/external_metrics/types.go` | 外部メトリクスの型定義 |

**読解のコツ**: NodeMetrics（**31-45行目**）はクラスタースコープ（nonNamespaced）、PodMetrics（**66-80行目**）はNamespaceスコープ。Usageフィールドは`corev1.ResourceList`型でCPU/メモリのリソース量を格納する。ContainerMetrics（**96-101行目**）はPod内の各コンテナ単位のメトリクスを表す。

#### Step 2: クライアントインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | clientset.go | `staging/src/k8s.io/metrics/pkg/client/clientset/versioned/clientset.go` | メトリクスClientsetのインターフェースと初期化 |
| 2-2 | interfaces.go (custom) | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/interfaces.go` | CustomMetricsClientインターフェース |
| 2-3 | interfaces.go (external) | `staging/src/k8s.io/metrics/pkg/client/external_metrics/interfaces.go` | ExternalMetricsClientインターフェース |

**主要処理フロー**:
1. **32-36行目** (clientset.go): Interface定義でMetricsV1alpha1()とMetricsV1beta1()を公開
2. **68-82行目** (clientset.go): NewForConfigでレート制限付きClientsetを生成
3. **27-30行目** (custom interfaces.go): CustomMetricsClientはRootScoped/Namespaced両方のメトリクス取得をサポート
4. **46-54行目** (custom interfaces.go): MetricsInterfaceでGetForObject/GetForObjectsメソッドを定義

#### Step 3: カスタムメトリクスクライアント実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | versioned_client.go | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/versioned_client.go` | バージョン付きカスタムメトリクスクライアント |
| 3-2 | multi_client.go | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/multi_client.go` | マルチバージョン対応クライアント |
| 3-3 | discovery.go | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/discovery.go` | APIバージョン自動検出 |

#### Step 4: 外部メトリクスクライアント実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | client.go | `staging/src/k8s.io/metrics/pkg/client/external_metrics/client.go` | 外部メトリクスクライアントの実装 |

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

```
Metrics Clientset
    |
    +-- MetricsV1alpha1Client
    |      +-- NodeMetrics().List/Get
    |      +-- PodMetrics().List/Get
    |
    +-- MetricsV1beta1Client
    |      +-- NodeMetrics().List/Get
    |      +-- PodMetrics().List/Get
    |
    +-- CustomMetricsClient
    |      +-- RootScopedMetrics().GetForObject/GetForObjects
    |      +-- NamespacedMetrics().GetForObject/GetForObjects
    |
    +-- ExternalMetricsClient
           +-- NamespacedMetrics().List
```

### データフロー図

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

Kubelet Summary API -----> Metrics Server -----> metrics.k8s.io API
                           (メトリクス集約)       (NodeMetrics/PodMetrics)

Prometheus等 -----------> Custom Metrics -----> custom.metrics.k8s.io API
                          Adapter              (MetricValue)

外部システム -----------> External Metrics ---> external.metrics.k8s.io API
                          Provider             (ExternalMetricValue)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| types.go | `staging/src/k8s.io/metrics/pkg/apis/metrics/types.go` | ソース | メトリクスAPIの内部型定義 |
| types.go (v1beta1) | `staging/src/k8s.io/metrics/pkg/apis/metrics/v1beta1/types.go` | ソース | v1beta1バージョンの型定義 |
| types.go (v1alpha1) | `staging/src/k8s.io/metrics/pkg/apis/metrics/v1alpha1/types.go` | ソース | v1alpha1バージョンの型定義 |
| clientset.go | `staging/src/k8s.io/metrics/pkg/client/clientset/versioned/clientset.go` | ソース | メトリクスClientset |
| interfaces.go | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/interfaces.go` | ソース | カスタムメトリクスインターフェース |
| interfaces.go | `staging/src/k8s.io/metrics/pkg/client/external_metrics/interfaces.go` | ソース | 外部メトリクスインターフェース |
| versioned_client.go | `staging/src/k8s.io/metrics/pkg/client/custom_metrics/versioned_client.go` | ソース | カスタムメトリクスクライアント実装 |
| client.go | `staging/src/k8s.io/metrics/pkg/client/external_metrics/client.go` | ソース | 外部メトリクスクライアント実装 |
| install.go | `staging/src/k8s.io/metrics/pkg/apis/metrics/install/install.go` | ソース | APIスキーマ登録 |
| register.go | `staging/src/k8s.io/metrics/pkg/apis/metrics/register.go` | ソース | APIグループ登録 |
