# 機能設計書 94-Taint管理（taint）

## 概要

本ドキュメントは、kubectl taintコマンドによるノードへのTaint追加・削除機能の設計を記述する。

### 本機能の処理概要

kubectl taintコマンドは、Kubernetesノードに対してTaintを追加・更新・削除するCLI機能である。TaintはTolerationと組み合わせてPodのスケジューリング制御を行うメカニズムである。

**業務上の目的・背景**：特定のノードに対して特定のワークロードのみを配置したい場合（GPU搭載ノード、高メモリノード等）や、メンテナンス中のノードへの新規Pod配置を防ぎたい場合に利用される。

**機能の利用シーン**：専用ノードの設定、ノードメンテナンス前の準備（NoSchedule）、障害ノードからのPod退去（NoExecute）、優先度の低いPodの排除（PreferNoSchedule）。

**主要な処理内容**：
1. コマンドライン引数からTaint仕様を解析
2. 対象ノードの現在のTaint状態を取得
3. Taintの追加・更新・削除をMerge Patchで適用
4. 結果の出力

**関連システム・外部連携**：Schedulerが新規Pod配置時にTaint/Tolerationマッチングを実施。NoExecute Taint追加時は既存Podが退去される（Taint Manager制御）。

**権限による制御**：ノードのupdate/patch権限（RBAC）が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | kubectl taint | 主機能 | ノードへのTaint追加・削除 |

## 機能種別

CRUD操作（Update） / ノードメタデータ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| NODE | string | Yes | Taint対象のノード名（複数可） | 存在するノード |
| TAINT_SPEC | string[] | Yes | Taint仕様（key=value:effect / key:effect- / key-） | 有効なTaint形式 |
| --overwrite | bool | No | 既存Taintの上書き許可 | - |
| --all | bool | No | 全ノードを対象 | - |
| --selector / -l | string | No | ラベルセレクタ | 有効なラベルセレクタ形式 |
| --dry-run | string | No | dry-run戦略 | none/client/server |
| -o / --output | string | No | 出力フォーマット | json/yaml/name等 |

### 入力データソース

CLI引数、kubeconfig（クラスター接続情報）

### Taint仕様の形式

| 形式 | 説明 | 例 |
|-----|------|-----|
| `key=value:effect` | Taint追加（key, value, effect指定） | `dedicated=gpu:NoSchedule` |
| `key:effect` | Taint追加（valueなし） | `maintenance:NoExecute` |
| `key:effect-` | 指定effectのTaint削除 | `dedicated:NoSchedule-` |
| `key-` | 指定keyの全Taint削除 | `dedicated-` |

### Taint Effect

| Effect | 説明 |
|--------|------|
| NoSchedule | 新規Podのスケジューリングを拒否 |
| PreferNoSchedule | 新規Podのスケジューリングを極力避ける |
| NoExecute | 新規Podのスケジューリングを拒否し、既存Podも退去 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Taint結果 | string | "node/xxx tainted" / "node/xxx untainted" / "node/xxx modified" |

### 出力先

標準出力（stdout）

## 処理フロー

### 処理シーケンス

```
1. Complete: コマンド引数と環境の初期化
   └─ Taint仕様のパース（parseTaints）
2. Validate: 入力パラメータの検証
   └─ Taint追加時はeffect必須
3. RunTaint: Taint操作実行
   ├─ resource.Builderでノード情報を取得
   ├─ 各ノードに対して:
   │   ├─ 既存Taint重複チェック（overwrite考慮）
   │   ├─ reorganizeTaints: 新旧Taintのマージ
   │   ├─ Merge Patchの生成
   │   └─ API ServerにPATCHリクエスト
   └─ 結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Complete: Taint仕様パース]
    B --> C[Validate: 形式検証]
    C --> D[RunTaint: ノード取得]
    D --> E[各ノードループ]
    E --> F{既存Taint重複?}
    F -->|Yes| G{overwrite=true?}
    G -->|No| H[エラー: overwrite必要]
    G -->|Yes| I[reorganizeTaints]
    F -->|No| I
    I --> J{dry-run client?}
    J -->|Yes| K[オブジェクト出力のみ]
    J -->|No| L[API Server PATCH]
    K --> M[結果出力]
    L --> M
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-94-01 | effect必須 | Taint追加時はeffectの指定が必須 | Taint追加時 |
| BR-94-02 | 重複チェック | 同一key:effectのTaintが既に存在する場合は--overwrite必要 | 既存Taintあり |
| BR-94-03 | 一意性 | 同一effectの同一keyのTaintは重複不可 | 常時 |
| BR-94-04 | 削除時effect任意 | Taint削除時はeffect省略可（key-形式で全effect削除） | Taint削除時 |
| BR-94-05 | reorganize結果 | MODIFIED/TAINTED/UNTAINTEDの3状態で結果を表示 | 常時 |

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Taint追加/更新/削除 | Node | PATCH | spec.taintsフィールドをMerge Patchで更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | Taint追加時にeffect未指定 | effectを指定（NoSchedule/PreferNoSchedule/NoExecute） |
| - | バリデーションエラー | 無効なeffect値 | 有効なeffect値を指定 |
| - | 重複Taintエラー | 同一Taintが既に存在（overwrite未指定） | --overwriteを指定 |
| - | Taint未存在エラー | 削除対象のTaintが存在しない | Taintのkey/effectを確認 |
| - | 重複仕様エラー | 同一key:effectのTaintが引数に重複 | 重複を除去 |

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

各ノードへのTaint操作はMerge Patchで実行。楽観的並行制御が適用される。

## パフォーマンス要件

Merge Patchによる軽量な操作。--allまたは--selector指定時はノード数分のAPI呼び出しが発生。

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

- ノードのupdate/patch権限が必要
- NoExecute Taintの追加は既存Podに即座に影響するため慎重に実施

## 備考

- Taint/Tolerationメカニズムの詳細はKubernetes Schedulerのドキュメントを参照
- NoExecute Taint追加時の既存Pod退去はTaint Managerが自動実行

---

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

### 推奨読解順序

#### Step 1: Taintパースロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | utils.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go` | **39-73行目**: parseTaints関数でTaint仕様の解析ロジック |
| 1-2 | utils.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go` | **77-118行目**: parseTaint関数で個別のTaint文字列パース |
| 1-3 | utils.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go` | **120-126行目**: validateTaintEffectでeffect値の検証 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | taint.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/taint.go` | NewCmdTaint関数でcobraコマンド定義 |
| 2-2 | taint.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/taint.go` | Complete関数でTaint仕様のパースと初期化 |

#### Step 3: Taint操作実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | taint.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/taint.go` | RunTaint関数でノード取得→Taint更新→PATCH適用の流れ |
| 3-2 | utils.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go` | **130-142行目**: reorganizeTaintsで新旧Taintのマージロジック |

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

```
NewCmdTaint
    │
    ├─ Complete
    │      ├─ parseTaints(spec)         → taintsToAdd, taintsToRemove
    │      ├─ f.ToRawKubeConfigLoader().Namespace()
    │      └─ f.NewBuilder()
    │
    ├─ Validate
    │      └─ Taint形式・パラメータ検証
    │
    └─ RunTaint
           ├─ builder.Do() → r.Visit()
           │      └─ 各ノードに対して:
           │             ├─ checkIfTaintsAlreadyExists()
           │             ├─ reorganizeTaints()
           │             │      ├─ addTaints()
           │             │      └─ deleteTaints()
           │             ├─ json.Marshal → CreateMergePatch
           │             └─ helper.Patch()  ───▶ API Server
           └─ PrintObj()
```

### データフロー図

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

CLI引数                  ───▶ parseTaints
 (key=value:effect)            │
                               ▼
kubeconfig              ───▶ RunTaint
                         ├─ Builder.Do()       ───▶ API Server (GET Node)
                         ├─ reorganizeTaints()
                         │      ├─ addTaints()
                         │      └─ deleteTaints()
                         ├─ helper.Patch()     ───▶ API Server (PATCH Node)
                         └─ PrintObj()         ───▶ stdout
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| taint.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/taint.go` | ソース | taintコマンドのメイン実装 |
| utils.go | `staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go` | ソース | Taintパース・マージユーティリティ |
