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

## はじめに

このガイドラインは、Kubernetesのコードベースを効率的に理解するための手引きです。
Go言語に精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、Go言語の基本構文と概念を解説します。

### 1.1 プログラム構造

Go言語のプログラムは `package` 宣言で始まり、`import` でパッケージを読み込み、関数やデータ型を定義する構造をとります。実行可能なバイナリのエントリーポイントは `package main` の `func main()` です。

```go
// ファイル: cmd/kube-apiserver/apiserver.go:19-36
package main

import (
	"os"
	_ "time/tzdata"

	"k8s.io/component-base/cli"
	_ "k8s.io/component-base/logs/json/register"
	_ "k8s.io/component-base/metrics/prometheus/clientgo"
	_ "k8s.io/component-base/metrics/prometheus/version"
	"k8s.io/kubernetes/cmd/kube-apiserver/app"
)

func main() {
	command := app.NewAPIServerCommand()
	code := cli.Run(command)
	os.Exit(code)
}
```

**ポイント:**
- `package main` はコンパイルして実行ファイルを生成するパッケージであることを示す
- `import` ブロック内で `_` プレフィックスを付けたインポートは「副作用インポート」と呼ばれ、パッケージの `init()` 関数のみを実行するために使用する
- Kubernetesでは全てのバイナリが `cmd/` 配下にエントリーポイントを持つ

### 1.2 データ型と変数

Goは静的型付け言語です。Kubernetesでは特に構造体（struct）が頻繁に使用されます。

```go
// ファイル: staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go:42-57
type TypeMeta struct {
	Kind       string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
	APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}
```

**ポイント:**
- `type 名前 struct { ... }` で構造体を定義する
- バッククォートで囲まれた部分（`` `json:"..."` ``）は「タグ」と呼ばれ、JSONシリアライズ時のフィールド名やprotobufエンコーディング情報を指定する
- `omitempty` はゼロ値の場合にJSONから省略することを意味する

```go
// ファイル: pkg/apis/core/types.go:27-42
const (
	NamespaceDefault   = "default"
	NamespaceAll       = ""
	NamespaceNone      = ""
	NamespaceSystem    = "kube-system"
	NamespacePublic    = "kube-public"
	NamespaceNodeLease = "kube-node-lease"
)
```

- `const` ブロックで定数を一括定義する
- Goでは定数名を大文字始まりにすると他パッケージから参照可能（exported）になる

### 1.3 制御構造

Goの制御構造は `if`、`for`、`switch`、`select` が基本です。`while` は存在せず、全てのループは `for` で表現します。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:193-198
for i := 0; i < workers; i++ {
	wg.Go(func() {
		wait.UntilWithContext(ctx, dc.worker, time.Second)
	})
}
<-ctx.Done()
```

**ポイント:**
- `for` 文はC言語スタイルのほか、`for range` で配列/スライス/マップのイテレーションが可能
- `<-ctx.Done()` はチャネルからの受信でブロックし、コンテキストがキャンセルされるまで待機するGoの並行処理パターン

### 1.4 関数/メソッド定義

Goではレシーバを持つ関数がメソッドとなります。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:171
func (dc *DeploymentController) Run(ctx context.Context, workers int) {
	defer utilruntime.HandleCrash()
	// ...
}
```

**ポイント:**
- `(dc *DeploymentController)` はレシーバで、`DeploymentController` 構造体のメソッドであることを示す
- `*` はポインタレシーバを意味し、構造体のフィールドを変更可能にする
- `defer` は関数終了時に実行される処理を登録するキーワード
- `context.Context` は処理のキャンセル・タイムアウトを伝播するGoの標準的なパターン

### 1.5 モジュール/インポート

Kubernetesは `go.mod` によるGoモジュールシステムを使用しています。

```go
// ファイル: go.mod:7-9
module k8s.io/kubernetes

go 1.25.0
```

インポートパスはモジュールパス + パッケージディレクトリで構成されます。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:30-51
import (
	apps "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	clientset "k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/util/workqueue"
	"k8s.io/kubernetes/pkg/controller"
)
```

**ポイント:**
- `apps "k8s.io/api/apps/v1"` のようにエイリアスを付けてインポートできる
- Kubernetes内のパッケージは `k8s.io/kubernetes/...` でインポートする
- `staging/` 配下のパッケージは `k8s.io/client-go`、`k8s.io/apimachinery` など独立したモジュールとしてインポートする
- 標準ライブラリ、外部ライブラリ、プロジェクト内パッケージをグループ分けしてインポートする慣習がある

---

## 2. プロジェクト固有の概念

> このセクションでは、Kubernetes特有の概念を解説します。

### 2.1 フレームワーク固有の概念

Kubernetesは独自のフレームワークを構築しており、以下の概念が中核を成します。

**API リソースとGVK (Group, Version, Kind)**

全てのKubernetesオブジェクトは Group（APIグループ）、Version（APIバージョン）、Kind（リソース種別）の3つで一意に識別されます。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:63
var controllerKind = apps.SchemeGroupVersion.WithKind("Deployment")
```

**Informer / Lister パターン**

Kubernetesコントローラはetcdから直接データを取得するのではなく、Informerを通じてローカルキャッシュを構築し、Listerでキャッシュからデータを読み取ります。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:80-97
// dLister can list/get deployments from the shared informer's store
dLister appslisters.DeploymentLister
// rsLister can list/get replica sets from the shared informer's store
rsLister appslisters.ReplicaSetLister
// dListerSynced returns true if the Deployment store has been synced at least once.
dListerSynced cache.InformerSynced
```

**WorkQueue パターン**

コントローラはイベント（Add/Update/Delete）を受け取り、WorkQueueに処理対象のキーを投入し、ワーカーゴルーチンがキューから取り出して処理します。

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:100
queue workqueue.TypedRateLimitingInterface[string]
```

### 2.2 プロジェクト独自のパターン

**コントローラパターン（Reconciliation Loop）**

Kubernetesの全てのコントローラは以下のパターンに従います。

1. `NewXxxController()` でInformerを登録し、イベントハンドラを設定
2. `Run()` でワーカーゴルーチンを起動
3. ワーカーがキューからキーを取り出し `syncHandler` を呼び出す
4. `syncHandler` が「望ましい状態」と「現在の状態」を比較し、差分を解消する

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:123-134
dInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
	AddFunc: func(obj interface{}) {
		dc.addDeployment(logger, obj)
	},
	UpdateFunc: func(oldObj, newObj interface{}) {
		dc.updateDeployment(logger, oldObj, newObj)
	},
	DeleteFunc: func(obj interface{}) {
		dc.deleteDeployment(logger, obj)
	},
})
```

**REST Storage パターン**

API Serverはリソースごとに `Storage` 構造体を定義し、CRUD操作を実装します。

```go
// ファイル: pkg/registry/core/pod/storage/storage.go:54-60
type PodStorage struct {
	Pod                 *REST
	Binding             *BindingREST
	LegacyBinding       *LegacyBindingREST
	Eviction            *EvictionREST
	Status              *StatusREST
	EphemeralContainers *EphemeralContainersREST
}
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `cmd/<バイナリ名>/` | 各バイナリのエントリーポイント | `cmd/kube-apiserver/`, `cmd/kubelet/` |
| `pkg/<コンポーネント>/` | コンポーネントの実装 | `pkg/controller/`, `pkg/scheduler/` |
| `pkg/apis/<グループ>/` | 内部APIの型定義 | `pkg/apis/core/`, `pkg/apis/apps/` |
| `staging/src/k8s.io/<モジュール>/` | 独立して公開されるライブラリ | `staging/src/k8s.io/client-go/` |
| `*_test.go` | テストファイル（Go標準） | `controller_utils_test.go` |
| `zz_generated.*.go` | コード生成ツールが出力したファイル | `zz_generated.deepcopy.go` |
| `doc.go` | パッケージドキュメント | `pkg/controller/doc.go` |
| `types.go` | 型定義を集約するファイル | `pkg/apis/core/types.go` |
| `register.go` | スキーム登録処理 | `pkg/apis/core/register.go` |
| `validation/` | バリデーションロジック | `pkg/apis/core/validation/` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `New<Type>` | コンストラクタ関数 | `NewDeploymentController()`, `NewAPIServerCommand()` |
| `<Type>Interface` | インターフェース定義 | `RSControlInterface` |
| `<Type>Lister` | キャッシュからの読み取り | `DeploymentLister`, `ReplicaSetLister` |
| `<Type>Informer` | リソース変更の監視 | `DeploymentInformer`, `PodInformer` |
| `<type>Synced` | キャッシュ同期完了フラグ | `dListerSynced`, `rsListerSynced` |
| `sync<Resource>` | リコンシリエーション処理 | `syncDeployment` |
| `add/update/delete<Resource>` | イベントハンドラ | `addDeployment`, `updateDeployment` |
| `Run()` | コントローラの起動メソッド | `DeploymentController.Run()` |
| `<type>REST` | RESTストレージ実装 | `BindingREST`, `StatusREST` |
| `util` / `utils` | ユーティリティパッケージ | `pkg/controller/deployment/util/` |

### 3.3 プログラム分類一覧

| 分類 | パス | 説明 |
|------|------|------|
| コントロールプレーンバイナリ | `cmd/kube-apiserver/`, `cmd/kube-controller-manager/`, `cmd/kube-scheduler/` | クラスタ管理コンポーネント |
| ノードバイナリ | `cmd/kubelet/`, `cmd/kube-proxy/` | 各ノードで動作するエージェント |
| CLI | `cmd/kubectl/`, `cmd/kubeadm/` | ユーザ向けコマンドラインツール |
| コントローラ | `pkg/controller/<名前>/` | 各リソースのリコンシリエーションロジック |
| API型定義（内部） | `pkg/apis/<グループ>/` | 内部表現の型定義 |
| API型定義（外部） | `staging/src/k8s.io/api/<グループ>/<バージョン>/` | 外部公開されるAPI型 |
| レジストリ | `pkg/registry/<グループ>/<リソース>/` | API ServerのRESTストレージ |
| テスト | `test/e2e/`, `test/integration/`, `test/e2e_node/` | 各レベルのテスト |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
kubernetes/
├── api/                    # OpenAPI仕様・APIルール
│   ├── api-rules/
│   ├── discovery/
│   └── openapi-spec/
├── build/                  # ビルドスクリプト・Docker関連
├── cmd/                    # 各バイナリのエントリーポイント
│   ├── kube-apiserver/     #   API Server
│   ├── kube-controller-manager/ # Controller Manager
│   ├── kube-scheduler/     #   Scheduler
│   ├── kubelet/            #   Kubelet
│   ├── kube-proxy/         #   Kube Proxy
│   ├── kubectl/            #   kubectl CLI
│   ├── kubeadm/            #   kubeadm CLI
│   └── ...                 #   その他ユーティリティ
├── cluster/                # クラスタデプロイスクリプト
├── docs/                   # ドキュメント
├── hack/                   # 開発用スクリプト群
├── pkg/                    # 主要な実装コード
│   ├── api/                #   API ヘルパー
│   ├── apis/               #   内部API型定義
│   ├── controller/         #   全コントローラの実装
│   ├── kubelet/            #   kubeletの実装
│   ├── proxy/              #   kube-proxyの実装
│   ├── registry/           #   APIリソースのストレージ
│   ├── scheduler/          #   スケジューラの実装
│   ├── volume/             #   ボリュームプラグイン
│   └── ...
├── plugin/                 # プラグイン
├── staging/                # 独立モジュール（client-go等）
│   └── src/k8s.io/
│       ├── api/            #   外部API型定義
│       ├── apimachinery/   #   APIの基盤ライブラリ
│       ├── apiserver/      #   API Serverライブラリ
│       ├── client-go/      #   Goクライアントライブラリ
│       ├── component-base/ #   コンポーネント共通基盤
│       └── ...
├── test/                   # テスト
│   ├── e2e/                #   E2Eテスト
│   ├── integration/        #   結合テスト
│   └── e2e_node/           #   ノードE2Eテスト
├── third_party/            # サードパーティコード
├── vendor/                 # 依存ライブラリ（vendoring）
├── go.mod                  # Goモジュール定義
├── go.sum                  # 依存ハッシュ
├── go.work                 # Goワークスペース定義
├── Makefile                # ビルドターゲット
└── OWNERS                  # コードオーナー定義
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `cmd/` | 各バイナリのmain関数とアプリケーション初期化 | `apiserver.go`, `kubelet.go` |
| `pkg/controller/` | リコンシリエーションループの実装 | `deployment_controller.go` |
| `pkg/apis/` | 内部API型定義・バリデーション・変換 | `types.go`, `validation/` |
| `pkg/registry/` | API ServerのRESTリソースストレージ | `storage/storage.go` |
| `pkg/scheduler/` | Podスケジューリングロジック | `scheduler.go`, `framework/` |
| `pkg/kubelet/` | ノード上のPod管理 | `kubelet.go` |
| `staging/` | 独立公開されるGoモジュール群 | 各モジュールの `go.mod` |
| `hack/` | コード生成・CI/CD・検証スクリプト | `update-vendor.sh` |
| `test/` | E2E/結合/ノードテスト | `e2e/`, `integration/` |
| `vendor/` | 依存ライブラリのvendored copy | 自動生成 |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Kubernetesは **コントロールプレーン + ノード** の分散アーキテクチャを採用しています。宣言的なAPIを中心に、各コンポーネントが独立して動作し、リコンシリエーション（調停）ループによってシステムを望ましい状態に収束させます。

```
                          ┌─────────────────────────────────────┐
                          │        コントロールプレーン            │
                          │                                     │
  kubectl ──HTTP──►  ┌────┴─────┐    ┌───────────────────┐     │
                     │   API    │◄──►│      etcd          │     │
                     │  Server  │    │  (データストア)      │     │
                     └────┬─────┘    └───────────────────┘     │
                          │                                     │
              ┌───────────┼────────────┐                       │
              │           │            │                       │
      ┌───────┴──┐  ┌─────┴────┐  ┌───┴──────┐               │
      │Controller│  │Scheduler │  │  Cloud    │               │
      │ Manager  │  │          │  │Controller │               │
      └──────────┘  └──────────┘  └──────────┘               │
                          └─────────────────────────────────────┘
                          │
              ┌───────────┼────────────┐
              │           │            │
         ┌────┴───┐  ┌───┴────┐  ┌───┴────┐
         │ Node 1 │  │ Node 2 │  │ Node N │
         │kubelet │  │kubelet │  │kubelet │
         │kube-   │  │kube-   │  │kube-   │
         │proxy   │  │proxy   │  │proxy   │
         └────────┘  └────────┘  └────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| エントリーポイント | バイナリの起動・コマンドライン解析 | `cmd/kube-apiserver/apiserver.go` |
| アプリケーション | コマンド構築・サーバ初期化 | `cmd/kube-apiserver/app/` |
| API定義 | リソースの型定義・スキーマ | `pkg/apis/core/types.go` |
| レジストリ | RESTストレージ・CRUD操作 | `pkg/registry/core/pod/storage/storage.go` |
| コントローラ | リコンシリエーションロジック | `pkg/controller/deployment/deployment_controller.go` |
| スケジューラ | Pod配置の決定 | `pkg/scheduler/scheduler.go` |
| Kubelet | ノード上のPod管理 | `pkg/kubelet/kubelet.go` |
| 基盤ライブラリ | API機構・シリアライズ | `staging/src/k8s.io/apimachinery/` |
| クライアント | API Server通信 | `staging/src/k8s.io/client-go/` |

### 5.3 データフロー

Kubernetesにおけるデータの流れは以下の通りです。

1. **ユーザ操作**: `kubectl` がYAML/JSONをAPI Serverに送信
2. **API Server**: リクエストを認証・認可・バリデーション後、etcdに保存
3. **Informerによる通知**: Controller Manager/Scheduler内のInformerがAPI Serverをwatch し、変更を検知
4. **コントローラのリコンシリエーション**: 望ましい状態と現在の状態を比較し、差分を解消するためにAPI Serverに更新を送信
5. **スケジューリング**: 未スケジュールのPodをSchedulerが検知し、最適なノードを選択してバインディング
6. **Kubelet**: 自ノードに割り当てられたPodの変更を検知し、コンテナランタイムを通じてコンテナを起動・停止

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

全てのKubernetesバイナリは `cmd/<バイナリ名>/` にエントリーポイントを持ちます。共通パターンとして、`app.NewXxxCommand()` でCobraコマンドを生成し、`cli.Run()` で実行します。

```go
// ファイル: cmd/kube-apiserver/apiserver.go:32-36
func main() {
	command := app.NewAPIServerCommand()
	code := cli.Run(command)
	os.Exit(code)
}
```

```go
// ファイル: cmd/kubelet/kubelet.go:35-39
func main() {
	command := app.NewKubeletCommand(context.Background())
	code := cli.Run(command)
	os.Exit(code)
}
```

```go
// ファイル: cmd/kube-controller-manager/controller-manager.go:34-38
func main() {
	command := app.NewControllerManagerCommand()
	code := cli.Run(command)
	os.Exit(code)
}
```

### 6.2 ビジネスロジック

Kubernetesの中核ビジネスロジックはコントローラに集約されています。`pkg/controller/` 配下に各リソースのコントローラが配置されています。

主要なコントローラ:

| コントローラ | パス | 役割 |
|------------|------|------|
| Deployment | `pkg/controller/deployment/` | Deploymentリソースの管理（ローリングアップデート等） |
| ReplicaSet | `pkg/controller/replicaset/` | ReplicaSetの管理（Pod数の維持） |
| StatefulSet | `pkg/controller/statefulset/` | ステートフルアプリケーションの管理 |
| DaemonSet | `pkg/controller/daemon/` | 全ノードへのPod配置 |
| Job/CronJob | `pkg/controller/job/`, `pkg/controller/cronjob/` | バッチ処理の管理 |
| Namespace | `pkg/controller/namespace/` | Namespace削除時のリソースクリーンアップ |
| GarbageCollector | `pkg/controller/garbagecollector/` | 不要リソースの回収 |

```go
// ファイル: pkg/controller/deployment/deployment_controller.go:65-101
type DeploymentController struct {
	rsControl controller.RSControlInterface
	client    clientset.Interface

	eventBroadcaster record.EventBroadcaster
	eventRecorder    record.EventRecorder

	syncHandler       func(ctx context.Context, dKey string) error
	enqueueDeployment func(deployment *apps.Deployment)

	dLister  appslisters.DeploymentLister
	rsLister appslisters.ReplicaSetLister
	podLister corelisters.PodLister

	queue workqueue.TypedRateLimitingInterface[string]
}
```

### 6.3 データアクセス

Kubernetesはetcdをデータストアとして使用し、API Serverのレジストリ層がCRUD操作を提供します。

```go
// ファイル: pkg/registry/core/pod/storage/storage.go:54-60
type PodStorage struct {
	Pod                 *REST
	Binding             *BindingREST
	LegacyBinding       *LegacyBindingREST
	Eviction            *EvictionREST
	Status              *StatusREST
	EphemeralContainers *EphemeralContainersREST
}
```

レジストリの構造:
- `pkg/registry/<APIグループ>/<リソース>/` にリソースごとの戦略（Strategy）とストレージを配置
- `strategy.go` でCreate/Update/Delete時のバリデーションやデフォルト値設定を定義
- `storage/storage.go` でREST APIのエンドポイントを構築

### 6.4 ユーティリティ/共通機能

| パッケージ | パス | 説明 |
|-----------|------|------|
| component-base | `staging/src/k8s.io/component-base/` | CLI基盤、メトリクス、ログ |
| apimachinery | `staging/src/k8s.io/apimachinery/` | API基盤（型、シリアライズ、スキーマ） |
| client-go | `staging/src/k8s.io/client-go/` | API Serverクライアント、Informer、WorkQueue |
| klog | 外部パッケージ `k8s.io/klog/v2` | 構造化ログライブラリ |
| controller utils | `pkg/controller/controller_utils.go` | コントローラ共通ユーティリティ |

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Controller Reconciliation Loop | Informer + WorkQueue + sync関数 | 高 | `pkg/controller/deployment/deployment_controller.go` |
| Informer / Lister | API Serverのwatchをキャッシュ化 | 高 | 全コントローラ |
| REST Storage | リソースのCRUD操作を実装 | 高 | `pkg/registry/core/pod/storage/storage.go` |
| Feature Gate | 機能のフラグ管理 | 高 | `pkg/features/` |
| Cobra Command | CLIコマンド構築 | 中 | `cmd/*/app/` |
| Code Generation | deepcopy, client, informer等の自動生成 | 中 | `zz_generated.*.go` |

### 各パターンの詳細

#### パターン1: Controller Reconciliation Loop

**目的:** リソースの望ましい状態と実際の状態を継続的に比較・調整する

**実装例:**
```go
// ファイル: pkg/controller/deployment/deployment_controller.go:104-167
func NewDeploymentController(ctx context.Context, dInformer appsinformers.DeploymentInformer,
	rsInformer appsinformers.ReplicaSetInformer, podInformer coreinformers.PodInformer,
	client clientset.Interface) (*DeploymentController, error) {

	dc := &DeploymentController{
		client: client,
		queue: workqueue.NewTypedRateLimitingQueueWithConfig(
			workqueue.DefaultTypedControllerRateLimiter[string](),
			workqueue.TypedRateLimitingQueueConfig[string]{Name: "deployment"},
		),
	}

	dInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc:    func(obj interface{}) { dc.addDeployment(logger, obj) },
		UpdateFunc: func(oldObj, newObj interface{}) { dc.updateDeployment(logger, oldObj, newObj) },
		DeleteFunc: func(obj interface{}) { dc.deleteDeployment(logger, obj) },
	})

	dc.syncHandler = dc.syncDeployment
	return dc, nil
}
```

**解説:**
1. コンストラクタでInformerにイベントハンドラ（Add/Update/Delete）を登録
2. イベント発生時にリソースのキーをWorkQueueに投入
3. ワーカーゴルーチンがキューからキーを取り出し、`syncHandler` を呼び出す
4. `syncHandler` 内で現在の状態を取得し、望ましい状態に調整する

#### パターン2: Informer / Lister

**目的:** API Serverへのwatch接続を一本化し、ローカルキャッシュからの高速な読み取りを実現する

**実装例:**
```go
// ファイル: pkg/controller/deployment/deployment_controller.go:155-160
dc.dLister = dInformer.Lister()
dc.rsLister = rsInformer.Lister()
dc.podLister = podInformer.Lister()
dc.dListerSynced = dInformer.Informer().HasSynced
dc.rsListerSynced = rsInformer.Informer().HasSynced
```

**解説:**
- `Lister()` はInformerのローカルキャッシュを読み取るインターフェースを返す
- `HasSynced` はキャッシュがAPI Serverと初回同期完了したかを確認するフラグ
- ワーカー開始前に `WaitForNamedCacheSyncWithContext` でキャッシュ同期を待つ

#### パターン3: REST Storage

**目的:** API ServerでリソースのCRUD操作を統一的に提供する

**実装例:**
```go
// ファイル: pkg/registry/core/pod/storage/storage.go:54-60
type PodStorage struct {
	Pod                 *REST
	Binding             *BindingREST
	LegacyBinding       *LegacyBindingREST
	Eviction            *EvictionREST
	Status              *StatusREST
	EphemeralContainers *EphemeralContainersREST
}
```

**解説:**
- メインリソース（Pod）に加え、サブリソース（Status, Binding等）をまとめて管理
- 各REST構造体は `rest.Storage` インターフェースを実装
- Strategy パターンにより、Create/Update時のバリデーション・デフォルト値設定をカスタマイズ

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイント（`cmd/` 配下）を特定
2. `app.NewXxxCommand()` でアプリケーション初期化を追跡
3. Informerの登録とイベントハンドラの設定を確認
4. `syncHandler` / `reconcile` のロジックを追跡
5. API Server呼び出し（Create/Update/Delete）を確認

### 8.2 フロー追跡の実例

#### 例1: Deployment作成からPod起動までのフロー

**概要:** ユーザが `kubectl apply -f deployment.yaml` を実行してから、実際にPodが起動するまでの処理フロー

**処理フロー:**
```
kubectl → API Server → etcd保存 → DeploymentController → ReplicaSetController → Scheduler → Kubelet → コンテナ起動
```

**詳細な追跡:**

1. **API Server がDeploymentを受信・保存** (`cmd/kube-apiserver/apiserver.go:32-36`)
   ```go
   func main() {
       command := app.NewAPIServerCommand()
       code := cli.Run(command)
       os.Exit(code)
   }
   ```
   API Serverはリクエストを認証・認可し、`pkg/registry/` のストレージ層を通じてetcdに保存します。

2. **DeploymentController がイベントを検知** (`pkg/controller/deployment/deployment_controller.go:123-134`)
   ```go
   dInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
       AddFunc: func(obj interface{}) {
           dc.addDeployment(logger, obj)
       },
   })
   ```
   InformerがAPI ServerのwatchストリームからDeployment作成イベントを受け取ります。

3. **DeploymentController がキューに追加** (`pkg/controller/deployment/deployment_controller.go:201-204`)
   ```go
   func (dc *DeploymentController) addDeployment(logger klog.Logger, obj interface{}) {
       d := obj.(*apps.Deployment)
       logger.V(4).Info("Adding deployment", "deployment", klog.KObj(d))
       dc.enqueueDeployment(d)
   }
   ```

4. **ワーカーがキューから取り出しsyncを実行** (`pkg/controller/deployment/deployment_controller.go:171-198`)
   ```go
   func (dc *DeploymentController) Run(ctx context.Context, workers int) {
       // ...
       for i := 0; i < workers; i++ {
           wg.Go(func() {
               wait.UntilWithContext(ctx, dc.worker, time.Second)
           })
       }
       <-ctx.Done()
   }
   ```
   ワーカーが `syncDeployment` を呼び出し、ReplicaSetを作成します。

5. **Scheduler がPodを検知しノードに割り当て** (`pkg/scheduler/scheduler.go:66-79`)
   ```go
   type Scheduler struct {
       Cache internalcache.Cache
       Extenders []fwk.Extender
       NextPod func(logger klog.Logger) (*framework.QueuedPodInfo, error)
   }
   ```
   未スケジュールのPodをキューから取り出し、フィルタ/スコアプラグインで最適なノードを選択します。

6. **Kubelet がPodを起動** (`pkg/kubelet/kubelet.go`)
   Kubeletは自ノードにバインドされたPodの変更を検知し、コンテナランタイム（CRI）を通じてコンテナを起動します。

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイント（`cmd/<バイナリ名>/`）を特定したか
- [ ] `app.NewXxxCommand()` からサーバ初期化を追跡したか
- [ ] Informerのイベントハンドラ登録を確認したか
- [ ] `syncHandler` / リコンシリエーションロジックを確認したか
- [ ] エラーハンドリング（retry, requeue）を確認したか
- [ ] 最終的なAPI Server呼び出しを確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` -- プロジェクト概要
2. `cmd/` ディレクトリ一覧 -- 各バイナリの役割把握
3. `pkg/` ディレクトリ一覧 -- 主要コンポーネントの把握
4. Kubernetes公式ドキュメント (https://kubernetes.io/docs/concepts/architecture/)

#### 特定機能を理解したい場合
1. `pkg/apis/<グループ>/types.go` -- リソースの型定義
2. `pkg/registry/<グループ>/<リソース>/` -- ストレージとバリデーション
3. `pkg/controller/<コントローラ>/` -- リコンシリエーションロジック
4. `test/integration/` -- 結合テストで動作を確認

#### 改修作業を行う場合
1. 対象コンポーネントの `OWNERS` ファイル -- レビュアーの確認
2. `hack/` ディレクトリ -- コード生成・検証ツールの確認
3. `test/e2e/` -- 関連するE2Eテストの確認
4. `CONTRIBUTING.md` -- 貢献ガイドライン

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要・ビルド手順 | 初回参照 |
| `CONTRIBUTING.md` | 貢献ガイドライン | コード変更時 |
| `OWNERS` | 各ディレクトリのコードオーナー | レビュー依頼時 |
| `CHANGELOG.md` | 変更履歴 | バージョン確認時 |
| `hack/` | 開発用スクリプト群 | ビルド・コード生成時 |
| `api/openapi-spec/` | OpenAPI仕様 | API仕様確認時 |
| `SUPPORT.md` | サポート情報 | 問い合わせ時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `staging/` と `pkg/` の関係がわかりません
A: `staging/` 配下のパッケージは独立したGoモジュールとして外部にも公開されるライブラリです（例: `client-go`, `apimachinery`）。`pkg/` は `k8s.io/kubernetes` モジュール内部でのみ使用されるコードです。`go.work` ファイルにより、開発時はローカルの `staging/` を参照しますが、リリース時にはそれぞれ独立したリポジトリとして公開されます。

#### Q: `zz_generated.*.go` ファイルは何ですか
A: コード生成ツールが自動生成したファイルです。手動で編集してはいけません。主な生成物は以下の通りです:
- `zz_generated.deepcopy.go`: DeepCopyメソッドの自動実装
- `zz_generated.defaults.go`: デフォルト値設定の自動実装
- `zz_generated.conversion.go`: バージョン間の型変換

#### Q: APIのバージョン（v1, v1beta1等）はどのように管理されていますか
A: `pkg/apis/<グループ>/` に内部表現（internal version）が定義され、`staging/src/k8s.io/api/<グループ>/<バージョン>/` に各バージョンの外部表現があります。変換関数により内部表現と各バージョン間を相互変換します。

#### Q: `OWNERS` ファイルの役割は何ですか
A: 各ディレクトリの承認者（approvers）とレビュアー（reviewers）を定義するファイルです。PRのレビュー・承認プロセスで使用されます。

#### Q: テストはどのように構成されていますか
A: テストは3つのレベルに分類されます:
- **単体テスト**: `*_test.go` ファイル（各パッケージ内）
- **結合テスト**: `test/integration/` -- API Serverを起動して検証
- **E2Eテスト**: `test/e2e/` -- 実際のクラスタ上で検証

### デバッグのヒント

- **ログレベル**: `klog.V(N)` でログレベルを制御。`V(4)` は詳細デバッグ情報
- **ビルド**: `make WHAT=cmd/kube-apiserver` で特定バイナリのみビルド可能
- **テスト実行**: `make test WHAT=./pkg/controller/deployment/` で特定パッケージのテスト実行
- **コード生成**: `hack/update-codegen.sh` でコード生成ツールを実行
- **依存管理**: `hack/update-vendor.sh` で依存ライブラリを更新

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| GVK | Group, Version, Kind -- APIリソースの一意識別子 |
| Informer | API Serverのwatchを抽象化し、ローカルキャッシュを提供する仕組み |
| Lister | Informerキャッシュからリソースを読み取るインターフェース |
| WorkQueue | コントローラの処理キュー。Rate Limiting付きで再試行を制御 |
| Reconciliation | 望ましい状態と現在の状態を比較・調整するプロセス |
| Scheme | APIリソースの型登録・変換・デフォルト値設定を管理する仕組み |
| Strategy | REST Storage におけるCRUD操作のカスタマイズポイント |
| Feature Gate | 機能のON/OFFを制御するフラグ機構 |
| CRI | Container Runtime Interface -- コンテナランタイムとの通信規約 |
| CSI | Container Storage Interface -- ストレージプラグインの通信規約 |
| etcd | Kubernetesのバックエンドデータストア（分散KVS） |
| staging | メインリポジトリ内で管理される独立公開モジュール群 |
| vendor | Go の vendoring 機構。依存をリポジトリ内に保持 |
| OWNERS | コードオーナーシップを定義するファイル |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `cmd/kube-apiserver/` | API Serverエントリーポイント | `apiserver.go`, `app/` |
| `cmd/kube-controller-manager/` | Controller Managerエントリーポイント | `controller-manager.go`, `app/` |
| `cmd/kube-scheduler/` | Schedulerエントリーポイント | `scheduler.go`, `app/` |
| `cmd/kubelet/` | Kubeletエントリーポイント | `kubelet.go`, `app/` |
| `cmd/kubectl/` | kubectl CLIエントリーポイント | `kubectl.go` |
| `pkg/apis/core/types.go` | Coreグループの内部API型定義 | Pod, Service, Namespace等 |
| `pkg/controller/deployment/` | Deploymentコントローラ | `deployment_controller.go` |
| `pkg/registry/core/pod/storage/` | Pod RESTストレージ | `storage.go` |
| `pkg/scheduler/scheduler.go` | スケジューラ本体 | Scheduler構造体、スケジューリングロジック |
| `pkg/kubelet/kubelet.go` | Kubelet本体 | Pod管理、CRI通信 |
| `staging/src/k8s.io/apimachinery/` | API基盤ライブラリ | TypeMeta, ObjectMeta, Scheme |
| `staging/src/k8s.io/client-go/` | Goクライアントライブラリ | Informer, Lister, WorkQueue |
| `go.mod` | Goモジュール定義 | 依存パッケージ一覧 |
| `Makefile` | ビルドターゲット定義 | `make`, `make test`, `make clean` |

### C. 参考資料

- Go言語公式ドキュメント: https://go.dev/doc/
- Kubernetes公式ドキュメント: https://kubernetes.io/docs/
- Kubernetes Developer Guide: https://github.com/kubernetes/community/tree/master/contributors/devel
- API Conventions: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
- client-go ドキュメント: https://pkg.go.dev/k8s.io/client-go
- controller-runtime (参考): https://pkg.go.dev/sigs.k8s.io/controller-runtime
