# 画面設計書 21-kubectl attach

## 概要

本ドキュメントは、Kubernetes CLIツール kubectl の `attach` コマンドに関する画面設計書である。kubectl attach は実行中のコンテナの標準入出力にアタッチし、対話的な操作を可能にするコマンドである。

### 本画面の処理概要

kubectl attach コマンドは、Kubernetes クラスター上で既に実行中のコンテナプロセスに対して標準入出力（stdin/stdout/stderr）を接続し、リアルタイムでの対話操作を実現する。

**業務上の目的・背景**：本番環境やステージング環境で稼働中のコンテナに対して、再起動することなくリアルタイムで出力を確認したり、入力を送信する必要がある。デバッグやモニタリング、対話型プロセスとの通信において不可欠な機能である。exec コマンドとは異なり、attach は既にコンテナ内で実行中のメインプロセス（PID 1）に直接接続する。

**画面へのアクセス方法**：ターミナルから `kubectl attach <POD名>` または `kubectl attach <TYPE/NAME>` を実行する。`-c` フラグでコンテナを指定し、`-i` フラグで stdin を渡し、`-t` フラグで TTY を有効にする。

**主要な操作・処理内容**：
1. 指定されたPod/リソースの検索とアタッチ可能なPodの特定
2. 対象コンテナの選択（`-c` フラグまたは `kubectl.kubernetes.io/default-container` アノテーション、または最初のコンテナ）
3. TTY の設定とターミナルサイズの監視
4. Kubelet の Attach エンドポイントへの SPDY/WebSocket 接続確立
5. stdin/stdout/stderr のストリーミング

**画面遷移**：kubectl run コマンドから `--attach` フラグで遷移可能。kubectl debug コマンドのアタッチ処理でも内部的に呼び出される。セッション終了後はシェルに戻る。

**権限による表示制御**：対象Podの `pods/attach` サブリソースに対する権限が必要。RBACにより制御される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 114 | Attach | 主機能 | 実行中のコンテナの標準入出力にアタッチする主処理 |
| 66 | Kubelet API Server | API連携 | KubeletのAttachエンドポイントを通じてコンテナに接続する |

## 画面種別

CLI対話型コマンド（ストリーミング）

## URL/ルーティング

```
kubectl attach (POD | TYPE/NAME) -c CONTAINER
```

内部的には以下の REST API エンドポイントを使用：
```
POST /api/v1/namespaces/{namespace}/pods/{name}/attach
```

## 入出力項目

| 項目名 | 種別 | 必須 | 型 | 説明 |
|--------|------|------|-----|------|
| POD / TYPE/NAME | 引数 | Yes | string | アタッチ対象のPodまたはリソース |
| --container, -c | フラグ | No | string | アタッチするコンテナ名 |
| --stdin, -i | フラグ | No | bool | stdinをコンテナに渡す（デフォルト: false） |
| --tty, -t | フラグ | No | bool | stdinがTTYかどうか（デフォルト: false） |
| --quiet, -q | フラグ | No | bool | 情報メッセージを抑制する（デフォルト: false） |
| --pod-running-timeout | フラグ | No | duration | PodがRunningになるまでの待機時間（デフォルト: 60s） |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| 警告メッセージ | セッション記録に関する警告（credential情報がログに記録される旨） |
| TTY警告 | コンテナがTTYを割り当てていない場合の警告 |
| コンテナ出力 | アタッチ先コンテナのstdout/stderrストリーム |
| 再接続メッセージ | セッション終了後の再接続コマンドの案内 |

## イベント仕様

### 1-コマンド実行

ユーザーが `kubectl attach` コマンドを実行すると、以下の処理フローが実行される：

1. Complete: コマンドライン引数の解析、namespace の決定、REST Config の取得
2. Validate: 引数が1つ以上2つ以下であることの確認、pod-running-timeout が正の値であることの確認
3. Run: Podの検索 -> コンテナの特定 -> TTYセットアップ -> Attach実行

### 2-セッション終了

Ctrl+C またはプロセス終了により接続が切断される。RestartPolicy が Always のPodの場合、再接続コマンドが表示される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| attach実行 | - | SELECT（読み取り） | Pod情報の取得のみ。リソースの変更は行わない |

kubectl attach コマンドはKubernetesリソースの状態を変更しない読み取り専用の操作である。

### テーブル別更新項目詳細

該当なし（読み取り専用操作）

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|----------|
| M-01 | 情報 | "All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt." | quiet=false |
| M-02 | 情報 | "If you don't see a command prompt, try pressing enter." | quiet=false |
| M-03 | 警告 | "error: Unable to use a TTY - container %s did not allocate one" | TTY要求だがコンテナがTTY未割当 |
| M-04 | エラー | "at least 1 argument is required for attach" | 引数なし |
| M-05 | エラー | "cannot attach a container in a completed pod; current phase is %s" | PodがSucceededまたはFailed |
| M-06 | 情報 | "Session ended, resume using '%s %s -c %s -n %s -i -t' command when the pod is running" | 通常コンテナのセッション終了時 |
| M-07 | 情報 | "Session ended, the ephemeral container will not be restarted but may be reattached..." | エフェメラルコンテナのセッション終了時 |

## 例外処理

| 例外 | 状態 | 対処 |
|------|------|------|
| Pod が見つからない | エラー終了 | リソースが存在しない旨のエラーを表示 |
| Pod が Succeeded/Failed | エラー終了 | 完了済みPodにはアタッチ不可のメッセージを表示 |
| コンテナが見つからない | エラー終了 | 指定コンテナが存在しない旨のエラーを表示 |
| REST Config 取得失敗 | エラー終了 | kubeconfig の設定エラーを表示 |
| Kubelet 接続失敗 | エラー終了 | ネットワークエラーまたは権限不足のエラーを表示 |
| SPDY/WebSocket アップグレード失敗 | フォールバック | WebSocket失敗時はSPDYにフォールバック |

## 備考

- attach はコンテナのメインプロセス（PID 1）に接続する。新しいプロセスを起動する場合は `kubectl exec` を使用する。
- `kubectl.kubernetes.io/default-container` アノテーションを使用して、デフォルトのコンテナを指定可能。
- WebSocket が有効な場合、最初に WebSocket 接続を試み、失敗した場合は SPDY にフォールバックする（`createExecutor` 関数、attach.go 行176-196）。
- TTY モードでは stderr が無効化される（`DisableStderr = true`、行309）。

---

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

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

### 推奨読解順序

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

まず、attach コマンドで使用されるオプション構造体とインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | AttachOptions 構造体（行72-91）: exec.StreamOptions を埋め込み、Pod、AttachFunc、Config 等を保持 |
| 1-2 | exec.go | `staging/src/k8s.io/kubectl/pkg/cmd/exec/exec.go` | StreamOptions 構造体（行168-184）: Namespace、PodName、ContainerName、Stdin、TTY等の共通ストリーム設定 |

**読解のコツ**: AttachOptions は StreamOptions を埋め込んでおり、exec パッケージとの共有構造になっている。RemoteAttach インターフェース（行129-131）がテストスタブのために抽象化されている点に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | NewCmdAttach関数（行105-126）: コマンド定義とフラグ登録 |

**主要処理フロー**:
1. **行114-118**: Complete -> Validate -> Run の3段階で実行
2. **行120-125**: --pod-running-timeout, -c, -i, -t, -q フラグの登録

#### Step 3: Complete/Validate/Run の処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | Complete（行199-228）: namespace取得、タイムアウト取得、REST Config取得 |
| 3-2 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | Validate（行231-243）: 引数数チェック、タイムアウト値チェック |
| 3-3 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | Run（行246-324）: Pod取得、コンテナ選択、TTYセットアップ、Attach実行 |

**主要処理フロー**:
- **行248-273**: Pod がnilの場合、resource.Builder で検索し findAttachablePod でアタッチ可能なPodを取得
- **行276-289**: TTYの整合性チェック（コンテナTTYとリクエストTTYの一致確認）
- **行292-310**: TTY セットアップとターミナルサイズ監視
- **行316**: AttachFunc を Safe でラップして実行

#### Step 4: 実際のAttach通信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | DefaultAttachFunc（行134-155）: REST API経由でattachサブリソースにPOST |
| 4-2 | attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | createExecutor（行176-196）: SPDY/WebSocketのエグゼキュータ生成 |

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

```
NewCmdAttach (行105)
    |
    +-- Complete (行199)
    |       +-- f.ToRawKubeConfigLoader().Namespace()
    |       +-- f.ToRESTConfig()
    |
    +-- Validate (行231)
    |
    +-- Run (行246)
            |
            +-- Builder.Do().Object() (行259)
            +-- findAttachablePod (行326)
            +-- containerToAttachTo (行339)
            |       +-- podcmd.FindOrDefaultContainerByName
            +-- SetupTTY (行292)
            +-- AttachFunc -> DefaultAttachFunc (行134)
                    |
                    +-- restclient.RESTClientFor (行136)
                    +-- restClient.Post().Resource("pods").SubResource("attach") (行140-144)
                    +-- Attach.Attach (行153)
                            |
                            +-- createExecutor (行176)
                            |       +-- NewSPDYExecutor (行177)
                            |       +-- NewWebSocketExecutor (行184)
                            |       +-- NewFallbackExecutor (行188)
                            +-- exec.StreamWithContext (行166)
```

### データフロー図

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

ユーザー入力             Complete
(POD名, フラグ) ------> (namespace, config取得) --------> 検証完了
                              |
                         Validate
                         (引数チェック) -----------------> エラー or 継続
                              |
                         Run
                         (Pod/Container特定)
                              |
                         TTY Setup
                         (ターミナル設定)
                              |
stdin -----------------> DefaultAttachFunc
                         (REST API POST)
                              |
                         Kubelet Attach Endpoint -------> stdout/stderr
                         (SPDY/WebSocket)                 (コンテナ出力)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| attach.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go` | ソース | attach コマンドの主実装 |
| exec.go | `staging/src/k8s.io/kubectl/pkg/cmd/exec/exec.go` | ソース | StreamOptions 構造体の定義、TTY セットアップ |
| podcmd.go | `staging/src/k8s.io/kubectl/pkg/cmd/util/podcmd/` | ソース | FindOrDefaultContainerByName 等のコンテナ選択ユーティリティ |
| term.go | `staging/src/k8s.io/kubectl/pkg/util/term/` | ソース | TTY管理とターミナルサイズ監視 |
| remotecommand/ | `staging/src/k8s.io/client-go/tools/remotecommand/` | ソース | SPDY/WebSocket エグゼキュータ |
| attach_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/attach/attach_test.go` | テスト | attach コマンドのユニットテスト |
