# 機能設計書 12-CronJobコントローラー

## 概要

本ドキュメントは、Kubernetes CronJobコントローラーの機能設計を記述する。CronJobコントローラーはCronスケジュールに基づいてJobを定期的に作成・実行する。

### 本機能の処理概要

**業務上の目的・背景**：定期的なバッチ処理（ログローテーション、バックアップ、レポート生成など）をKubernetesネイティブに管理する必要がある。CronJobコントローラーはUNIX cronフォーマットに基づくスケジューリングを提供し、Jobの自動作成とライフサイクル管理を行う。

**機能の利用シーン**：日次バックアップ、定期的なデータクリーンアップ、夜間バッチ処理、定期レポート生成、ヘルスチェックジョブの定期実行など、スケジュールベースのワークロード管理全般。

**主要な処理内容**：
1. CronJobリソースの監視とCronスケジュールの解析
2. スケジュール時刻に基づくJobリソースの自動作成
3. 並行実行ポリシー（Allow/Forbid/Replace）の制御
4. 完了Jobの履歴管理（成功/失敗の保持数制御）
5. CronJobの一時停止（Suspend）対応
6. タイムゾーン指定によるスケジュール制御
7. StartingDeadlineSecondsによるスケジュール遅延の許容制御

**関連システム・外部連携**：API Server（CronJobおよびJobリソースの永続化）、Jobコントローラー（作成されたJobの実行管理）

**権限による制御**：RBACによりCronJob/Jobの作成・削除・更新権限が制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CronJobコントローラーは直接の画面を持たない |

## 機能種別

コントローラー（Reconciliation Loop） / スケジューリング / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| spec.schedule | string | Yes | Cronスケジュール式 | 有効なcron式 |
| spec.timeZone | *string | No | タイムゾーン指定 | 有効なIANAタイムゾーン |
| spec.jobTemplate | JobTemplateSpec | Yes | 作成するJobのテンプレート | - |
| spec.concurrencyPolicy | string | No | Allow/Forbid/Replace | 3値のいずれか |
| spec.suspend | *bool | No | 一時停止フラグ | - |
| spec.startingDeadlineSeconds | *int64 | No | スケジュール遅延の許容時間（秒） | > 0 |
| spec.successfulJobsHistoryLimit | *int32 | No | 成功Job保持数 | >= 0 |
| spec.failedJobsHistoryLimit | *int32 | No | 失敗Job保持数 | >= 0 |

### 入力データソース

- Kubernetes API Server: CronJob Informer
- Kubernetes API Server: Job Informer

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| status.active | []ObjectReference | 実行中のJobへの参照リスト |
| status.lastScheduleTime | *metav1.Time | 最後にスケジュールされた時刻 |
| status.lastSuccessfulTime | *metav1.Time | 最後にJob成功した時刻 |

### 出力先

- Kubernetes API Server: Job作成、CronJobステータス更新

## 処理フロー

### 処理シーケンス

```
1. CronJob/Jobイベント受信
   └─ workqueueにCronJobキーをエンキュー
2. workerがデキューし、sync関数を実行
   └─ CronJobとその子Jobを取得
3. cleanupFinishedJobs: 完了Job履歴のクリーンアップ
   └─ SuccessfulJobsHistoryLimit/FailedJobsHistoryLimitに基づく
4. syncCronJob: メイン同期処理
   a. activeリストの更新（完了Job除去、欠落Job追加）
   b. suspend/timezone/scheduleの検証
   c. 次回スケジュール時刻の計算
   d. StartingDeadlineSecondsの確認
   e. ConcurrencyPolicyの適用
   f. Jobテンプレートからの新規Job作成
   g. activeリストとlastScheduleTimeの更新
5. CronJobステータスのAPI Server更新
6. 次回スケジュール時刻にdelayed requeue
```

### フローチャート

```mermaid
flowchart TD
    A[CronJob/Jobイベント受信] --> B[workqueueにエンキュー]
    B --> C[sync関数実行]
    C --> D[完了Job履歴クリーンアップ]
    D --> E{CronJob Suspended?}
    E -->|Yes| F[処理終了]
    E -->|No| G[Cronスケジュール解析]
    G --> H{次回スケジュール時刻到来?}
    H -->|No| I[delayed requeue]
    H -->|Yes| J{StartingDeadline超過?}
    J -->|Yes| K[スキップ, delayed requeue]
    J -->|No| L{ConcurrencyPolicy}
    L -->|Forbid & Active > 0| M[スキップ]
    L -->|Replace| N[既存Job削除]
    L -->|Allow| O[Job作成]
    N --> O
    O --> P[ステータス更新]
    P --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ConcurrencyPolicy=Forbid | アクティブJobがある場合は新Job作成をスキップ | Forbidポリシー設定時 |
| BR-02 | ConcurrencyPolicy=Replace | アクティブJobを削除して新Jobを作成 | Replaceポリシー設定時 |
| BR-03 | StartingDeadline | スケジュール時刻＋deadline秒を過ぎた場合はスキップ | startingDeadlineSeconds設定時 |
| BR-04 | Job名の一意性 | CronJob名-スケジュール時刻ハッシュでJob名を生成 | 常時 |
| BR-05 | 履歴制限 | 成功/失敗Jobを保持数超過分の古い順に削除 | HistoryLimit設定時 |
| BR-06 | タイムゾーン | spec.timeZoneに基づきスケジュール計算 | timeZone設定時 |

### 計算ロジック

- Job名: `{CronJob名}-{getTimeHashInMinutes(scheduledTime)}`
- 次回実行遅延: `nextScheduleTimeDuration` = 次回スケジュール時刻 - 現在時刻 + 100ms
- スケジュール遅延判定: `scheduledTime + startingDeadlineSeconds < now`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Job作成 | Jobs (etcd) | INSERT | スケジュールに基づくJob新規作成 |
| Job削除 | Jobs (etcd) | DELETE | 履歴制限超過のJob削除、Replace時の既存Job削除 |
| CronJobステータス更新 | CronJobs (etcd) | UPDATE | active/lastScheduleTime/lastSuccessfulTime更新 |

### テーブル別操作詳細

#### CronJobs (etcd)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status.active | アクティブJobへのObjectReference | 作成/完了時に更新 |
| UPDATE | status.lastScheduleTime | 最新のスケジュール時刻 | Job作成成功時に更新 |
| UPDATE | status.lastSuccessfulTime | 最新の成功時刻 | Job成功検出時に更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnParseableCronJobSchedule | Warning Event | 無効なcronスケジュール式 | イベント記録、次回更新まで再処理しない |
| UnknownTimeZone | Warning Event | 無効なタイムゾーン指定 | イベント記録、処理スキップ |
| FailedCreate | Warning Event | Job作成失敗 | エラーとしてrequeue |
| FailedDelete | Warning Event | Job削除失敗 | エラーログ記録 |
| MissSchedule | Warning Event | StartingDeadline超過 | イベント記録、次回スケジュールにrequeue |

### リトライ仕様

- sync失敗時: RateLimited requeue（exponential backoff）
- sync成功時: 次回スケジュール時刻にdelayed requeue

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

Job作成とCronJobステータス更新は別々のAPI呼び出しで行われる。Job作成後にステータス更新が失敗した場合、次回syncでJob名の一意性チェックにより重複作成を防止する（AlreadyExists時はactiveリストに再追加）。

## パフォーマンス要件

- nextScheduleDelta: 100ms（スケジュール時刻の微小オフセット）
- ワーカー数: 起動時に指定（デフォルト5）
- RateLimitingQueue: デフォルトのexponential backoff

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

- CronJobが作成するJobはCronJobのOwnerReferenceを持ち、カスケード削除に対応
- Jobテンプレート内のPodSecurityContextの設定はそのまま継承される

## 備考

- CronJobコントローラーV2: DelayingQueueとInformerを使用するリファクタリング版が現在のデフォルト実装
- CRON_TZまたはTZの非公式サポート: spec.scheduleに直接TZ指定を含む場合は警告イベントを発行
- CronJobCreationSkewメトリクス: Job作成時刻とスケジュール時刻の差を記録

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `staging/src/k8s.io/api/batch/v1/types.go` | CronJob, CronJobSpec, CronJobStatus, ConcurrencyPolicyの定義 |
| 1-2 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | ControllerV2構造体（63-81行目） |

**読解のコツ**: ConcurrencyPolicyの3つの値（Allow/Forbid/Replace）がsyncCronJob内でどう分岐するかに注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | NewControllerV2（84-131行目）: Informerハンドラの登録 |
| 2-2 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | Run（134-162行目）: ワーカーの起動 |

**主要処理フロー**:
1. **84-131行目**: CronJob/Job Informerのイベントハンドラ登録
2. **134-162行目**: キャッシュ同期後、workerをgoroutineで起動
3. **169-186行目**: processNextWorkItem: キューからデキューしてsyncを呼び出し

#### Step 3: sync処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | sync関数（188-235行目）: メインの同期ロジック |
| 3-2 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | cleanupFinishedJobs（682-716行目）: 履歴クリーンアップ |
| 3-3 | cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | syncCronJob（426-674行目）: スケジュール評価とJob作成 |

#### Step 4: ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | utils.go | `pkg/controller/cronjob/utils.go` | nextScheduleTime, getJobFromTemplate2の実装 |

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

```
NewControllerV2 (初期化)
    |
    +-- Run (ワーカー起動)
        |
        +-- worker -> processNextWorkItem -> sync
                |
                +-- cleanupFinishedJobs
                |       +-- removeOldestJobs -> deleteJob
                |
                +-- syncCronJob
                        +-- formatSchedule / ParseCronScheduleWithPanicRecovery
                        +-- nextScheduleTime
                        +-- getJobFromTemplate2
                        +-- jobControl.CreateJob
                        +-- cronJobControl.UpdateStatus
```

### データフロー図

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

CronJob Informer ---+
                    |--> workqueue --> sync --> syncCronJob --> Job作成 (API Server)
Job Informer -------+                    |
                                         +--> cleanupFinishedJobs --> Job削除 (API Server)
                                         +--> cronJobControl.UpdateStatus --> CronJobステータス更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cronjob_controllerv2.go | `pkg/controller/cronjob/cronjob_controllerv2.go` | ソース | メインコントローラーロジック |
| utils.go | `pkg/controller/cronjob/utils.go` | ソース | スケジュール計算・Jobテンプレート変換 |
| injection.go | `pkg/controller/cronjob/injection.go` | ソース | Job/CronJob操作インターフェース |
| metrics/ | `pkg/controller/cronjob/metrics/` | ソース | Prometheusメトリクス定義 |
| config/ | `pkg/controller/cronjob/config/` | 設定 | コントローラー設定構造体 |
