# 画面設計書 14-kubectl top

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl top` コマンドの画面設計書である。ノードおよびPodのCPU/メモリリソース使用量をMetrics API経由で取得・表示するコマンドの仕様を記載する。

### 本画面の処理概要

`kubectl top` コマンドは、Metrics Serverから取得したリソースメトリクスを基に、ノードまたはPodのCPU・メモリ使用量をテーブル形式で表示する。HPAやVPAなどのオートスケーリングが参照するメトリクスと同じデータソースを使用するため、スケーリング設定の検証にも有用である。

**業務上の目的・背景**：クラスタの運用監視において、ノードやPodのリソース消費状況をリアルタイムに把握する必要がある。本コマンドにより、リソース使用量の確認やボトルネック特定を迅速に行える。本格的なモニタリングソリューションの代替ではなく、オートスケーラー用メトリクスの確認や簡易的なスポットチェックを目的とする。

**画面へのアクセス方法**：ターミナル上で `kubectl top node` または `kubectl top pod` を実行する。

**主要な操作・処理内容**：
1. `kubectl top node [NAME]` - ノードのCPU/メモリ使用量を表示
2. `kubectl top pod [NAME]` - PodのCPU/メモリ使用量を表示
3. ラベルセレクタやソート、コンテナ別表示などのオプションをサポート

**画面遷移**：本コマンドは情報表示のみのコマンドであり、リソース変更は行わない。

**権限による表示制御**：Metrics API（metrics.k8s.io）に対するget/list権限が必要。またnodeまたはpodリソースのget/list権限も必要。

## 関連機能

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

## 画面種別

CLI コマンド（情報表示 - サブコマンド構成）

## URL/ルーティング

```
kubectl top node [NAME | -l label]
kubectl top pod [NAME | -l label]
```

## 入出力項目

### 入力項目（top node）

| 項目名 | フラグ | 型 | 必須 | デフォルト | 説明 |
|--------|--------|------|------|-----------|------|
| ノード名 | 位置引数 | string | No | - | 特定ノードのメトリクスを表示 |
| ラベルセレクタ | -l, --selector | string | No | "" | ラベルによるフィルタリング |
| ソート | --sort-by | string | No | "" | "cpu"または"memory"でソート |
| ヘッダ非表示 | --no-headers | bool | No | false | ヘッダ行を非表示 |
| Protocol Buffers | --use-protocol-buffers | bool | No | true | Metrics APIアクセスにProtocol Buffersを使用 |
| Capacity表示 | --show-capacity | bool | No | false | Allocatableの代わりにCapacityを基準に表示 |
| Swap表示 | --show-swap | bool | No | false | Swapメモリ関連情報も表示 |

### 入力項目（top pod）

| 項目名 | フラグ | 型 | 必須 | デフォルト | 説明 |
|--------|--------|------|------|-----------|------|
| Pod名 | 位置引数 | string | No | - | 特定Podのメトリクスを表示 |
| ラベルセレクタ | -l, --selector | string | No | "" | ラベルによるフィルタリング |
| フィールドセレクタ | --field-selector | string | No | "" | フィールドによるフィルタリング |
| ソート | --sort-by | string | No | "" | "cpu"または"memory"でソート |
| コンテナ表示 | --containers | bool | No | false | コンテナ別の使用量を表示 |
| 全名前空間 | -A, --all-namespaces | bool | No | false | 全名前空間のPodを表示 |
| ヘッダ非表示 | --no-headers | bool | No | false | ヘッダ行を非表示 |
| Protocol Buffers | --use-protocol-buffers | bool | No | true | Protocol Buffersを使用 |
| 合計表示 | --sum | bool | No | false | リソース使用量の合計を表示 |
| Swap表示 | --show-swap | bool | No | false | Swapメモリ関連情報も表示 |

### 出力項目

テーブル形式でリソース使用量を表示。

## 表示項目

### top node の表示項目

| 項目 | 説明 |
|------|------|
| NAME | ノード名 |
| CPU(cores) | CPU使用量（コア単位） |
| CPU% | CPU使用率（Allocatable/Capacity比） |
| MEMORY(bytes) | メモリ使用量（バイト単位） |
| MEMORY% | メモリ使用率（Allocatable/Capacity比） |

### top pod の表示項目

| 項目 | 説明 |
|------|------|
| NAMESPACE | 名前空間（--all-namespaces時） |
| NAME | Pod名 |
| CPU(cores) | CPU使用量 |
| MEMORY(bytes) | メモリ使用量 |
| CONTAINER | コンテナ名（--containers時のみ） |

## イベント仕様

### 1-top node実行

1. コマンドライン引数を解析しTopNodeOptionsを初期化する（`Complete`、top_node.go L104-134）
2. --sort-byの値を検証する（`Validate`、L136-146）
3. Discovery APIでMetrics APIの可用性を確認する（`RunTopNode`、L158-167）
4. Metrics APIからノードメトリクスを取得する（`getNodeMetricsFromMetricsAPI`、L216-239）
5. ノードリソース情報（Allocatable/Capacity）を取得する（L179-211）
6. メトリクスとリソース情報を組み合わせてテーブル表示する（L213）

### 2-top pod実行

1. コマンドライン引数を解析しTopPodOptionsを初期化する（`Complete`、top_pod.go L125-159）
2. --sort-byの値を検証する（`Validate`、L161-171）
3. Discovery APIでMetrics APIの可用性を確認する（`RunTopPod`、L190-199）
4. Metrics APIからPodメトリクスを取得する（`getMetricsFromMetricsAPI`、L225-250）
5. メトリクスが空の場合、Pod作成からの経過時間を確認する（`verifyEmptyMetrics`、L252-279）
6. メトリクスをテーブル表示する（L222）

## データベース更新仕様

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

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| top node実行 | NodeMetrics (metrics.k8s.io) | SELECT | ノードメトリクスを取得 |
| top node実行 | Node | SELECT | ノードのAllocatable/Capacity情報を取得 |
| top pod実行 | PodMetrics (metrics.k8s.io) | SELECT | Podメトリクスを取得 |

読み取り専用コマンドのため、データ書き込みは発生しない。

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|-----------|------|
| エラー | `Metrics API not available` | Metrics Serverが未インストール |
| エラー | `metrics not available yet` | メトリクスデータが未収集 |
| エラー | `--sort-by accepts only cpu or memory` | 不正なsort-by値 |
| エラー | `only one of NAME or --selector can be provided` | 名前とセレクタの同時指定 |
| エラー | `Metrics not available for pod %s/%s, age: %s` | Pod作成後2分超経過でメトリクスなし |
| 情報 | `No resources found` | 全名前空間指定時に対象なし |
| 情報 | `No resources found in %s namespace.` | 特定名前空間で対象なし |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| Metrics Serverが未インストール | `Metrics API not available` エラーを表示 |
| メトリクスが未収集（Pod作成直後） | `metrics not available yet` エラーを表示 |
| Pod作成後2分超経過でメトリクスなし | `Metrics not available for pod` エラーを表示（top_pod.go L281-289） |
| ノード/Pod取得権限がない | 403 Forbiddenエラーを表示 |
| API Serverに接続できない | 接続エラーメッセージを表示 |

## 備考

- Metrics APIバージョンはv1beta1のみサポート（top.go L36-38）
- Protocol Buffersはデフォルトで有効であり、Metrics APIアクセスの効率化に寄与する
- メトリクスの値はOSツール（`top`コマンド等）とは異なり、オートスケーラー向けに最適化されたもの
- Pod作成後約2分（`metricsCreationDelay`、top_pod.go L66）はメトリクスが利用不可
- --show-capacityフラグによりAllocatable（デフォルト）またはCapacityを基準にした使用率を表示可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | 定数定義（sortByCPU/sortByMemory）とMetrics APIバージョン |
| 1-2 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | TopNodeOptions構造体（L41-56） |
| 1-3 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | TopPodOptions構造体（L45-64） |

**読解のコツ**: MetricsClient（metricsclientset.Interface）がMetrics APIとの通信を担当し、NodeClient/PodClientが通常のKubernetes APIとの通信を担当する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | NewCmdTop関数（L69-82）：親コマンドとnode/podサブコマンド登録 |
| 2-2 | top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | SupportedMetricsAPIVersionAvailable（L84-98）：APIバージョン確認 |

#### Step 3: top node処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | RunTopNode（L148-213）：メトリクス取得・ノード情報取得・表示 |
| 3-2 | top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | getNodeMetricsFromMetricsAPI（L216-239）：Metrics APIアクセス |

**主要処理フロー**:
- **L158-167**: Metrics APIの可用性確認
- **L169-172**: メトリクスデータ取得
- **L179-211**: ノードのAllocatable/Capacity情報取得とSwap対応
- **L213**: PrintNodeMetricsでテーブル表示

#### Step 4: top pod処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | RunTopPod（L173-223）：Podメトリクス取得と表示 |
| 4-2 | top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | verifyEmptyMetrics（L252-279）：空メトリクスの原因調査 |

**主要処理フロー**:
- **L200**: Metrics APIからPodメトリクスを取得
- **L206-220**: メトリクスが空の場合の原因確認（Pod年齢チェック）
- **L222**: PrintPodMetricsでテーブル表示

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

```
NewCmdTop (top.go L69)
    |
    +-- NewCmdTopNode (top_node.go L72)
    |       +-- Complete (L104)
    |       |       +-- f.KubernetesClientSet()
    |       |       +-- metricsclientset.NewForConfig()
    |       +-- Validate (L136)
    |       +-- RunTopNode (L148)
    |               +-- SupportedMetricsAPIVersionAvailable (top.go L84)
    |               +-- getNodeMetricsFromMetricsAPI (L216)
    |               |       +-- MetricsV1beta1().NodeMetricses().Get/List()
    |               +-- NodeClient.Nodes().Get/List()
    |               +-- Printer.PrintNodeMetrics()
    |
    +-- NewCmdTopPod (top_pod.go L91)
            +-- Complete (L125)
            +-- Validate (L161)
            +-- RunTopPod (L173)
                    +-- SupportedMetricsAPIVersionAvailable
                    +-- getMetricsFromMetricsAPI (L225)
                    |       +-- MetricsV1beta1().PodMetricses().Get/List()
                    +-- verifyEmptyMetrics (L252)
                    |       +-- checkPodAge (L281)
                    +-- Printer.PrintPodMetrics()
```

### データフロー図

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

コマンドライン引数        Complete()
  node/pod NAME        --> クライアント初期化 --------+
  --selector                                          |
  --sort-by            Validate()                     |
                       --> ソート値検証 --------------+
                                                      |
                       RunTopNode/RunTopPod()          |
                       --> Metrics API可用性確認 ---->|
                       --> Metrics API取得 ---------->+---> Metrics Server
                       --> Node/Pod情報取得 --------->+---> API Server
                                                      |
                       Printer.PrintMetrics() ------->+---> stdout
                                                             テーブル表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| top.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top.go` | ソース | topコマンドの親コマンド定義とMetrics APIバージョン確認 |
| top_node.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go` | ソース | top nodeサブコマンドの実装 |
| top_pod.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod.go` | ソース | top podサブコマンドの実装 |
| top_node_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_node_test.go` | テスト | top nodeのユニットテスト |
| top_pod_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/top/top_pod_test.go` | テスト | top podのユニットテスト |
| metricsutil/ | `staging/src/k8s.io/kubectl/pkg/metricsutil/` | ソース | メトリクス表示ユーティリティ（TopCmdPrinter等） |
