# 画面設計書 52-kubeadm upgrade

## 概要

本ドキュメントは、kubeadmツールの `kubeadm upgrade` コマンドに関する画面設計書である。Kubernetesクラスターのバージョンアップグレードを計画・実行・検証するための包括的なコマンド群を提供する。

### 本画面の処理概要

`kubeadm upgrade` コマンドは、Kubernetesクラスターのコントロールプレーンおよびワーカーノードのバージョンアップグレードを管理するためのCLIコマンドである。4つのサブコマンド（`apply`, `plan`, `diff`, `node`）を持ち、アップグレードの計画立案から実行、各ノードの更新までの一連のワークフローを提供する。

**業務上の目的・背景**：Kubernetesクラスターは定期的なバージョンアップグレードが必要であり、セキュリティパッチの適用や新機能の利用のために行われる。アップグレードはコントロールプレーンコンポーネント（kube-apiserver、kube-controller-manager、kube-scheduler、etcd）、DNS（CoreDNS）、kubelet等の多数のコンポーネントに影響するため、計画的かつ安全に実行する必要がある。本コマンドは、事前のアップグレード可能性チェック、ドライラン、差分確認、実際のアップグレード実行、およびノード単位の更新を段階的に行えるようにすることで、クラスター運用者の安全なアップグレード作業を支援する。

**画面へのアクセス方法**：ターミナル上で `kubeadm upgrade <サブコマンド>` を実行する。コントロールプレーンノード上で実行する必要があり、`admin.conf` kubeconfigファイルへのアクセスが必要。

**主要な操作・処理内容**：
1. `kubeadm upgrade plan [version]` - アップグレード可能なバージョンを確認し、現在のクラスターがアップグレード可能かを検証
2. `kubeadm upgrade apply <version>` - 指定バージョンへのコントロールプレーンのアップグレードを実行
3. `kubeadm upgrade diff [version]` - アップグレード時のstatic podマニフェストの差分を表示
4. `kubeadm upgrade node` - 個別ノードのアップグレード処理を実行（コントロールプレーンノードとワーカーノードの両方に対応）

**画面遷移**：典型的なアップグレードワークフローでは、`plan` で確認 -> `apply` でコントロールプレーン更新 -> 各ノードで `node` を実行する。`diff` はオプションとして事前確認に利用する。アップグレード完了後は `kubectl get nodes` 等で結果を確認する。

**権限による表示制御**：全サブコマンドでroot権限が必要。`plan` と `apply` ではコントロールプレーンノードの `admin.conf` へのアクセスが必須。`node` はワーカーノードでは `kubelet.conf` へのアクセスで動作可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 120 | クラスターアップグレード | 主機能 | Kubernetesクラスターのバージョンアップグレードを管理する主処理 |
| 121 | 証明書管理 | 補助機能 | アップグレード時に証明書の更新を行う |
| 1 | API Serverコア | API連携 | アップグレード中にAPI Serverの設定更新を行う |

## 画面種別

CLIコマンド（クラスターアップグレード管理）

## URL/ルーティング

```
kubeadm upgrade plan [version] [flags]
kubeadm upgrade apply [version] [flags]
kubeadm upgrade diff [version] [flags]
kubeadm upgrade node [flags]
```

## 入出力項目

### kubeadm upgrade apply

| 項目名 | 入出力 | 必須 | 型 | デフォルト値 | 説明 |
|--------|--------|------|-----|-------------|------|
| version (引数) | 入力 | 条件付必須 | string | - | アップグレード先のKubernetesバージョン。設定ファイルで指定されていない場合は必須 |
| --kubeconfig | 入力 | 任意 | string | /etc/kubernetes/admin.conf | kubeconfigファイルのパス |
| --config | 入力 | 任意 | string | "" | kubeadm設定ファイルのパス |
| --yes / -y | 入力 | 任意 | bool | false | 確認プロンプトをスキップ（非対話モード） |
| --force / -f | 入力 | 任意 | bool | false | 要件を満たさなくても強制アップグレード |
| --dry-run | 入力 | 任意 | bool | false | 実際の変更を行わず、実行予定の操作を出力 |
| --certificate-renewal | 入力 | 任意 | bool | true | アップグレード中の証明書更新を行うか |
| --etcd-upgrade | 入力 | 任意 | bool | true | etcdのアップグレードを行うか |
| --allow-experimental-upgrades | 入力 | 任意 | bool | false | alpha/beta/rcバージョンへのアップグレードを許可 |
| --allow-release-candidate-upgrades | 入力 | 任意 | bool | false | rcバージョンへのアップグレードを許可 |
| --print-config | 入力 | 任意 | bool | false | アップグレードに使用する設定を出力 |
| --patches | 入力 | 任意 | string | "" | コンポーネントパッチファイルのディレクトリ |
| --ignore-preflight-errors | 入力 | 任意 | []string | [] | 無視するプリフライトチェックエラーのリスト |
| アップグレード結果 | 出力 | - | text | - | アップグレードの成功・失敗メッセージ |

### kubeadm upgrade plan

| 項目名 | 入出力 | 必須 | 型 | デフォルト値 | 説明 |
|--------|--------|------|-----|-------------|------|
| version (引数) | 入力 | 任意 | string | - | チェック対象のバージョン（省略時はインターネットから最新版を確認） |
| --kubeconfig | 入力 | 任意 | string | /etc/kubernetes/admin.conf | kubeconfigファイルのパス |
| --config | 入力 | 任意 | string | "" | kubeadm設定ファイルのパス |
| -o / --output | 入力 | 任意 | string | text | 出力フォーマット（text / json / yaml） |
| アップグレード計画 | 出力 | - | text/json/yaml | - | 利用可能なアップグレードバージョンとコンポーネント情報 |

### kubeadm upgrade diff

| 項目名 | 入出力 | 必須 | 型 | デフォルト値 | 説明 |
|--------|--------|------|-----|-------------|------|
| version (引数) | 入力 | 条件付必須 | string | - | 差分比較対象のバージョン |
| --kubeconfig | 入力 | 任意 | string | /etc/kubernetes/admin.conf | kubeconfigファイルのパス |
| --config | 入力 | 任意 | string | "" | kubeadm設定ファイルのパス |
| -c / --context-lines | 入力 | 任意 | int | 3 | 差分表示のコンテキスト行数 |
| 差分出力 | 出力 | - | unified diff | - | static podマニフェストの差分 |

### kubeadm upgrade node

| 項目名 | 入出力 | 必須 | 型 | デフォルト値 | 説明 |
|--------|--------|------|-----|-------------|------|
| --kubeconfig | 入力 | 任意 | string | 自動判定 | kubeconfigファイルのパス。コントロールプレーンではadmin.conf、ワーカーではkubelet.conf |
| --config | 入力 | 任意 | string | "" | kubeadm設定ファイルのパス |
| --dry-run | 入力 | 任意 | bool | false | 実際の変更を行わず出力のみ |
| --certificate-renewal | 入力 | 任意 | bool | true | 証明書の更新を行うか |
| --etcd-upgrade | 入力 | 任意 | bool | true | etcdのアップグレードを行うか |
| --patches | 入力 | 任意 | string | "" | パッチファイルのディレクトリ |
| --ignore-preflight-errors | 入力 | 任意 | []string | [] | 無視するプリフライトエラー |

## 表示項目

### upgrade plan 出力

| 項目名 | 説明 |
|--------|------|
| COMPONENT | コンポーネント名（kubelet, kube-apiserver, kube-controller-manager, kube-scheduler, kube-proxy, CoreDNS, etcd, kubeadm） |
| NODE | 対象ノード名 |
| CURRENT | 現在のバージョン |
| TARGET | アップグレード先バージョン |
| API GROUP | コンポーネント設定のAPIグループ |
| CURRENT VERSION | 設定の現在バージョン |
| PREFERRED VERSION | 推奨バージョン |
| MANUAL UPGRADE REQUIRED | 手動アップグレードが必要かどうか |

### upgrade diff 出力

| 項目名 | 説明 |
|--------|------|
| unified diff | kube-apiserver、kube-controller-manager、kube-schedulerの各static podマニフェストのunified diff形式の差分 |

## イベント仕様

### 1-upgrade plan 実行

1. クラスターの健全性チェック（`enforceRequirements`）
2. Kubernetes clientの作成とプリフライトチェック実行
3. クラスターから現在の設定情報を取得（`FetchInitConfigurationFromCluster`）
4. 利用可能なアップグレードバージョンを計算（`upgrade.GetAvailableUpgrades`）
5. コンポーネント設定のバージョン状態を取得（`componentconfigs.GetVersionStates`）
6. アップグレード計画を生成・出力

### 2-upgrade apply 実行

ワークフローベースの段階的実行:
1. **Preflight Phase**: プリフライトチェック（クラスター健全性、バージョン互換性）
2. **Control Plane Phase**: コントロールプレーンコンポーネント（static pod）の更新
3. **Upload Config Phase**: 更新後の設定をConfigMapにアップロード
4. **Kubeconfig Phase**: kubeconfigファイルの更新
5. **Kubelet Config Phase**: kubelet設定の更新
6. **Bootstrap Token Phase**: ブートストラップトークンの更新
7. **Addon Phase**: アドオン（CoreDNS、kube-proxy）の更新
8. **Post Upgrade Phase**: アップグレード後処理

### 3-upgrade diff 実行

1. 現在のstatic podマニフェストファイルの存在確認
2. クラスターから設定情報を取得
3. 指定バージョンのstatic pod仕様を生成（`controlplane.GetStaticPodSpecs`）
4. 現在のマニフェストと新しいマニフェストのunified diffを出力

### 4-upgrade node 実行

ワークフローベースの段階的実行:
1. **Preflight Phase**: プリフライトチェック
2. **Control Plane Phase**: コントロールプレーンノードの場合のstatic pod更新
3. **Kubeconfig Phase**: kubeconfigの更新
4. **Kubelet Config Phase**: kubelet設定の更新
5. **Addon Phase**: アドオンの更新
6. **Post Upgrade Phase**: アップグレード後処理

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| upgrade plan実行 | なし | SELECT | クラスター設定の読み取りのみ |
| upgrade apply実行 | ConfigMap (kubeadm-config) | UPDATE | アップグレード後の設定を反映 |
| upgrade apply実行 | Static Podマニフェスト | UPDATE | コントロールプレーンのstatic podマニフェストを更新 |
| upgrade apply実行 | DaemonSet (kube-proxy) | UPDATE | kube-proxyのイメージバージョンを更新 |
| upgrade apply実行 | Deployment (coredns) | UPDATE | CoreDNSのイメージバージョンを更新 |
| upgrade diff実行 | なし | SELECT | 差分比較のための読み取りのみ |
| upgrade node実行 | Static Podマニフェスト | UPDATE | ノードのstatic podマニフェストを更新 |
| upgrade node実行 | kubelet設定 | UPDATE | kubelet設定ファイルを更新 |

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|----------|------|
| 成功 | `[upgrade] SUCCESS! A control plane node of your cluster was upgraded to "%s".` | upgrade apply成功時 |
| 成功 | `[upgrade] Now please proceed with upgrading the rest of the nodes by following the right order.` | upgrade apply成功後の案内 |
| 成功 | `[upgrade/successful] Finished dryrunning successfully!` | dry-run成功時 |
| 情報 | `Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':` | plan出力時のkubelet手動アップグレード案内 |
| 情報 | `You can now apply the upgrade by executing the following command:` | plan出力時のapplyコマンド案内 |
| 情報 | `Note: Before you can perform this upgrade, you have to update kubeadm to %s.` | kubeadm自体のアップグレードが先に必要な場合 |
| エラー | `the ConfigMap "%s" in the "%s" namespace was not found` | kubeadm-config ConfigMapが存在しない場合 |
| エラー | `[upgrade/health] FATAL` | クラスター健全性チェック失敗時 |
| エラー | `[upgrade/versions] FATAL` | バージョン取得失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| クラスターへの接続失敗 | kubeconfigファイルからのクライアント生成失敗としてエラー返却 |
| プリフライトチェック失敗 | エラーを表示。`--ignore-preflight-errors` で特定チェックをスキップ可能 |
| kubeadm-config ConfigMap未存在 | 再アップロードの手順を案内して終了 |
| クラスター健全性チェック失敗 | `[upgrade/health] FATAL` エラーを表示 |
| バージョン引数未指定（apply時） | 設定ファイルにも未指定の場合はエラー |
| static podマニフェスト未存在（diff時） | マニフェストファイルが存在しないエラーを返却 |
| dry-run時 | 一時ディレクトリを作成し、そこにファイルを出力。クラスターへの実際の変更なし |

## 備考

- `upgrade apply` はワークフローランナー（`workflow.Runner`）を使用し、各フェーズを段階的に実行する
- `--skip-phases` フラグで特定フェーズをスキップ可能
- `upgrade node` はコントロールプレーンノードとワーカーノードの両方で動作し、ノード種別を自動判定する
- `upgrade plan` の出力は `--output` フラグで text / json / yaml 形式を選択可能
- dry-run時はfakeクライアントを使用し、実際のAPI Serverへの変更を行わない
- 設定はフラグと設定ファイルの両方から読み込み可能で、フラグが設定ファイルより優先される

---

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

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

### 推奨読解順序

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

アップグレード処理で使用される設定・データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | upgrade.go | `cmd/kubeadm/app/cmd/upgrade/upgrade.go` | `applyPlanFlags` 構造体（31-41行目）: apply/plan共通のフラグを保持 |
| 1-2 | apply.go | `cmd/kubeadm/app/cmd/upgrade/apply.go` | `applyFlags` 構造体（47-55行目）と `applyData` 構造体（62-78行目）: applyワークフローのランタイム情報 |
| 1-3 | node.go | `cmd/kubeadm/app/cmd/upgrade/node.go` | `nodeOptions` 構造体（48-56行目）と `nodeData` 構造体（63-76行目）: nodeワークフローのランタイム情報 |
| 1-4 | diff.go | `cmd/kubeadm/app/cmd/upgrade/diff.go` | `diffFlags` 構造体（47-56行目）: diff処理のフラグ |

**読解のコツ**: `applyData` と `nodeData` は `workflow.RunData` インタフェースを実装しており、ワークフローの各フェーズがこのデータにアクセスする。

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

親コマンドとサブコマンドの登録構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | upgrade.go | `cmd/kubeadm/app/cmd/upgrade/upgrade.go` | `NewCmdUpgrade()` 関数（44-67行目）: 親コマンドの定義と4つのサブコマンド（apply, plan, diff, node）の登録 |

**主要処理フロー**:
1. **44-54行目**: `applyPlanFlags` のデフォルト値設定
2. **56-59行目**: `upgrade` コマンドの定義
3. **62-66行目**: サブコマンドの追加

#### Step 3: upgrade apply の処理を理解する

コントロールプレーンのアップグレード実行ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | apply.go | `cmd/kubeadm/app/cmd/upgrade/apply.go` | `newCmdApply()` 関数（81-160行目）: applyコマンドの定義とワークフローフェーズの登録 |
| 3-2 | apply.go | `cmd/kubeadm/app/cmd/upgrade/apply.go` | `newApplyData()` 関数（163-298行目）: 設定読み込み、バージョン解決、クライアント作成 |

**主要処理フロー**:
- **87-88行目**: ワークフローランナーの初期化とデータ初期化
- **132-139行目**: フェーズの登録（Preflight -> ControlPlane -> UploadConfig -> Kubeconfig -> KubeletConfig -> BootstrapToken -> Addon -> PostUpgrade）
- **163-298行目**: `newApplyData` でUpgradeConfigurationのロード、バージョン引数の処理、クライアント作成、クラスター設定の取得

#### Step 4: upgrade plan の処理を理解する

アップグレード計画表示のロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | plan.go | `cmd/kubeadm/app/cmd/upgrade/plan.go` | `newCmdPlan()` 関数（58-87行目）: planコマンドの定義 |
| 4-2 | plan.go | `cmd/kubeadm/app/cmd/upgrade/plan.go` | `runPlan()` 関数（100-148行目）: 利用可能なアップグレードの計算と出力 |
| 4-3 | plan.go | `cmd/kubeadm/app/cmd/upgrade/plan.go` | `genUpgradePlan()` 関数（151-157行目）と `genAvailableUpgrade()` 関数（183-233行目）: 各コンポーネントのアップグレード情報生成 |

#### Step 5: upgrade diff の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | diff.go | `cmd/kubeadm/app/cmd/upgrade/diff.go` | `newCmdDiff()` 関数（59-91行目）: diffコマンドの定義 |
| 5-2 | diff.go | `cmd/kubeadm/app/cmd/upgrade/diff.go` | `runDiff()` 関数（112-196行目）: static podマニフェストの差分計算とunified diff出力 |

#### Step 6: upgrade node の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | node.go | `cmd/kubeadm/app/cmd/upgrade/node.go` | `newCmdNode()` 関数（79-144行目）: nodeコマンドの定義とワークフローフェーズの登録 |
| 6-2 | node.go | `cmd/kubeadm/app/cmd/upgrade/node.go` | `newNodeData()` 関数（167-241行目）: ノード種別の自動判定、設定ロード |

#### Step 7: 共通処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | common.go | `cmd/kubeadm/app/cmd/upgrade/common.go` | `enforceRequirements()` 関数（52-159行目）: plan/apply共通の前提条件チェック |
| 7-2 | common.go | `cmd/kubeadm/app/cmd/upgrade/common.go` | `getClient()` 関数（190-245行目）: dry-run時のfakeクライアント生成 |

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

```
kubeadm upgrade
    |
    +-- NewCmdUpgrade() [upgrade.go:44]
            |
            +-- newCmdApply() [apply.go:81]
            |       |
            |       +-- workflow.NewRunner()
            |       +-- phases: Preflight -> ControlPlane -> UploadConfig
            |       |           -> Kubeconfig -> KubeletConfig -> BootstrapToken
            |       |           -> Addon -> PostUpgrade
            |       +-- newApplyData() [apply.go:163]
            |               +-- configutil.LoadOrDefaultUpgradeConfiguration()
            |               +-- getClient() [common.go:190]
            |               +-- configutil.FetchInitConfigurationFromCluster()
            |
            +-- newCmdPlan() [plan.go:58]
            |       |
            |       +-- runPlan() [plan.go:100]
            |               +-- enforceRequirements() [common.go:52]
            |               +-- upgrade.GetAvailableUpgrades()
            |               +-- componentconfigs.GetVersionStates()
            |               +-- genUpgradePlan() [plan.go:151]
            |
            +-- newCmdDiff() [diff.go:59]
            |       |
            |       +-- runDiff() [diff.go:112]
            |               +-- configutil.LoadOrDefaultUpgradeConfiguration()
            |               +-- FetchInitConfigurationFromCluster()
            |               +-- controlplane.GetStaticPodSpecs()
            |               +-- difflib.WriteUnifiedDiff()
            |
            +-- newCmdNode() [node.go:79]
                    |
                    +-- workflow.NewRunner()
                    +-- phases: Preflight -> ControlPlane -> Kubeconfig
                    |           -> KubeletConfig -> Addon -> PostUpgrade
                    +-- newNodeData() [node.go:167]
                            +-- staticpodutil.IsControlPlaneNode()
                            +-- configutil.LoadOrDefaultUpgradeConfiguration()
                            +-- getClient() [common.go:190]
```

### データフロー図

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

                    +----- upgrade plan -----+
[version arg] ─────>| enforceRequirements() |
[--kubeconfig] ────>| GetAvailableUpgrades()|──> アップグレード計画表示
[--config] ────────>| GetVersionStates()    |
                    +-----------------------+

                    +----- upgrade apply ----+
[version arg] ─────>| newApplyData()        |
[各種フラグ] ──────>| workflow.Run()        |──> static pod更新
                    |  Preflight            |──> ConfigMap更新
                    |  ControlPlane         |──> kubeconfig更新
                    |  UploadConfig         |──> kubelet設定更新
                    |  Kubeconfig           |──> アドオン更新
                    |  KubeletConfig        |
                    |  BootstrapToken       |
                    |  Addon                |
                    |  PostUpgrade          |
                    +-----------------------+

                    +----- upgrade diff -----+
[version arg] ─────>| runDiff()             |
[--context-lines] ─>| GetStaticPodSpecs()   |──> unified diff出力
                    | WriteUnifiedDiff()     |
                    +-----------------------+

                    +----- upgrade node -----+
[各種フラグ] ──────>| newNodeData()         |
                    | workflow.Run()         |──> ノード設定更新
                    |  (各フェーズ実行)      |
                    +-----------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| upgrade.go | `cmd/kubeadm/app/cmd/upgrade/upgrade.go` | ソース | 親コマンド定義・共通フラグ |
| apply.go | `cmd/kubeadm/app/cmd/upgrade/apply.go` | ソース | upgrade applyコマンド実装 |
| plan.go | `cmd/kubeadm/app/cmd/upgrade/plan.go` | ソース | upgrade planコマンド実装 |
| diff.go | `cmd/kubeadm/app/cmd/upgrade/diff.go` | ソース | upgrade diffコマンド実装 |
| node.go | `cmd/kubeadm/app/cmd/upgrade/node.go` | ソース | upgrade nodeコマンド実装 |
| common.go | `cmd/kubeadm/app/cmd/upgrade/common.go` | ソース | 共通処理（enforceRequirements, getClient等） |
| workflow/ | `cmd/kubeadm/app/cmd/phases/workflow/` | ソース | ワークフローランナーフレームワーク |
| upgrade/apply/ | `cmd/kubeadm/app/cmd/phases/upgrade/apply/` | ソース | applyワークフローの各フェーズ実装 |
| upgrade/node/ | `cmd/kubeadm/app/cmd/phases/upgrade/node/` | ソース | nodeワークフローの各フェーズ実装 |
| upgrade/ | `cmd/kubeadm/app/phases/upgrade/` | ソース | アップグレードロジック（GetAvailableUpgrades等） |
| controlplane/ | `cmd/kubeadm/app/phases/controlplane/` | ソース | static pod仕様の生成 |
| componentconfigs/ | `cmd/kubeadm/app/componentconfigs/` | ソース | コンポーネント設定のバージョン管理 |
| config/ | `cmd/kubeadm/app/util/config/` | ソース | 設定ファイルのロード・マーシャル |
