# 機能設計書 64-証明書管理

## 概要

本ドキュメントは、Kubeletのクライアント/サーバー証明書のローテーション管理機能の設計を記述する。

### 本機能の処理概要

Kubeletの証明書管理機能は、API Serverとの通信に使用するクライアント証明書およびKubelet自身のサーバー証明書のライフサイクル（生成、ローテーション、監視）を管理するコンポーネントである。

**業務上の目的・背景**：Kubernetesクラスターのセキュリティにおいて、TLS証明書による通信の暗号化と認証は必須である。証明書は有効期限があるため、自動的にローテーションする仕組みがなければ、期限切れによりノードが通信不能になる。本機能はCertificateSigningRequest（CSR）を通じた自動証明書更新を提供する。

**機能の利用シーン**：(1) Kubeletの初回起動時のブートストラップ証明書による認証、(2) クライアント証明書の有効期限が近づいた際の自動ローテーション、(3) サーバー証明書の自動更新、(4) 証明書ファイルの動的監視・リロード。

**主要な処理内容**：
1. クライアント証明書マネージャの初期化とCSRベースのローテーション設定
2. サーバー証明書マネージャの初期化とCSRベースまたはファイルベースの証明書管理
3. ノードアドレス（IP/DNS）に基づくCSRテンプレートの動的生成
4. 証明書のTTL監視とメトリクス公開
5. 証明書ファイルの動的変更検出とリロード

**関連システム・外部連携**：API Server（CSR API）、ファイルシステム（証明書ストア）、Certificate署名コントローラー。

**権限による制御**：CSR作成にはsystem:node:＜nodename＞のクライアント証明書が必要。サーバー証明書のCSRはkubelet-serving-signerで署名される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLI画面との直接的な関連はなく、Kubelet内部コンポーネントとして動作する |

## 機能種別

セキュリティ管理（証明書のライフサイクル管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| certDirectory | string | Yes | 証明書ファイルの保存ディレクトリ | 有効なディレクトリパス |
| nodeName | types.NodeName | Yes | ノード名 | 有効なノード名 |
| tlsCertFile | string | No | TLS証明書ファイルパス | 有効なファイルパス |
| tlsPrivateKeyFile | string | No | TLS秘密鍵ファイルパス | 有効なファイルパス |
| bootstrapCertData | []byte | No | ブートストラップ証明書データ | X509形式 |
| bootstrapKeyData | []byte | No | ブートストラップ秘密鍵データ | PKCS形式 |

### 入力データソース

- Kubelet設定（KubeletConfiguration）
- ノードアドレス情報（getAddresses関数）
- ファイルシステム上の証明書ファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tls.Certificate | *tls.Certificate | 現在有効なTLS証明書 |
| CSR | CertificateSigningRequest | 証明書署名リクエスト |
| メトリクス | Gauge/Counter/Histogram | 証明書TTL、ローテーション回数、更新エラー |

### 出力先

- ファイルシステム: 証明書ストア（kubelet-client-*, kubelet-server-*）
- API Server: CertificateSigningRequest API
- メトリクスエンドポイント: /metrics

## 処理フロー

### 処理シーケンス

```
1. 証明書マネージャ初期化
   └─ FileStore作成 → certificate.NewManager() で証明書マネージャ生成
2. CSRテンプレート生成（サーバー証明書）
   └─ getAddresses()でノードIPとDNS名を取得 → x509.CertificateRequest生成
3. 証明書ローテーション（CSRベース）
   └─ 有効期限の監視 → CSR作成・送信 → 署名された証明書の取得・保存
4. 証明書監視（ファイルベース）
   └─ DynamicCertKeyPairContentでファイル変更検出 → currentTLSCertificate更新
```

### フローチャート

```mermaid
flowchart TD
    A[Kubelet起動] --> B{証明書モード}
    B -->|CSRベース| C[NewKubeletServerCertificateManager]
    B -->|ファイルベース| D[NewKubeletServerCertificateDynamicFileManager]
    C --> E[certificate.NewManager]
    E --> F[CSRテンプレート生成]
    F --> G{IPアドレスあり?}
    G -->|No| H[CSR送信しない]
    G -->|Yes| I[CSR送信]
    I --> J[署名済み証明書取得]
    J --> K[FileStore保存]
    D --> L[ファイル監視開始]
    L --> M[変更検出時に証明書リロード]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-64-01 | CSR Subject | CommonName=system:node:＜nodeName＞、Organization=system:nodes | 全CSR |
| BR-64-02 | サーバー証明書SignerName | KubeletServingSignerName（kubernetes.io/kubelet-serving） | サーバー証明書CSR |
| BR-64-03 | クライアント証明書SignerName | KubeAPIServerClientKubeletSignerName | クライアント証明書CSR |
| BR-64-04 | IP必須（デフォルト） | サーバー証明書CSRにはIPアドレスが必須（AllowDNSOnlyNodeCSR無効時） | サーバー証明書CSR |
| BR-64-05 | DNS許可 | AllowDNSOnlyNodeCSRフィーチャーゲート有効時、DNSのみでもCSR可能 | AllowDNSOnlyNodeCSR有効時 |

### 計算ロジック

- 証明書TTL: `time.Until(c.Leaf.NotAfter).Seconds()`
- 証明書未設定時のTTL: `math.Inf(1)`（無限大）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| CSR作成 | etcd (certificatesigningrequests) | CREATE | 証明書署名リクエストの作成 |
| CSR取得 | etcd (certificatesigningrequests) | GET/WATCH | 署名済み証明書の取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 初期化エラー | FileStore作成失敗 | Kubelet起動失敗 |
| - | CSRエラー | CSR送信/承認失敗 | 自動リトライ（certificate.Manager内部） |
| - | ファイルエラー | 証明書ファイル読み取り失敗 | エラーログ出力、前回の有効な証明書を維持 |
| - | 証明書解析エラー | 無効な証明書/鍵ペア | エラーログ出力 |

### リトライ仕様

certificate.Managerが内部的にCSRのリトライを管理する。リトライ間隔はexponential backoffに基づく。

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

該当なし。証明書ファイルの更新はFileStoreによるアトミックな書き込み（一時ファイル→リネーム）で行われる。

## パフォーマンス要件

- 証明書TTLメトリクスはGaugeFunc（遅延評価）で提供
- 証明書ローテーションは有効期限の一定割合（通常70-90%）経過後に実行

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

- クライアント証明書はノード固有のIdentity（system:node:＜nodename＞）を持つ
- ブートストラップ証明書は初回ローテーション後に使用されなくなる
- 秘密鍵はファイルシステム上にローカル保存され、API Serverには送信されない
- server_expiration_renew_errorsメトリクスで更新失敗を監視可能

## 備考

- ブートストラップ証明書は、kubeadm等で初回参加時に提供される高権限の一時証明書である
- NewKubeletServerCertificateDynamicFileManagerはファイル監視ベースで、API Serverとの通信なしに証明書を管理する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | kubeletServerCertificateDynamicFileManager構造体（275-281行目）: ファイルベース証明書管理 |

**読解のコツ**: certificate.Managerインターフェース（client-goで定義）がCurrent()、Start()、Stop()、ServerHealthy()を提供する。kubelet.goの実装はこのインターフェースの具体実装を提供する。

#### Step 2: サーバー証明書管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | NewKubeletServerCertificateManager（75-156行目）: CSRベースのサーバー証明書管理 |
| 2-2 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | newGetTemplateFn（47-71行目）: CSRテンプレート生成関数 |
| 2-3 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | addressesToHostnamesAndIPs（158-194行目）: ノードアドレスからDNS/IPを抽出 |

**主要処理フロー**:
- **82-88行目**: FileStoreの初期化（証明書の永続化先）
- **125-133行目**: certificate.NewManagerの呼び出し（CSRベースのローテーション設定）
- **137-154行目**: TTLメトリクスGaugeの登録

#### Step 3: クライアント証明書管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | NewKubeletClientCertificateManager（199-254行目）: クライアント証明書管理 |

#### Step 4: ファイルベース証明書管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | NewKubeletServerCertificateDynamicFileManager（259-272行目）: ファイル監視ベース |
| 4-2 | kubelet.go | `pkg/kubelet/certificate/kubelet.go` | Enqueue関数（284-296行目）: ファイル変更通知時の証明書リロード |

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

```
Kubelet起動
    │
    ├─ NewKubeletClientCertificateManager()
    │      └─ certificate.NewManager()
    │             ├─ FileStore (cert保存)
    │             └─ CSR送信 → Certificate署名コントローラー
    │
    ├─ NewKubeletServerCertificateManager()
    │      ├─ newGetTemplateFn()
    │      │      └─ addressesToHostnamesAndIPs()
    │      └─ certificate.NewManager()
    │             ├─ FileStore (cert保存)
    │             └─ CSR送信 → Certificate署名コントローラー
    │
    └─ NewKubeletServerCertificateDynamicFileManager() [代替]
           └─ DynamicServingContentFromFiles()
                  └─ ファイル監視 → Enqueue() → currentTLSCertificate更新
```

### データフロー図

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

ノードアドレス ────────▶ CSRテンプレート生成 ────▶ CSR API送信
CSR署名済み証明書 ────▶ certificate.Manager ───▶ FileStore保存
証明書ファイル変更 ───▶ DynamicFileManager ────▶ currentTLSCertificate
有効期限 ─────────────▶ TTL計算 ────────────────▶ メトリクス公開
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kubelet.go | `pkg/kubelet/certificate/kubelet.go` | ソース | 証明書マネージャの初期化と構成 |
| transport.go | `pkg/kubelet/certificate/transport.go` | ソース | 証明書を使用したHTTPトランスポート |
| kubelet_test.go | `pkg/kubelet/certificate/kubelet_test.go` | テスト | 証明書管理のユニットテスト |
| bootstrap/ | `pkg/kubelet/certificate/bootstrap/` | ソース | ブートストラップ関連処理 |
