# 画面設計書 2-kubectl expose

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl` の `expose` コマンドに関する画面設計書である。`kubectl expose` は既存のリソース（Deployment、Pod、ReplicaSet、ReplicationController、Service）からKubernetes Serviceリソースを新規に作成し、ネットワーク経由でアクセス可能にするコマンドである。

### 本画面の処理概要

`kubectl expose` コマンドは、指定されたリソースのセレクタとポート情報を元にServiceリソースを生成し、API Serverを通じてクラスタに登録する。

**業務上の目的・背景**：Kubernetesクラスタ上で動作するPodやDeploymentに対し、クラスタ内外からのネットワークアクセスを提供するためのServiceリソースを簡単に作成する。マニフェストファイルを別途用意せずに、既存リソースの情報を元にServiceを自動生成できるため、開発・テスト時の迅速なサービス公開に適している。

**画面へのアクセス方法**：ターミナルから `kubectl expose <resource-type> <name> [options]` の形式で実行する。

**主要な操作・処理内容**：
1. 対象リソース（Deployment, Pod, ReplicaSet, ReplicationController, Service）を指定してServiceを作成
2. ポート番号、ターゲットポート、プロトコル、Serviceタイプの指定
3. ClusterIP、NodePort、LoadBalancer、ExternalNameの各Serviceタイプをサポート
4. セレクタの自動取得または手動指定
5. ラベルの引き継ぎまたは手動指定
6. セッションアフィニティの設定

**画面遷移**：本コマンドはkubectlのBasic Commands (Beginner)カテゴリに属する。`kubectl create` や `kubectl run` でリソースを作成した後に、サービスを公開するために使用される。作成されたServiceは `kubectl get svc` で確認できる。

**権限による表示制御**：Serviceリソースの作成権限（RBAC）が必要。また対象リソースに対するget権限も必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 97 | Service公開（expose） | 主機能 | Deployment等のリソースからServiceリソースを作成して公開する主処理 |
| 139 | Service管理 | API連携 | ClusterIP、NodePort、LoadBalancer等のServiceタイプの作成をAPI Server経由で行う |
| 1 | API Serverコア | API連携 | Serviceリソース作成リクエストをAPI Serverに送信する |

## 画面種別

CLIコマンド（リソース作成）

## URL/ルーティング

```
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]
```

## 入出力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| TYPE NAME / -f FILENAME | string | Yes | 公開対象のリソースタイプと名前、またはファイル |
| --port | string | No | Serviceが提供するポート番号（未指定時は対象リソースから推定） |
| --target-port | string | No | コンテナ側のポート番号または名前 |
| --protocol | string | No | ネットワークプロトコル（デフォルト: TCP） |
| --name | string | No | 作成するServiceの名前（デフォルト: 対象リソース名） |
| --type | string | No | Serviceタイプ（ClusterIP/NodePort/LoadBalancer/ExternalName。デフォルト: ClusterIP） |
| --selector | string | No | ラベルセレクタ（デフォルト: 対象リソースから推定） |
| -l, --labels | string | No | Serviceに付与するラベル |
| --external-ip | string | No | 外部IPアドレス |
| --load-balancer-ip | string | No | LoadBalancerに割り当てるIP |
| --session-affinity | string | No | セッションアフィニティ（None/ClientIP） |
| --cluster-ip | string | No | ClusterIP（Noneでheadless service） |
| --dry-run | string | No | ドライランモード |
| -o, --output | string | No | 出力フォーマット |
| --field-manager | string | No | フィールドマネージャ名（デフォルト: kubectl-expose） |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| Service作成結果 | `service/<name> exposed` の形式 |
| ドライラン結果 | リソース定義のYAML/JSON出力 |
| エラーメッセージ | バリデーションエラー等 |

## イベント仕様

### 1-コマンド実行

1. ユーザーが `kubectl expose <type> <name> --port=<port>` を実行
2. `ExposeServiceFlags.ToOptions()` でフラグからオプションに変換（行227-268）
3. `ExposeServiceOptions.Complete()` で補完処理（行271-292）
4. `ExposeServiceOptions.RunExpose()` で以下を実行（行296-428）:
   a. resource.Builderで対象リソースを取得
   b. `CanBeExposed()` で公開可能か確認（行316）
   c. セレクタ未指定時は `MapBasedSelectorForObject()` で自動取得（行328-334）
   d. ポート未指定時は `PortsForObject()` で自動取得（行340-355）
   e. プロトコル情報を `ProtocolsForObject()` で取得（行359-365）
   f. ラベル未指定時はリソースのラベルを引き継ぐ（行367-373）
   g. `createService()` でServiceオブジェクトを生成（行376-378）
   h. OverrideOptions を適用（行381-383）
   i. API Serverにリソースを作成（行400-425）

### 2-Serviceオブジェクト生成

`createService()` メソッド（行430-575）で以下を実行:
1. セレクタのパース（行434）
2. ラベルのパース（行440-445）
3. ポートリストの構築（行466-521）: 複数ポート対応、プロトコルマッピング
4. TargetPortの設定（行533-547）
5. ExternalIP、ServiceType、LoadBalancerIP、SessionAffinity、ClusterIPの設定

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Service作成 | etcd（Service） | INSERT | Serviceリソースをetcdに永続化 |

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

#### etcd（Serviceリソース）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | metadata.name | --nameフラグまたは対象リソース名 | DNS1035ラベル最大長でトランケート |
| INSERT | spec.selector | --selectorフラグまたは対象リソースのセレクタ | |
| INSERT | spec.ports | --portフラグまたは対象リソースのポート情報 | 複数ポート対応 |
| INSERT | spec.type | --typeフラグ（デフォルト: ClusterIP） | |
| INSERT | spec.clusterIP | --cluster-ipフラグ | Noneでheadless |
| INSERT | spec.sessionAffinity | --session-affinityフラグ | None/ClientIP |

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|-----------|------|
| 成功 | `service/<name> exposed` | Serviceが正常に作成された場合 |
| エラー | `couldn't retrieve selectors via --selector flag or introspection` | セレクタの取得に失敗した場合 |
| エラー | `couldn't find port via --port flag or introspection` | ポートの取得に失敗した場合 |
| エラー | `selector must be specified` | セレクタが空の場合 |
| エラー | `name must be specified` | 名前が空の場合 |
| エラー | `unknown session affinity: <value>` | 不正なセッションアフィニティ値 |

## 例外処理

| 例外条件 | 動作 |
|----------|------|
| 対象リソースが存在しない | リソース取得エラーを表示して終了 |
| リソースがexposeに対応していない | `CanBeExposed` のエラーを表示して終了 |
| ポートが推定できない | ポート取得エラーを表示して終了 |
| 権限不足 | RBAC forbiddenエラーを表示して終了 |
| Service名の重複 | AlreadyExistsエラーを表示して終了 |

## 備考

- 対象リソースのセレクタがmatchLabelsのみの場合にServiceに変換可能。matchExpressionsを含む場合は変換不可。
- 複数ポートを持つリソースの場合、--portが未指定であれば全ポートがServiceに含まれる。
- pod, service, replicationcontroller, deployment, replicasetが対象リソースとして指定可能。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | `ExposeServiceOptions` 構造体（行89-135）: コマンドオプション全体を保持。Port, Ports, Protocols, Type, SessionAffinity等のフィールド |
| 1-2 | expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | `ExposeServiceFlags` 構造体（行138-160）: CLIフラグを保持するFlagsパターン |

**読解のコツ**: Flags → ToOptions → Options のパターンで、CLIフラグからランタイムオプションへの変換が行われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | `NewCmdExposeService()` 関数（行173-199）: cobraコマンド定義、validArgsの構築 |

**主要処理フロー**:
1. **行174**: NewExposeFlags()でフラグ初期化
2. **行176-180**: 有効なリソースタイプからvalidArgsを構築
3. **行189-194**: Run関数: ToOptions → Complete → RunExpose

#### Step 3: メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | `RunExpose()` メソッド（行296-428）: 対象リソースの取得、セレクタ・ポートの推定、Service生成、API Server送信 |
| 3-2 | expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | `createService()` メソッド（行430-575）: Serviceオブジェクトの構築ロジック |

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

```
NewCmdExposeService()
    |
    +-- ExposeServiceFlags.ToOptions()
    |
    +-- ExposeServiceOptions.Complete()
    |       +-- f.NewBuilder()
    |       +-- polymorphichelpers.CanBeExposedFn
    |       +-- polymorphichelpers.MapBasedSelectorForObjectFn
    |       +-- polymorphichelpers.PortsForObjectFn
    |       +-- polymorphichelpers.MultiProtocolsForObjectFn
    |
    +-- ExposeServiceOptions.RunExpose()
            +-- resource.Builder.Do()
            +-- r.Visit()
                    +-- CanBeExposed()
                    +-- MapBasedSelectorForObject()
                    +-- PortsForObject()
                    +-- ProtocolsForObject()
                    +-- createService()
                    |       +-- parseLabels()
                    |       +-- parseProtocols()
                    +-- NewOverrider().Apply()
                    +-- resource.NewHelper().Create()
```

### データフロー図

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

対象リソース名  ───────▶  resource.Builder        ───▶  resource.Info
                               |
                               v
                         セレクタ・ポート推定
                               |
                               v
                         createService()           ───▶  corev1.Service オブジェクト
                               |
                               v
                         resource.NewHelper().Create() ───▶  API Server (etcd)
                               |
                               v
                         PrintObj()                ───▶  stdout (作成結果)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| expose.go | `staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go` | ソース | exposeコマンドの主処理 |
| polymorphichelpers | `staging/src/k8s.io/kubectl/pkg/polymorphichelpers/` | ソース | CanBeExposed, MapBasedSelectorForObject, PortsForObject等のヘルパー |
| resource.Builder | `staging/src/k8s.io/cli-runtime/pkg/resource/builder.go` | ソース | リソース構築フレームワーク |
| resource.Helper | `staging/src/k8s.io/cli-runtime/pkg/resource/helper.go` | ソース | API Serverとの通信ヘルパー |
