# 機能設計書 103-トップ（top）

## 概要

本ドキュメントは、`kubectl top` コマンドによるリソース使用量表示機能の設計を記述する。ノードやPodのCPU/メモリ使用量をMetrics Server経由で取得し表示する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターの運用において、ノードやPodのリソース消費状況をリアルタイムに把握することは、パフォーマンス問題の特定やキャパシティプランニングに不可欠である。`kubectl top` はMetrics Serverから収集されたメトリクスを簡易的に表示し、HPA/VPAが使用するメトリクスと同じ値を確認できる。

**機能の利用シーン**：クラスターのリソース使用状況の即時確認、リソース不足ノードの特定、Pod単位のリソース消費分析、HPA/VPA設定の検証時に利用される。

**主要な処理内容**：
1. Metrics Server APIのバージョン確認（v1beta1サポートチェック）
2. ノードまたはPodのメトリクス取得
3. メトリクスデータの変換と整形
4. テーブル形式での表示（CPU/メモリ使用量と割合）

**関連システム・外部連携**：Metrics Server（metrics.k8s.io API）、API Server（ノード/Pod情報取得）

**権限による制御**：metrics.k8s.io APIグループへのget/list権限、およびノード/Pod情報の読み取り権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | kubectl top | 主機能 | ノードやPodのリソース使用量を表示する主処理 |
| 14 | kubectl top | API連携 | Metrics APIを通じてCPU/メモリ使用量のメトリクスを取得する |

## 機能種別

データ参照・メトリクス表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| サブコマンド | string | Yes | node または pod | node / pod のいずれか |
| NAME | string | No | リソース名 | セレクターとの同時指定不可 |
| -l / --selector | string | No | ラベルセレクター | 有効なラベルセレクター形式 |
| --field-selector | string | No | フィールドセレクター（Pod用） | 有効なフィールドセレクター形式 |
| --sort-by | string | No | ソートキー | cpu / memory のみ |
| --containers | bool | No | コンテナ別表示（Pod用） | デフォルト: false |
| -A / --all-namespaces | bool | No | 全Namespace対象（Pod用） | デフォルト: false |
| --no-headers | bool | No | ヘッダー非表示 | デフォルト: false |
| --use-protocol-buffers | bool | No | Protocol Buffers使用 | デフォルト: true |
| --sum | bool | No | 合計表示（Pod用） | デフォルト: false |
| --show-capacity | bool | No | Capacity表示（Node用） | デフォルト: false（Allocatable表示） |
| --show-swap | bool | No | スワップ情報表示 | デフォルト: false |

### 入力データソース

- Metrics Server API（metrics.k8s.io/v1beta1）
- API Server（ノード/Pod情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| NAME | string | ノードまたはPod名 |
| CPU(cores) | string | CPU使用量 |
| CPU% | string | CPU使用率（ノード用） |
| MEMORY(bytes) | string | メモリ使用量 |
| MEMORY% | string | メモリ使用率（ノード用） |
| SWAP(bytes) | string | スワップ使用量（--show-swap時） |

### 出力先

標準出力（stdout）にテーブル形式で表示

## 処理フロー

### 処理シーケンス

```
1. サブコマンド判定（node / pod）
2. 引数のパースとバリデーション
   └─ NAME と --selector の排他チェック
3. Metrics APIバージョンチェック
   └─ SupportedMetricsAPIVersionAvailable()
4. メトリクスデータの取得
   ├─ [node] getNodeMetricsFromMetricsAPI()
   └─ [pod] getMetricsFromMetricsAPI()
5. [node] ノード情報の取得（Allocatable/Capacity）
6. [pod] メトリクス空時の原因調査
   └─ verifyEmptyMetrics() - Pod年齢チェック
7. 表示処理
   ├─ [node] PrintNodeMetrics()
   └─ [pod] PrintPodMetrics()
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{サブコマンド}
    B -->|node| C[TopNodeOptions.Complete]
    B -->|pod| D[TopPodOptions.Complete]
    C --> E[Metrics API利用可能チェック]
    D --> E
    E --> F{利用可能か}
    F -->|No| G[Metrics API not available エラー]
    F -->|Yes| H[メトリクス取得]
    H --> I{メトリクスが空か}
    I -->|Yes - node| J[metrics not available yet エラー]
    I -->|Yes - pod| K[Pod年齢チェック]
    I -->|No| L[テーブル表示]
    K --> L
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-301 | Metrics APIバージョン | v1beta1のみサポート | 常に適用 |
| BR-302 | Pod年齢チェック | 作成後2分未満のPodはメトリクス未取得の可能性を通知 | Pod メトリクスが空の場合 |
| BR-303 | ソートキー制約 | --sort-byは cpu または memory のみ | --sort-by指定時 |
| BR-304 | リソース表示基準 | デフォルトはAllocatable、--show-capacityでCapacity表示 | node サブコマンド |
| BR-305 | Protocol Buffers | デフォルトでProtocol Buffersを使用して効率的な通信 | 常に適用 |

### 計算ロジック

CPU/メモリ使用率 = (使用量 / Allocatable or Capacity) * 100。ノードのスワップ容量は `node.Status.NodeInfo.Swap.Capacity` から取得。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メトリクス取得 | Metrics Server | SELECT（GET/LIST） | メトリクスデータの読み取り |
| ノード/Pod情報取得 | etcd（API Server経由） | SELECT（GET/LIST） | リソース情報の読み取り |

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

本機能は読み取り専用。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API未対応 | Metrics API が利用できない | "Metrics API not available" エラー |
| - | メトリクス未取得 | メトリクスがまだ収集されていない | "metrics not available yet" エラー |
| - | バリデーションエラー | NAME と --selector の同時指定 | 排他チェックエラー |

### リトライ仕様

特にリトライ処理は実装されていない。メトリクスが未取得の場合はエラーメッセージを表示して終了する。

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

読み取り専用の参照処理であり、トランザクション管理は不要。

## パフォーマンス要件

Protocol Buffers使用（デフォルトON）により、JSON通信と比較して効率的なメトリクスデータ転送を実現する。

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

- metrics.k8s.io APIグループへのアクセス権限が必要
- --all-namespaces 指定時は全Namespaceのメトリクス閲覧権限が必要

## 備考

- Metrics Serverがクラスターにインストールされている必要がある
- 表示されるメトリクスはHPA/VPAが使用する値と同一であり、OSツール（top等）とは値が異なる場合がある
- Pod作成後約2分間はメトリクスが利用できない場合がある（metricsCreationDelay = 2分）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | TopPodOptions構造体（45-64行目）：Pod用オプション |
| 1-2 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | TopNodeOptions構造体（41-56行目）：Node用オプション |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | NewCmdTop関数（69-82行目）：親コマンド定義、サブコマンド登録 |
| 2-2 | top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | SupportedMetricsAPIVersionAvailable関数（84-98行目）：APIバージョンチェック |

#### Step 3: Pod メトリクス処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | RunTopPod関数（173-223行目）：Podメトリクス取得と表示 |
| 3-2 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | getMetricsFromMetricsAPI関数（225-250行目）：Metrics APIからのデータ取得 |
| 3-3 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | verifyEmptyMetrics関数（252-279行目）：空メトリクスの原因調査 |

#### Step 4: Node メトリクス処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | RunTopNode関数（148-213行目）：Nodeメトリクス取得と表示 |
| 4-2 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | **195-211行目**: Allocatable/Capacityの選択とスワップ情報取得 |

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

```
NewCmdTop
    │
    ├─ NewCmdTopNode
    │      ├─ TopNodeOptions.Complete()
    │      ├─ TopNodeOptions.Validate()
    │      └─ TopNodeOptions.RunTopNode()
    │             ├─ SupportedMetricsAPIVersionAvailable()
    │             ├─ getNodeMetricsFromMetricsAPI()
    │             ├─ NodeClient.Nodes().Get/List()
    │             └─ Printer.PrintNodeMetrics()
    │
    └─ NewCmdTopPod
           ├─ TopPodOptions.Complete()
           ├─ TopPodOptions.Validate()
           └─ TopPodOptions.RunTopPod()
                  ├─ SupportedMetricsAPIVersionAvailable()
                  ├─ getMetricsFromMetricsAPI()
                  ├─ verifyEmptyMetrics() [メトリクス空時]
                  └─ Printer.PrintPodMetrics()
```

### データフロー図

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

コマンドライン引数 ──▶ Complete() ──▶ Validate()
                                          │
Metrics Server ◀── MetricsClient ◀───────┘
       │                                   │
       ▼                                   ▼
   メトリクスデータ ──▶ 変換処理 ──▶ TopCmdPrinter ──▶ stdout
                                          ▲
API Server ──▶ ノード/Pod情報 ────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | ソース | 親コマンド定義、APIバージョンチェック |
| top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | ソース | Podメトリクス取得・表示 |
| top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | ソース | Nodeメトリクス取得・表示 |
| top_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_test.go` | テスト | APIバージョンチェックのテスト |
| top_pod_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod_test.go` | テスト | Podメトリクスのテスト |
| top_node_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node_test.go` | テスト | Nodeメトリクスのテスト |
