# 機能設計書 52-ノードステータス管理

## 概要

本ドキュメントは、Kubeletのノードステータス管理機能について、ノードの状態（CPU、メモリ、ディスク、ネットワーク等）をAPI Serverに定期報告する仕組みの設計を記載する。

### 本機能の処理概要

Kubeletのノードステータス管理機能は、ノードのハードウェア情報、ネットワークアドレス、容量情報、条件（Condition）、イメージ一覧などの状態情報を収集し、API Serverに定期的に報告する。これによりスケジューラーやコントローラーがノードの最新状態を把握してスケジューリング判定やノード管理を行える。

**業務上の目的・背景**：Kubernetesクラスターの安定運用には、各ノードの状態をコントロールプレーンが正確に把握する必要がある。ノードのリソース容量、利用可能量、ネットワーク到達性、各種条件（MemoryPressure、DiskPressure等）を定期報告することで、適切なPodスケジューリングとノード障害検知を実現する。

**機能の利用シーン**：Kubelet起動時のノード登録、定期的なステータス更新（デフォルト10秒間隔）、ノード状態変化時の即時報告、クラウドプロバイダーとの連携時に利用される。

**主要な処理内容**：
1. ノードのAPI Serverへの初回登録（registerWithAPIServer）
2. ノードアドレス（InternalIP、ExternalIP、Hostname）の設定
3. マシン情報（OS、アーキテクチャ、カーネルバージョン等）の収集と報告
4. ノードリソース容量（CPU、メモリ、Pods数等）と割り当て可能量の計算
5. ノード条件（Ready、MemoryPressure、DiskPressure、PIDPressure）の更新
6. ノード上のイメージ一覧の報告
7. ボリューム制限情報の報告

**関連システム・外部連携**：API Server（ノードオブジェクトの作成・更新）、cAdvisor（マシン情報取得）、クラウドプロバイダー（外部ノードアドレス）。

**権限による制御**：Kubeletはノード自身のNodeオブジェクトに対してのみ更新権限を持つ。NodeRestriction Admission Controllerにより制限される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Kubelet内部機能のため画面関連なし |

## 機能種別

データ連携 / 状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| nodeIPs | []net.IP | No | ノードIPアドレス（--node-ip指定時） | 有効なIPアドレスであること |
| hostname | string | Yes | ノードのホスト名 | 空文字不可 |
| externalCloudProvider | bool | No | 外部クラウドプロバイダー使用フラグ | - |

### 入力データソース

- cAdvisor: マシンハードウェア情報（CPU、メモリ、OS情報等）
- コンテナランタイム: ランタイムバージョン情報
- ファイルシステム: ディスク容量情報
- Kubelet内部状態: ノード条件、イメージリスト、ボリューム制限

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Node.Status.Addresses | []v1.NodeAddress | ノードのネットワークアドレス |
| Node.Status.Capacity | v1.ResourceList | ノードリソース容量 |
| Node.Status.Allocatable | v1.ResourceList | 割り当て可能リソース量 |
| Node.Status.Conditions | []v1.NodeCondition | ノード条件一覧 |
| Node.Status.NodeInfo | v1.NodeSystemInfo | ノードシステム情報 |
| Node.Status.Images | []v1.ContainerImage | ノード上のイメージ一覧 |
| Node.Status.VolumesAttached | []v1.AttachedVolume | アタッチ済みボリューム |

### 出力先

- API Server（Node Status Subresource経由のPATCH更新）

## 処理フロー

### 処理シーケンス

```
1. ノード初期化（initialNode）
   └─ 初期ノードオブジェクト構築
2. API Serverへの登録（registerWithAPIServer）
   └─ exponential backoffで登録試行
3. ステータスSetters構成
   └─ 各Setter関数（アドレス、マシン情報、容量等）の設定
4. 定期ステータス更新（syncNodeStatus）
   └─ 全Settersの順次適用とAPI Serverへの報告
5. 差分更新
   └─ 前回報告との差分がある場合のみ更新を送信
```

### フローチャート

```mermaid
flowchart TD
    A[Kubelet起動] --> B[initialNode構築]
    B --> C[registerWithAPIServer]
    C --> D{登録成功?}
    D -->|No| E[exponential backoffで再試行]
    E --> C
    D -->|Yes| F[syncNodeStatusループ開始]
    F --> G[全Setters適用]
    G --> H{差分あり?}
    H -->|Yes| I[API Server PATCH更新]
    H -->|No| J[スキップ]
    I --> K[次回更新まで待機]
    J --> K
    K --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | 登録リトライ | exponential backoff（100ms起点、最大7秒）で登録再試行 | ノード登録失敗時 |
| BR-52-02 | 差分更新 | 前回ステータスと差分がある場合のみAPI更新を送信 | 定期更新時 |
| BR-52-03 | イメージ名数制限 | 1イメージあたり最大5名前をステータスに報告 | イメージ一覧更新時 |
| BR-52-04 | 容量計算 | Allocatable = Capacity - SystemReserved - KubeReserved - EvictionThreshold | 容量報告時 |

### 計算ロジック

- Allocatable = Capacity - SystemReserved - KubeReserved - EvictionThreshold（各リソースタイプごと）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ノード登録 | Node（etcd） | INSERT | 初回ノードオブジェクト作成 |
| ステータス更新 | Node.Status（etcd） | UPDATE | 定期的なステータスサブリソース更新 |

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

#### Nodeオブジェクト（etcd）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | Status.Addresses | ノードIP、ホスト名 | Setter: NodeAddress |
| UPDATE | Status.Conditions | Ready、各Pressure条件 | Setter: ReadyCondition等 |
| UPDATE | Status.Capacity | CPU、メモリ等の容量 | Setter: MachineInfo |
| UPDATE | Status.Images | イメージ一覧 | Setter: Images |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AlreadyExists | 正常系 | ノード既存時の登録試行 | 既存ノードとの調整（reconcile）を実行 |
| Forbidden | 権限エラー | ノード作成権限不足 | RBAC設定を確認 |
| NodeIPValidation | 設定エラー | 指定されたnode-ipが無効 | ノードIPの設定を確認 |

### リトライ仕様

- ノード登録: exponential backoff（100ms初期、最大7秒間隔）
- ステータス更新: nodeStatusUpdateFrequency間隔（デフォルト10秒）で継続再試行

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

API Serverへのステータス更新はoptimistic concurrency controlによるリソースバージョンベースの楽観的ロック。競合発生時は次回更新サイクルで再試行。

## パフォーマンス要件

- ステータス更新間隔: デフォルト10秒（nodeStatusUpdateFrequency）
- ステータスレポート間隔: デフォルト5分（nodeStatusReportFrequency）
- 差分検出による不要な更新の抑制

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

- NodeRestriction Admission Controllerにより、Kubeletは自ノードのステータスのみ更新可能
- クラウドプロバイダー連携時はアノテーションでノードIPを通知

## 備考

- 外部クラウドプロバイダー使用時はノードアドレスの管理方法が異なる
- Kubelet起動時にReboot イベントが一度だけ記録される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | setters.go | `pkg/kubelet/nodestatus/setters.go` | Setter型の定義、各Setter関数の構造 |

**読解のコツ**: Setter型は `func(ctx context.Context, node *v1.Node) error` という関数型。各Setter関数はクロージャパターンで設定値をキャプチャし、Setter関数を返す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kubelet_node_status.go | `pkg/kubelet/kubelet_node_status.go` | registerWithAPIServer、tryRegisterWithAPIServer |

**主要処理フロー**:
1. **52-82行目**: registerWithAPIServer - exponential backoffでのノード登録ループ
2. **89-94行目**: tryRegisterWithAPIServer - API ServerへのCreate/既存ノードとの調整

#### Step 3: Setter関数群を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | setters.go | `pkg/kubelet/nodestatus/setters.go` | NodeAddress、MachineInfo、ReadyCondition等の各Setter |

**主要処理フロー**:
- **64-83行目**: NodeAddress - ノードアドレス設定（IPv4/IPv6デュアルスタック対応）
- **53行目**: MaxNamesPerImageInNodeStatus = 5 - イメージ名数制限定数

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

```
Kubelet.Run()
    |
    +-- registerWithAPIServer()
    |       +-- initialNode()
    |       +-- tryRegisterWithAPIServer()
    |               +-- kubeClient.CoreV1().Nodes().Create()
    |
    +-- syncNodeStatus() [定期ループ]
            +-- setNodeStatus()
            |       +-- Setter: NodeAddress()
            |       +-- Setter: MachineInfo()
            |       +-- Setter: VersionInfo()
            |       +-- Setter: Images()
            |       +-- Setter: ReadyCondition()
            |       +-- Setter: VolumeLimits()
            |
            +-- patchNodeStatus()
                    +-- kubeClient.CoreV1().Nodes().PatchStatus()
```

### データフロー図

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

cAdvisor            ──▶  MachineInfo Setter   ──▶  Node.Status.Capacity
(CPU/メモリ/OS)                                      Node.Status.NodeInfo

ネットワーク設定     ──▶  NodeAddress Setter   ──▶  Node.Status.Addresses
(node-ip)

内部状態            ──▶  ReadyCondition Setter ──▶  Node.Status.Conditions
(Eviction等)

イメージキャッシュ   ──▶  Images Setter        ──▶  Node.Status.Images

                         patchNodeStatus()     ──▶  API Server (etcd)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kubelet_node_status.go | `pkg/kubelet/kubelet_node_status.go` | ソース | ノード登録、ステータス同期のメインロジック |
| setters.go | `pkg/kubelet/nodestatus/setters.go` | ソース | 各ステータスSetter関数の実装 |
| setters_test.go | `pkg/kubelet/nodestatus/setters_test.go` | テスト | Setter関数のユニットテスト |
