# アーキテクチャ設計書

## 概要

本ドキュメントは、Kubernetes（k8s.io/kubernetes）のアプリケーションアーキテクチャを記述する設計書である。Kubernetesはコンテナオーケストレーションプラットフォームであり、Go言語で実装されたマイクロサービス的な分散システムである。主要コンポーネントとして kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy を持ち、それぞれが独立したバイナリとして動作する。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図](./アーキテクチャ構成図.md) を参照。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| etcd | gRPC (etcd3 client) | クラスタ状態の永続化ストレージ。全リソースの保存先 |
| Container Runtime (containerd, CRI-O等) | gRPC (CRI: Container Runtime Interface) | コンテナのライフサイクル管理 |
| Cloud Provider API | REST API (cloud-provider インターフェース) | ノード管理、ロードバランサー、ストレージプロビジョニング |
| CSI Driver | gRPC (CSI: Container Storage Interface) | 永続ボリュームのプロビジョニング・アタッチ・マウント |
| CNI Plugin | exec (CNI: Container Network Interface) | Pod ネットワークの構成 |
| External OIDC Provider | HTTPS (OpenID Connect) | ユーザー認証（トークン検証） |
| Webhook Server | HTTPS (Admission Webhook) | カスタム Admission Control |
| Metrics Collector (Prometheus等) | HTTP (/metrics エンドポイント) | メトリクス収集 |
| Aggregated API Server | HTTPS (API Aggregation) | カスタム API の拡張 |

## レイヤー構成

### アーキテクチャスタイル

Kubernetes は**コンポーネントベースの分散アーキテクチャ**を採用している。各コンポーネントは独立プロセスとして動作し、kube-apiserver を中心としたハブ・アンド・スポーク型の通信パターンを持つ。内部的には各コンポーネントが以下のレイヤー構造を持つ。

- **API Server**: RESTful API レイヤー + Storage レイヤー（Registry パターン）
- **Controller / Scheduler**: コントロールループパターン（Reconciliation Loop）
- **Kubelet**: エージェントパターン（ノード上のコンテナ管理）

全体として「宣言的 API + コントロールループ」というKubernetes固有のアーキテクチャパターンに基づく。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| API / Presentation | REST API エンドポイントの提供、リクエストのルーティング、認証・認可・Admission Control | `staging/src/k8s.io/apiserver/pkg/endpoints/`, `pkg/registry/` |
| Control Plane Logic | コントローラーによる宣言的状態の調整（Reconciliation）、スケジューリング | `pkg/controller/`, `pkg/scheduler/`, `pkg/controlplane/` |
| Domain / API Types | Kubernetes API オブジェクトの型定義、バリデーション、デフォルト値設定 | `staging/src/k8s.io/api/`, `pkg/apis/`, `staging/src/k8s.io/apimachinery/` |
| Storage / Infrastructure | etcd への永続化、キャッシュ、ストレージバックエンド抽象化 | `staging/src/k8s.io/apiserver/pkg/storage/`, `staging/src/k8s.io/apiserver/pkg/storage/etcd3/` |
| Node Agent | ノード上のコンテナライフサイクル管理、Pod の実行 | `pkg/kubelet/`, `cmd/kubelet/` |
| Client | API Server への通信抽象化、Informer / Lister によるキャッシュ | `staging/src/k8s.io/client-go/` |

### レイヤー間の依存関係ルール

- **全コンポーネントは kube-apiserver を介して通信する**: 直接的なコンポーネント間通信は原則禁止。
- **pkg/ は staging/ のパッケージに依存可能**: `staging/src/k8s.io/` 配下のライブラリは独立して公開される共有ライブラリであり、`pkg/` はこれらに依存する。
- **staging/ 内のパッケージは pkg/ に依存しない**: 共有ライブラリの独立性を維持するため。
- **cmd/ はアプリケーションのエントリーポイント**: `cmd/` は `pkg/` と `staging/` の両方に依存し、コンポーネントを組み立てる。
- **vendor/ による依存管理**: 全ての外部依存は `vendor/` ディレクトリに固定される。

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| API Server | REST API の提供、認証・認可・Admission、etcd 永続化 | `cmd/kube-apiserver/`, `pkg/controlplane/`, `pkg/registry/`, `pkg/kubeapiserver/` |
| Controller Manager | 組み込みコントローラーの管理・実行 | `cmd/kube-controller-manager/`, `pkg/controller/` |
| Scheduler | Pod のノード割り当て | `cmd/kube-scheduler/`, `pkg/scheduler/` |
| Kubelet | ノード上のPod・コンテナ管理 | `cmd/kubelet/`, `pkg/kubelet/` |
| Kube-Proxy | Service のネットワークプロキシ (iptables/ipvs/nftables) | `cmd/kube-proxy/`, `pkg/proxy/` |
| Cloud Controller Manager | クラウドプロバイダー固有の制御ロジック | `cmd/cloud-controller-manager/`, `staging/src/k8s.io/cloud-provider/` |
| kubectl | CLI クライアント | `cmd/kubectl/`, `staging/src/k8s.io/kubectl/` |
| kubeadm | クラスタブートストラップツール | `cmd/kubeadm/` |
| API Machinery | API オブジェクトのスキーマ、シリアライズ、バージョニング | `staging/src/k8s.io/apimachinery/` |
| Client Go | Go クライアントライブラリ（Informer, Lister, RESTClient） | `staging/src/k8s.io/client-go/` |

### パッケージ構造

```
kubernetes-master/
├── api/                          # OpenAPI仕様、APIルール定義
│   ├── api-rules/
│   ├── discovery/
│   └── openapi-spec/
├── cmd/                          # 各コンポーネントのエントリーポイント
│   ├── kube-apiserver/
│   ├── kube-controller-manager/
│   ├── kube-scheduler/
│   ├── kubelet/
│   ├── kube-proxy/
│   ├── cloud-controller-manager/
│   ├── kubectl/
│   ├── kubeadm/
│   └── kubemark/
├── pkg/                          # コア実装
│   ├── api/                      # 内部APIヘルパー
│   ├── apis/                     # 内部API型定義
│   ├── auth/                     # 認可ヘルパー
│   ├── controller/               # 組み込みコントローラー群
│   ├── controlplane/             # コントロールプレーン構成
│   ├── kubelet/                  # Kubelet実装
│   ├── proxy/                    # kube-proxy実装
│   ├── registry/                 # API リソースのストレージ（Registry）
│   ├── scheduler/                # スケジューラ実装
│   ├── security/                 # セキュリティユーティリティ
│   ├── serviceaccount/           # ServiceAccount管理
│   └── volume/                   # ボリュームプラグイン
├── plugin/                       # プラグインフレームワーク
│   └── pkg/
├── staging/src/k8s.io/           # 独立公開される共有ライブラリ
│   ├── api/                      # 公開API型定義
│   ├── apimachinery/             # APIフレームワーク基盤
│   ├── apiserver/                # 汎用APIサーバーフレームワーク
│   ├── client-go/                # Goクライアントライブラリ
│   ├── cloud-provider/           # クラウドプロバイダーインターフェース
│   ├── controller-manager/       # コントローラーマネージャー基盤
│   ├── cri-api/                  # Container Runtime Interface定義
│   ├── kube-aggregator/          # API Aggregationレイヤー
│   ├── kube-scheduler/           # スケジューラーフレームワーク
│   ├── kubectl/                  # kubectl実装
│   ├── kubelet/                  # Kubelet API型定義
│   └── metrics/                  # メトリクスライブラリ
├── test/                         # E2Eテスト・統合テスト
├── hack/                         # ビルド・開発ユーティリティスクリプト
├── build/                        # ビルド設定
├── third_party/                  # サードパーティコード
└── vendor/                       # 依存パッケージ（vendoring）
```

### コンポーネント依存関係

主要コンポーネントの依存関係は以下の通り。

1. **kube-apiserver** は etcd に依存し、全コンポーネントの通信ハブとなる。
2. **kube-controller-manager** は client-go を介して kube-apiserver に接続し、Informer で状態を監視する。
3. **kube-scheduler** は client-go を介して kube-apiserver に接続し、未スケジュールの Pod を監視・割り当てる。
4. **kubelet** は client-go を介して kube-apiserver に接続し、CRI を介してコンテナランタイムと通信する。
5. **kube-proxy** は client-go を介して kube-apiserver に接続し、Service のネットワークルールを設定する。
6. 全コンポーネントは `staging/src/k8s.io/` 配下の共有ライブラリ（apimachinery, client-go, component-base 等）に依存する。

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| KVS | etcd | v3 (etcd3 プロトコル) | 全 Kubernetes リソースの永続化ストレージ。kube-apiserver のみがアクセスする |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| Informer Cache (in-process) | client-go 内蔵 | 各コンポーネントにおける API オブジェクトのローカルキャッシュ | Watch による継続的同期 |
| API Server Cacher | apiserver/pkg/storage/cacher | etcd Watch 結果のインメモリキャッシュ | Watch 接続維持中は常時更新 |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Work Queue (in-process) | client-go/util/workqueue | コントローラー内のイベント処理キュー（rate limiting, delayed requeue対応） |

Kubernetes は外部メッセージキューを使用しない。代わりに、etcd の Watch メカニズムと client-go の Informer/WorkQueue パターンにより、イベント駆動のコントロールループを実現している。

### 検索エンジン

該当なし。Kubernetes は全リソースを etcd に保存し、API Server のフィールドセレクター・ラベルセレクターで検索を行う。

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Prometheus client_golang | v1.23.2 | メトリクスの公開 (/metrics エンドポイント) |
| gRPC | - | etcd通信、CRI通信、CSI通信 |
| cobra | - | CLI フレームワーク（全コンポーネントのコマンドライン処理） |
| go-restful/v3 | v3.13.0 | kube-apiserver の REST API フレームワーク |
| klog/v2 | - | 構造化ロギングライブラリ |
| CEL (cel-go) | v0.26.0 | Admission Policy / Validation 用の式評価エンジン |

## データフロー

### リクエスト処理の流れ

kube-apiserver における API リクエストの処理フロー:

1. **HTTP リクエスト受信**: go-restful ベースの HTTP ハンドラがリクエストを受信
2. **認証 (Authentication)**: トークン認証、クライアント証明書認証、OIDC 等で呼び出し元を識別（`apiserver/pkg/authentication/`）
3. **認可 (Authorization)**: RBAC / ABAC / Webhook / Node authorizer で操作権限を検証（`apiserver/pkg/authorization/`）
4. **Admission Control (Mutating)**: MutatingAdmissionWebhook、デフォルト値設定等（`apiserver/pkg/admission/`）
5. **バリデーション**: API オブジェクトのスキーマバリデーション
6. **Admission Control (Validating)**: ValidatingAdmissionWebhook、ValidatingAdmissionPolicy (CEL)
7. **Registry 処理**: `pkg/registry/` の Strategy パターンにより CRUD 操作を実行
8. **Storage 永続化**: `apiserver/pkg/storage/etcd3/` を介して etcd に読み書き
9. **レスポンス返却**: 結果を JSON/Protobuf でシリアライズして返却

### 非同期処理の流れ

コントローラーによる Reconciliation Loop:

1. **Informer 起動**: client-go の SharedInformer が kube-apiserver の Watch API に接続
2. **イベント受信**: リソースの追加・更新・削除イベントを受信し、ローカルキャッシュを更新
3. **Work Queue エンキュー**: イベントハンドラがオブジェクトのキーを Work Queue に投入
4. **Worker による処理**: Worker goroutine が Queue からキーを取り出し、Reconcile ロジックを実行
5. **状態更新**: 必要に応じて kube-apiserver に API コールを発行し、リソースの Status を更新
6. **リトライ**: 処理失敗時は指数バックオフ付きで Work Queue に再投入

### データ永続化の流れ

1. kube-apiserver が API リクエストを処理し、Registry レイヤーで Storage インターフェースを呼び出す
2. Storage レイヤー（`apiserver/pkg/storage/etcd3/`）が etcd3 gRPC クライアントを使用して etcd にデータを書き込む
3. データはキー・バリュー形式で保存される（キー: `/registry/{resource}/{namespace}/{name}`）
4. etcd の Watch メカニズムにより、変更は即座に Informer Cache を通じて各コンポーネントに伝播する
5. API Server 内の Cacher レイヤーが Watch イベントをキャッシュし、クライアントの List/Watch 負荷を軽減する

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| X.509 クライアント証明書 | `apiserver/pkg/authentication/` | コンポーネント間通信（kubelet, controller-manager等） |
| Bearer Token (Static Token, Bootstrap Token) | `apiserver/pkg/authentication/token/` | サービスアカウント、ブートストラップ |
| OpenID Connect (OIDC) | `apiserver/pkg/authentication/` (coreos/go-oidc) | 外部IDプロバイダーによるユーザー認証 |
| ServiceAccount Token (JWT) | `pkg/serviceaccount/` | Pod 内からの API アクセス |
| RBAC (Role-Based Access Control) | `plugin/pkg/auth/authorizer/rbac/`, `pkg/registry/rbac/` | リソースへのアクセス制御 |
| Node Authorizer | `plugin/pkg/auth/authorizer/node/` | kubelet のアクセスを自ノード関連リソースに制限 |
| Webhook Authorizer | `apiserver/pkg/authorization/` | 外部認可サービスへの委任 |
| Admission Control | `apiserver/pkg/admission/`, `plugin/pkg/admission/` | リソース作成・更新時の追加検証・変更 |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | klog/v2 による構造化ログ出力 | 標準出力 / 標準エラー出力 |
| 監査ログ | Audit Policy に基づくリクエスト/レスポンスの記録 (`apiserver/pkg/audit/`) | ファイル / Webhook |
| アクセスログ | apiserver の httplog パッケージ (`apiserver/pkg/server/httplog/`) | 標準出力 |
| メトリクス | Prometheus client_golang による /metrics エンドポイント | Prometheus 等の外部コレクター |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| バリデーションエラー | API Server の Registry/Strategy がフィールドバリデーションを実行 | 422 Unprocessable Entity (StatusReasonInvalid) |
| 認証エラー | Authentication フィルターチェーンで検出 | 401 Unauthorized |
| 認可エラー | Authorization フィルターで検出 | 403 Forbidden |
| リソース未検出 | Storage レイヤーの NotFound エラー | 404 Not Found |
| コンフリクト (楽観的ロック) | etcd の ResourceVersion 不一致 | 409 Conflict |
| Admission 拒否 | Admission Webhook / Policy による拒否 | 403 Forbidden |
| 内部エラー | panic recovery ミドルウェア + エラーレスポンス生成 | 500 Internal Server Error |
| コントローラーエラー | Work Queue への requeue (指数バックオフ) | - (非同期リトライ) |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| 単一リソース操作 | etcd の楽観的並行制御 (ResourceVersion による CAS) | Serializable (単一キー) |
| 複数リソース操作 | コントローラーによる最終的整合性 (Eventual Consistency) | 結果整合性 |
| リーダー選出 | client-go/tools/leaderelection (Lease リソースベース) | - |

Kubernetes は分散トランザクションを使用しない。代わりに、宣言的 API と Reconciliation Loop により最終的整合性を保証するアーキテクチャを採用している。

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 宣言的 API | 全 API リソース | ユーザーは Desired State を宣言し、コントローラーが Current State を調整 |
| コントロールループ (Reconciliation) | 全コントローラー | `pkg/controller/` 配下の各コントローラーが Watch + Reconcile パターンを実装 |
| レベルトリガー (Level-triggered) | Informer / Controller | エッジトリガーでなくレベルトリガーにより、イベント喪失に対する耐性を確保 |
| API Machinery パターン | API 型定義 | Group/Version/Kind (GVK) による API バージョニング、Internal/External 型変換 |
| Strategy パターン | pkg/registry/ | 各リソースの CRUD ロジックを Strategy インターフェースで抽象化 |
| Plugin アーキテクチャ | Scheduler Framework, Admission, Volume | プラグインインターフェースを定義し、拡張可能な設計 |
| Interface 分離 | staging/ パッケージ | CRI, CSI, CNI 等の標準インターフェースで実装を交換可能に |
| Dependency Injection | コンポーネント初期化 | `cmd/` のアプリケーション組み立て時にインターフェースの実装を注入 |

### コーディング規約

- **Go 言語標準**: Go 1.25 を使用。Go の標準的なコーディングスタイル・ディレクトリ構成に準拠。
- **staging リポジトリパターン**: 共有ライブラリは `staging/src/k8s.io/` に配置し、独立したモジュールとして公開される。
- **生成コード**: `pkg/generated/`, `staging/*/generated/` に OpenAPI、DeepCopy、Informer、Lister のコードが自動生成される。
- **Feature Gate**: 新機能は `pkg/features/` で Feature Gate として定義し、段階的に有効化する。
- **API バージョニング**: Alpha (v1alpha1) -> Beta (v1beta1) -> GA (v1) の段階的な API 成熟プロセス。
- **テスト**: 単体テスト (`_test.go`)、統合テスト (`test/integration/`)、E2Eテスト (`test/e2e/`) の3層テスト構造。
- **オーナーシップ**: 各ディレクトリに `OWNERS` ファイルを配置し、コードレビューの責任範囲を明確化。

## 備考

- Kubernetes は極めて大規模なプロジェクト（Go モジュール `k8s.io/kubernetes`）であり、`staging/` ディレクトリのパッケージは個別の Go モジュールとして公開され、外部プロジェクトから利用可能である。
- `vendor/` ディレクトリによる依存管理を採用しており、`go.work` による Go Workspace 機能も併用している。
- `hack/` ディレクトリにはビルド、コード生成、検証用のスクリプトが多数含まれる。
- `build/` ディレクトリにはコンテナイメージビルド用の設定が含まれる。
