# 機能設計書 99-デバッグ（debug）

## 概要

本ドキュメントは、kubectl debugコマンドによるインタラクティブデバッグ機能の設計を記述する。

### 本機能の処理概要

kubectl debugコマンドは、Podやノードに対してデバッグ用コンテナを追加し、インタラクティブなトラブルシューティングを行うCLI機能である。3つのデバッグスタイル（エフェメラルコンテナ、Podコピー、ノードデバッグ）をサポートする。

**業務上の目的・背景**：プロダクション環境で動作中のPodやノードのトラブルシューティングを、ワークロードを再起動することなく実行するために利用される。軽量なデバッグイメージを使用してネットワーク、プロセス、ファイルシステムの調査が可能。

**機能の利用シーン**：動作中Podへのデバッグツール追加（strace, tcpdump等）、Podコピーによるイメージ変更デバッグ、ノードのホストネームスペースでの調査、コンテナクラッシュ時の原因調査。

**主要な処理内容**：
1. ターゲット（Pod/Node）の特定
2. デバッグスタイルの決定（エフェメラルコンテナ/コピー/ノード）
3. プロファイルに基づくセキュリティコンテキストの適用
4. デバッグコンテナの追加またはPodコピーの作成
5. オプションでインタラクティブアタッチ

**関連システム・外部連携**：EphemeralContainer APIを使用。attach/exec/logsコマンドの機能を内部利用。

**権限による制御**：pods/ephemeralcontainersのupdate権限（エフェメラルコンテナ時）、podsのcreate権限（コピー/ノードデバッグ時）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | kubectl debug | 主機能 | デバッグコンテナの追加・Podコピー・ノードデバッグ |

## 機能種別

デバッグ・トラブルシューティング / Pod/Node操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| POD/TYPE/NAME | string | Yes | デバッグ対象のPod/Node名 | 有効なリソース名 |
| --image | string | Yes(copy-to未使用時) | デバッグコンテナイメージ | 有効なイメージ参照 |
| --container / -c | string | No | デバッグコンテナ名 | DNS-1123形式 |
| --copy-to | string | No | Podコピー時の新Pod名 | DNS-1123形式 |
| --replace | bool | No | コピー後に元Podを削除 | --copy-to時のみ |
| --same-node | bool | No | 同一ノードにスケジュール | --copy-to時のみ |
| --set-image | map | No | コンテナイメージの変更 | name=image形式 |
| --target | string | No | プロセス共有のターゲットコンテナ | --copy-to非使用時のみ |
| --share-processes | bool | No | プロセス名前空間の共有 | --copy-to時のみ |
| -i / --stdin | bool | No | stdinをオープンに保持 | - |
| -t / --tty | bool | No | TTY割り当て | -i必須 |
| --attach | bool | No | 作成後にアタッチ | -i時デフォルトtrue |
| --env | map | No | 環境変数 | key=value形式 |
| --profile | string | No | セキュリティプロファイル | general/baseline/restricted/netadmin/sysadmin |
| --custom | string | No | カスタムプロファイルJSONファイル | 有効なJSONパス |
| --arguments-only | bool | No | -- 以降をArgsとして使用 | - |
| --image-pull-policy | string | No | イメージプルポリシー | Always/IfNotPresent/Never |
| -q / --quiet | bool | No | メッセージ抑制 | - |
| --keep-labels | bool | No | 元Podのラベルを保持 | --copy-to時のみ |
| --keep-annotations | bool | No | 元Podのアノテーションを保持 | --copy-to時のみ |
| --keep-liveness | bool | No | 元Podのlivenessプローブを保持 | --copy-to時のみ |
| --keep-readiness | bool | No | 元Podのreadinessプローブを保持 | --copy-to時のみ |
| --keep-startup | bool | No | 元Podのstartupプローブを保持 | --copy-to時のみ |
| --keep-init-containers | bool | No | initコンテナを実行（デフォルトtrue） | --copy-to時のみ |

### 入力データソース

CLI引数、カスタムプロファイルJSONファイル、kubeconfig

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| デバッグ情報 | string | "Defaulting debug container name to xxx" 等のメッセージ |
| アタッチ出力 | stream | デバッグコンテナのstdin/stdout/stderr |
| 警告メッセージ | string | 非rootユーザーへの警告等 |

### 出力先

標準出力（stdout）、標準エラー出力（stderr）

## 処理フロー

### 処理シーケンス

```
1. Complete: 引数と環境の初期化
   ├─ PullPolicy設定
   ├─ ターゲット名とArgs分離
   ├─ Attach/AttachFunc設定
   ├─ 環境変数パース
   ├─ ProfileApplier生成
   ├─ カスタムプロファイル読み込み
   └─ podClient設定

2. Validate: 入力パラメータの検証
   ├─ --attach時はimage/container必須
   ├─ --copy-to時はimage/set-image/args必須
   ├─ --replace/--same-node/--set-imageは--copy-to時のみ
   ├─ --targetは--copy-to非使用時のみ
   ├─ カスタムプロファイル制限（name, command, image等不可）
   └─ legacyプロファイル非推奨警告

3. Run: デバッグ実行
   ├─ resource.Builderでターゲット取得
   ├─ Visit: リソースタイプに応じた処理分岐
   │   ├─ Node: visitNode → generateNodeDebugPod
   │   └─ Pod: visitPod
   │       ├─ copy-to指定時: debugByCopy → generatePodCopyWithDebugContainer
   │       └─ copy-to未指定時: debugByEphemeralContainer → generateDebugContainer
   ├─ ProfileApplier.Apply(): プロファイル適用
   ├─ CustomProfile適用（指定時）
   └─ [attach] handleAttachPod: アタッチ
```

### 3つのデバッグスタイル

| スタイル | 条件 | 処理内容 |
|---------|------|---------|
| エフェメラルコンテナ | Pod指定かつ--copy-to未使用 | 既存Podにエフェメラルコンテナを追加（StrategicMergePatch） |
| Podコピー | Pod指定かつ--copy-to使用 | 既存Podのコピーを作成し、デバッグコンテナを追加/既存コンテナを変更 |
| ノードデバッグ | Node指定 | ホストネームスペースで動作するデバッグPodを作成 |

### セキュリティプロファイル

| プロファイル名 | 説明 |
|--------------|------|
| general | 汎用デバッグ（デフォルト） |
| baseline | baselineセキュリティポリシー準拠（ホストネームスペース等を排除） |
| restricted | restrictedポリシー準拠（非root、全capabilities Drop） |
| netadmin | ネットワークデバッグ用の昇格権限（NET_ADMIN capability） |
| sysadmin | システム管理用の昇格権限 |

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | コンテナ名自動生成 | コンテナ名未指定時はdebugger-{random5}を生成 | container未指定時 |
| BR-99-02 | ノードデバッグPod名 | node-debugger-{nodeName}-{random5}形式で自動生成 | ノードデバッグ時 |
| BR-99-03 | コピー時EphemeralContainerクリア | Podコピー時はEphemeralContainersをnilに設定 | copy-to時 |
| BR-99-04 | コピー時NodeNameクリア | --same-node未指定時はNodeNameをクリア | copy-to時かつsame-node=false |
| BR-99-05 | プロファイル適用 | セキュリティプロファイルをデバッグコンテナに適用 | 常時 |
| BR-99-06 | 非rootユーザー警告 | Pod全体にRunAsUserが非rootで設定されている場合、特権capabilityが動作しない可能性を警告 | 非rootユーザー設定時 |
| BR-99-07 | カスタムプロファイル制限 | name, command, image, lifecycle, volumeDevicesはカスタムプロファイルで変更不可 | custom指定時 |
| BR-99-08 | legacyプロファイル非推奨 | legacyプロファイルはv1.39で削除予定 | legacy指定時 |

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| エフェメラルコンテナ追加 | pods/ephemeralcontainers | PATCH | StrategicMergePatchでエフェメラルコンテナを追加 |
| Podコピー作成 | Pod | CREATE | デバッグ用のPodコピーを作成 |
| ノードデバッグPod作成 | Pod | CREATE | ノードデバッグ用のPodを作成 |
| 元Pod削除 | Pod | DELETE | --replace時に元のPodを削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | image必須エラー | --copy-to未使用時に--image未指定 | --imageを指定 |
| - | copy-toパラメータ不足 | --copy-to時にimage/set-image/argsすべて未指定 | 少なくとも1つ指定 |
| - | 排他フラグエラー | --replace/--same-node/--set-imageを--copy-to未使用時に指定 | --copy-toと組み合わせ |
| - | target排他エラー | --targetと--copy-toの同時指定 | どちらかを選択 |
| - | EphemeralContainers無効 | クラスタでEphemeralContainersが無効 | 機能を有効化するか--copy-toを使用 |
| - | カスタムプロファイルエラー | 不正なJSON/YAML | 有効なcontainer specを指定 |

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

エフェメラルコンテナ追加はStrategicMergePatch。Podコピーはatomic create。--replace時の元Pod削除は別API呼び出し。

## パフォーマンス要件

API呼び出しは1-2回。アタッチモードではコンテナ起動待機のためwatchポーリングが発生。

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

- エフェメラルコンテナはpods/ephemeralcontainersサブリソースのupdate権限が必要
- プロファイルの選択でセキュリティレベルを制御（baseline/restrictedで制限的に）
- ノードデバッグはホストネームスペース（PID/NET/IPC）にアクセスするため高権限
- ノードデバッグPodにはapp.kubernetes.io/managed-by=kubectl-debugラベルが付与

## 備考

- EphemeralContainers機能はKubernetes 1.25でGA
- カスタムプロファイルでcontainer specの一部をオーバーライド可能
- legacyプロファイルはv1.39で削除予定
- ノードデバッグ時は全Tolerationが設定される（全taintを許容）
- ノードデバッグPodのRestartPolicyはNever

---

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

### 推奨読解順序

#### Step 1: データ構造とプロファイルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **116-158行目**: DebugOptions構造体で全オプションを確認 |
| 1-2 | profiles.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go` | **28-61行目**: debugStyle定数とプロファイル名定数の定義 |
| 1-3 | profiles.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go` | **63-66行目**: ProfileApplierインターフェース |
| 1-4 | profiles.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go` | **69-80行目**: NewProfileApplierでプロファイル選択 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **172-190行目**: NewCmdDebug関数でComplete→Validate→Runの3段階実行 |
| 2-2 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **192-218行目**: AddFlags関数で多数のフラグ登録 |

#### Step 3: 3つのデバッグスタイルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **411-456行目**: Run関数でNode/Podの分岐 |
| 3-2 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **460-472行目**: visitNode → generateNodeDebugPod |
| 3-3 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **479-484行目**: visitPod → copy-to判定 → debugByCopy or debugByEphemeralContainer |
| 3-4 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **487-526行目**: debugByEphemeralContainer（StrategicMergePatch） |
| 3-5 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **613-639行目**: debugByCopy（Podコピー作成） |
| 3-6 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **710-773行目**: generateNodeDebugPod（ノードデバッグPod生成） |

#### Step 4: カスタムプロファイル適用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **530-568行目**: applyCustomProfile（通常コンテナ向け） |
| 4-2 | debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | **572-610行目**: applyCustomProfileEphemeral（エフェメラルコンテナ向け） |

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

```
NewCmdDebug
    │
    ├─ Complete
    │      ├─ PullPolicy, TargetNames, Args分離
    │      ├─ AttachFunc設定
    │      ├─ Env解析
    │      ├─ Namespace取得
    │      ├─ NewProfileApplier(profile, keepFlags)
    │      ├─ CustomProfile読み込み (JSON/YAML)
    │      └─ kubernetes.NewForConfig → podClient
    │
    ├─ Validate
    │      ├─ attach + image/container チェック
    │      ├─ copy-to排他チェック
    │      ├─ image形式検証
    │      ├─ set-image形式検証
    │      ├─ target排他チェック
    │      └─ customProfile制限チェック
    │
    └─ Run
           ├─ Builder.Do() → r.Visit()
           │      ├─ [Node] visitNode
           │      │      ├─ generateNodeDebugPod()
           │      │      │      ├─ コンテナ定義
           │      │      │      ├─ Applier.Apply()
           │      │      │      └─ applyCustomProfile()
           │      │      └─ pods.Create()  ───▶ API Server
           │      │
           │      └─ [Pod] visitPod
           │             ├─ [copy-to] debugByCopy
           │             │      ├─ generatePodCopyWithDebugContainer()
           │             │      │      ├─ SetImages適用
           │             │      │      ├─ コンテナ追加/変更
           │             │      │      ├─ Applier.Apply()
           │             │      │      └─ applyCustomProfile()
           │             │      ├─ pods.Create()  ───▶ API Server
           │             │      └─ [replace] pods.Delete()
           │             │
           │             └─ [ephemeral] debugByEphemeralContainer
           │                    ├─ generateDebugContainer()
           │                    │      ├─ EphemeralContainer定義
           │                    │      ├─ Applier.Apply()
           │                    │      └─ applyCustomProfileEphemeral()
           │                    ├─ StrategicMergePatch生成
           │                    └─ pods.Patch()  ───▶ API Server
           │
           └─ [attach] handleAttachPod
                  ├─ waitForContainer()
                  ├─ attach.Run()
                  └─ logOpts() (fallback)
```

### データフロー図

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

CLI引数                  ───▶ Complete（初期化）
 (POD/NODE --image)            │
                               ▼
CustomProfile.json ─────▶ Validate（検証）
                               │
                               ▼
kubeconfig              ───▶ Run
                         ├─ Builder.Do()            ───▶ API Server (GET)
                         │
                         ├─ [Node] visitNode
                         │   └─ pods.Create()       ───▶ API Server (CREATE Pod)
                         │
                         ├─ [Pod/copy] debugByCopy
                         │   ├─ pods.Create()       ───▶ API Server (CREATE Pod)
                         │   └─ pods.Delete()       ───▶ API Server (DELETE Pod)
                         │
                         ├─ [Pod/ephemeral]
                         │   └─ pods.Patch()        ───▶ API Server (PATCH)
                         │
                         └─ [attach]
                             ├─ waitForContainer()  ───▶ API Server (WATCH)
                             └─ attach.Run()        ◀──▶ Container Runtime
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| debug.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go` | ソース | debugコマンドのメイン実装（1032行） |
| profiles.go | `staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go` | ソース | セキュリティプロファイル定義 |
| attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/` | ソース | アタッチ機能 |
| exec.go | `staging/src/k8s.io/kubectl/pkg/cmd/exec/` | ソース | StreamOptions定義 |
| logs.go | `staging/src/k8s.io/kubectl/pkg/cmd/logs/` | ソース | ログストリーミング |
