# 機能設計書 119-ノード参加（join）

## 概要

本ドキュメントは、kubeadm joinコマンドの設計を記述する。既存のKubernetesクラスターに新しいワーカーノードまたはコントロールプレーンノードを参加させる。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターの拡張においてノードの追加は頻繁に行われる操作である。kubeadm joinは、クラスターとの信頼関係の確立（Discovery）、TLSブートストラップ、kubeletの設定を自動化し、ノードのクラスターへの安全な参加を実現する。

**機能の利用シーン**：ワーカーノードをクラスターに追加する場合、HA構成のために追加のコントロールプレーンノードを追加する場合に使用する。

**主要な処理内容**：
1. **Preflight** - システム要件の事前チェック
2. **ControlPlanePrepare** - コントロールプレーン参加の準備（コントロールプレーン参加時のみ）
3. **CheckEtcd** - etcdの状態確認（コントロールプレーン参加時のみ）
4. **KubeletStart** - kubeletの設定と起動
5. **EtcdJoin** - etcdクラスターへの参加（コントロールプレーン参加時のみ）
6. **KubeletWaitBootstrap** - kubelet TLSブートストラップの完了待機
7. **ControlPlaneJoin** - コントロールプレーンの参加処理（コントロールプレーン参加時のみ）
8. **WaitControlPlane** - コントロールプレーンの起動完了待機

**関連システム・外部連携**：API Server（Discovery、TLS Bootstrap）、kubelet、etcd、CRI

**権限による制御**：root権限が必要。Discoveryにはブートストラップトークンまたはkubeconfigが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIコマンドのため画面なし |

## 機能種別

クラスター拡張 / ワークフロー実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| [api-server-endpoint] | string | No* | API Serverのエンドポイント | 引数として指定 |
| --token | string | No | Discovery + TLSブートストラップ兼用トークン | - |
| --discovery-token | string | No | Discovery用トークン | - |
| --discovery-token-ca-cert-hash | []string | No | CAのSPKIハッシュ | sha256:<hex>形式 |
| --discovery-token-unsafe-skip-ca-verification | bool | No | CA検証スキップ | - |
| --discovery-file | string | No | Discoveryファイルパス | ファイルパスまたはHTTPS URL |
| --tls-bootstrap-token | string | No | TLSブートストラップ用トークン | - |
| --control-plane | bool | No | コントロールプレーンノードとして参加 | - |
| --certificate-key | string | No | 証明書復号キー | AES 32バイト |
| --apiserver-advertise-address | string | No | API Serverの広告アドレス | コントロールプレーン参加時 |
| --apiserver-bind-port | int32 | No | API Serverバインドポート | コントロールプレーン参加時 |
| --node-name | string | No | ノード名 | - |
| --cri-socket | string | No | CRIソケットパス | - |
| --config | string | No | 設定ファイルパス | ファイルの存在 |
| --dry-run | bool | No | ドライラン | - |
| --ignore-preflight-errors | []string | No | 無視するプレフライトエラー | - |
| --patches | string | No | パッチディレクトリ | ディレクトリパス |

### 入力データソース

- API Server（Discoveryプロセスでクラスター情報を取得）
- 設定ファイル（JoinConfiguration）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 参加完了メッセージ | string | ワーカー/コントロールプレーン参加の成功メッセージ |
| kubeconfig案内 | string | コントロールプレーン参加時のkubeconfig設定手順 |

### 出力先

標準出力（メッセージ）、/etc/kubernetes/（証明書、kubeconfig、マニフェスト）

## 処理フロー

### 処理シーケンス

```
1. joinOptionsの構築
   └─ newJoinOptions()でデフォルト値設定
2. 設定の読み込みと検証
   └─ newJoinData()で設定のロード・検証
      ├─ トークンの処理（--tokenが--discovery-tokenと--tls-bootstrap-tokenを兼用）
      ├─ DiscoveryFileの処理
      ├─ BootstrapTokenの処理
      └─ --control-planeフラグの処理
3. ワークフロー実行（8フェーズ）
   └─ joinRunner.Run()で順次実行
4. 完了メッセージの出力
   └─ ワーカーorコントロールプレーンに応じたメッセージ
```

### フローチャート

```mermaid
flowchart TD
    A[kubeadm join] --> B[設定読み込み・検証]
    B --> C[Preflight チェック]
    C --> D{control-plane?}
    D -->|Yes| E[ControlPlanePrepare]
    D -->|No| F[KubeletStart]
    E --> G[CheckEtcd]
    G --> F
    F --> H{control-plane?}
    H -->|Yes| I[EtcdJoin]
    H -->|No| J[KubeletWaitBootstrap]
    I --> J
    J --> K{control-plane?}
    K -->|Yes| L[ControlPlaneJoin]
    K -->|No| M[完了メッセージ]
    L --> N[WaitControlPlane]
    N --> O[コントロールプレーン参加メッセージ]
    M --> P[終了]
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-119-01 | Discovery方式 | トークンベースとファイルベースの2つのDiscovery方式をサポート | 常時 |
| BR-119-02 | CA検証 | トークンDiscovery時は--discovery-token-ca-cert-hashによるCA検証を推奨 | トークンDiscovery時 |
| BR-119-03 | トークン兼用 | --tokenは--discovery-tokenと--tls-bootstrap-tokenの両方に使用される | --tokenのみ指定時 |
| BR-119-04 | control-plane必須フラグ警告 | --control-planeなしでコントロールプレーン関連フラグを使用すると警告 | --control-plane未指定時 |
| BR-119-05 | admin.conf優先 | admin.confが存在する場合はDiscoveryをスキップ | コントロールプレーン参加時 |
| BR-119-06 | 双方向信頼 | Discovery（ノード→CP信頼）とTLSブートストラップ（CP→ノード信頼）の双方向 | 常時 |
| BR-119-07 | HTTPS必須 | Discovery URLはHTTPSのみサポート | ファイルDiscovery URL時 |

### 計算ロジック

特になし

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

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

| 操作 | リソース | 説明 |
|------|---------|------|
| Read | ConfigMap (kubeadm-config) | クラスター設定の読み取り |
| Read | ConfigMap (cluster-info) | Discoveryプロセスでクラスター情報取得 |
| Create | CSR | kubelet証明書署名要求の作成 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Discovery失敗 | API Serverへの接続失敗/トークン無効 | エンドポイントとトークンの確認 |
| - | CA検証失敗 | CA証明書ハッシュ不一致 | 正しいハッシュ値の使用 |
| - | PreflightError | システム要件未達 | --ignore-preflight-errorsで無視可能 |
| - | ControlPlaneフラグ警告 | --control-planeなしでCP関連フラグ使用 | --control-planeフラグの追加 |

### リトライ仕様

リトライなし（フェーズ単位での再実行が可能）

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

各フェーズは順序的に実行される。途中失敗時は`kubeadm reset`で環境クリーンアップ後に再実行する。

## パフォーマンス要件

DiscoveryプロセスとTLSブートストラップにはネットワーク通信が必要であり、ネットワーク環境に依存する。

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

- --discovery-token-unsafe-skip-ca-verificationはセキュリティモデルを弱化させる（MITM攻撃のリスク）
- ブートストラップトークンにはTTLが設定されており、期限切れトークンは使用不可
- 証明書復号キーは安全な経路で共有すること

## 備考

- kubeadm init実行時に表示されるjoinコマンドをそのまま使用するのが最も簡単
- HA構成ではすべてのコントロールプレーンノードが同じ--control-plane-endpointを使用すること

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | join.go | `cmd/kubeadm/app/cmd/join.go` | joinOptions構造体（134-143行目）、joinData構造体（150-160行目） |

**読解のコツ**: joinDataはinitCfgフィールド（*kubeadmapi.InitConfiguration）を持つ。これはDiscoveryプロセスでクラスターからフェッチされた設定で、joinワークフローの各フェーズで使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | join.go | `cmd/kubeadm/app/cmd/join.go` | newCmdJoin（165-255行目）でフェーズ登録とRunner構築 |

**主要処理フロー**:
1. **169行目**: ワークフローRunnerの作成
2. **222-229行目**: 8フェーズの登録
3. **233-248行目**: DataInitializerの設定
4. **252行目**: RunnerをCobraコマンドにバインド

#### Step 3: 設定の読み込みと検証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | join.go | `cmd/kubeadm/app/cmd/join.go` | newJoinData（349-485行目）で設定のロード・検証 |

**主要処理フロー**:
- **363-370行目**: トークンの処理（兼用ロジック）
- **373-385行目**: DiscoveryFile/BootstrapTokenの処理
- **388-406行目**: --control-planeフラグの処理
- **410-418行目**: admin.conf存在時のDiscoveryスキップ

#### Step 4: Discoveryプロセスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | join.go | `cmd/kubeadm/app/cmd/join.go` | TLSBootstrapCfg（538-557行目）とInitCfg（560-579行目）でDiscovery実行 |

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

```
newCmdJoin()
    │
    └─ workflow.NewRunner()
           │
           ├─ AppendPhase(PreflightPhase)
           ├─ AppendPhase(ControlPlanePreparePhase)
           ├─ AppendPhase(CheckEtcdPhase)
           ├─ AppendPhase(KubeletStartPhase)
           ├─ AppendPhase(EtcdJoinPhase)
           ├─ AppendPhase(KubeletWaitBootstrapPhase)
           ├─ AppendPhase(ControlPlaneJoinPhase)
           └─ AppendPhase(WaitControlPlanePhase)

newJoinData()
    ├─ validation.ValidateMixedArguments()
    ├─ configutil.LoadOrDefaultJoinConfiguration()
    └─ validation.ValidateIgnorePreflightErrors()

joinData.TLSBootstrapCfg()
    └─ discovery.For()

joinData.InitCfg()
    └─ fetchInitConfigurationFromJoinConfiguration()
           ├─ kubeconfigutil.ToClientSet()
           ├─ fetchInitConfiguration()
           │      └─ configutil.FetchInitConfigurationFromCluster()
           └─ kubeconfigutil.GetClusterFromKubeConfig()
```

### データフロー図

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

APIエンドポイント ──▶ Discovery (token/file)
  + トークン               │
                    TLSBootstrapCfg取得
                          │
                    InitConfiguration取得
                          │
              ┌───────────┼───────────┐
              │           │           │
      [ワーカー]    [コントロールプレーン]
              │           │
     KubeletStart   ControlPlane処理
              │           │
              ▼           ▼
        参加完了      CP参加完了
         メッセージ    メッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| join.go | `cmd/kubeadm/app/cmd/join.go` | ソース | joinコマンドの主要ロジック |
| phases/join/ | `cmd/kubeadm/app/cmd/phases/join/` | ソース | 各フェーズの実装 |
| discovery/ | `cmd/kubeadm/app/discovery/` | ソース | Discoveryプロセス |
| discovery/token/ | `cmd/kubeadm/app/discovery/token/` | ソース | トークンベースDiscovery |
| workflow/ | `cmd/kubeadm/app/cmd/phases/workflow/` | ソース | ワークフローRunner |
