# 機能設計書 72-QoS管理

## 概要

本ドキュメントは、KubeletにおけるPod/コンテナのQoS（Quality of Service）クラス管理機能の設計を記述する。QoSクラス（Guaranteed、Burstable、BestEffort）に基づくOOMスコア調整値の算出ロジックを定義する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesでは、ノード上のメモリが逼迫した際にLinuxカーネルのOOM Killerがどのプロセスを優先的に終了するかを制御する必要がある。QoSクラスに基づいてOOMスコア調整値（oom_score_adj）を適切に設定することで、重要なコンテナ（Guaranteed）が最後まで保護され、リソース保証のないコンテナ（BestEffort）が最初に終了されるよう制御する。

**機能の利用シーン**：Kubeletがコンテナを起動する際に、各コンテナのoom_score_adjを算出して設定する。サイドカーコンテナへの対応、PodLevelResources機能との統合も行う。

**主要な処理内容**：
1. PodのQoSクラス（Guaranteed/Burstable/BestEffort）の判定
2. コンテナごとのOOMスコア調整値の算出
3. サイドカーコンテナのOOMスコア調整（通常コンテナより優先保護）
4. PodLevelResources機能有効時の追加メモリ配分計算
5. ノードクリティカルPodの特別扱い

**関連システム・外部連携**：Linuxカーネルの/proc/[pid]/oom_score_adjへの設定。QoSクラス判定ロジックはcore/v1/helper/qosパッケージに委譲。

**権限による制御**：ノードクリティカルPodは常にguaranteedOOMScoreAdj（-997）が適用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | Kubelet内部処理のため、直接の画面関連はなし |

## 機能種別

計算処理 / 内部制御処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pod | *v1.Pod | Yes | 対象Pod | - |
| container | *v1.Container | Yes | 対象コンテナ | - |
| memoryCapacity | int64 | Yes | ノードのメモリ容量（バイト） | 正の整数 |

### 入力データソース

- Kubelet内部のPodオブジェクトおよびコンテナ情報
- ノードのメモリ容量情報（cAdvisorまたはCRI経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| oomScoreAdj | int | OOMスコア調整値（-997〜1000の範囲） |

### 出力先

コンテナランタイムへの設定パラメータとして使用される。

## 処理フロー

### 処理シーケンス

```
1. ノードクリティカルPod判定
   └─ 該当する場合、-997を返却
2. QoSクラス判定
   ├─ Guaranteed: -997を返却
   ├─ BestEffort: 1000を返却
   └─ Burstable: 以下の計算を実行
3. コンテナメモリ要求値の取得
4. PodLevelResources有効時の追加メモリ配分計算
   └─ remainingPodMemReqPerContainer算出
5. OOMスコア調整値の算出
   └─ 1000 - (1000 * (containerMemReq + remainingReq) / memoryCapacity)
6. サイドカーコンテナの場合の調整
   └─ 通常コンテナの最小メモリ要求に基づくOOMスコアとの比較
7. 境界値チェック
   └─ 最小値: 1000 + guaranteedOOMScoreAdj (3)
   └─ BestEffortと同値の場合: -1して999に
```

### フローチャート

```mermaid
flowchart TD
    A[GetContainerOOMScoreAdjust] --> B{ノードクリティカルPod?}
    B -->|Yes| C[return -997]
    B -->|No| D{QoSクラス判定}
    D -->|Guaranteed| C
    D -->|BestEffort| E[return 1000]
    D -->|Burstable| F[containerMemReq取得]
    F --> G{PodLevelResources有効?}
    G -->|Yes| H[remainingReqPerContainer算出]
    G -->|No| I[oomScoreAdj = 1000 - 1000*memReq/capacity]
    H --> J[oomScoreAdj = 1000 - 1000*(memReq+remaining)/capacity]
    I --> K{サイドカーコンテナ?}
    J --> K
    K -->|Yes| L[通常コンテナ最小メモリ基準で調整]
    K -->|No| M[境界値チェック]
    L --> M
    M --> N[return oomScoreAdj]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-72-01 | Guaranteed OOM保護 | oom_score_adj = -997で最大限保護 | QoSクラスがGuaranteedまたはノードクリティカルPod |
| BR-72-02 | BestEffort OOM優先終了 | oom_score_adj = 1000でOOM Kill最優先対象 | QoSクラスがBestEffort |
| BR-72-03 | Burstable計算式 | oom_score_adj = 1000 - (1000 * memReq / memCapacity) | QoSクラスがBurstable |
| BR-72-04 | サイドカー保護 | サイドカーのOOMスコアは通常コンテナの最小メモリ基準以下に調整 | InitContainerでRestartPolicy=Always |
| BR-72-05 | Burstable最小値 | oom_score_adjの最小値は3（1000 + (-997)） | Burstableクラスの全コンテナ |
| BR-72-06 | BestEffort回避 | Burstableコンテナのoom_score_adjが1000と算出された場合は999に | Burstableクラスのコンテナ |

### 計算ロジック

**基本式（Burstable）**：
```
oomScoreAdj = 1000 - (1000 * containerMemoryRequest / nodeMemoryCapacity)
```

**PodLevelResources有効時**：
```
remainingReq = (podMemoryRequest - sumOfContainerMemoryRequests) / numContainers
oomScoreAdj = 1000 - (1000 * (containerMemReq + remainingReq) / memoryCapacity)
```

**サイドカー調整**：
```
minMemoryReq = min(regularContainers[*].Resources.Requests.Memory)
minMemOomAdj = 1000 - (1000 * minMemoryReq / memoryCapacity)
oomScoreAdj = min(oomScoreAdj, minMemOomAdj)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベースへの直接操作はなし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数はエラーを返さない | 入力値に基づき常に値を返却する |

### リトライ仕様

リトライ不要。純粋な計算処理のため。

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

トランザクションの概念はなし。

## パフォーマンス要件

O(N)の計算量（Nはコンテナ数）。サイドカー判定時にInitContainerリストを走査する。

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

- OOMスコアの不適切な設定はノードの安定性に影響するため、算出ロジックの正確性が重要
- ノードクリティカルPodが適切に保護されることを保証する

## 備考

- KubeletOOMScoreAdj（-999）およびKubeProxyOOMScoreAdj（-999）は本パッケージで定数として定義されているが、GetContainerOOMScoreAdjustとは別に使用される
- guaranteedOOMScoreAdj（-997）はKubelet自身（-999）よりも高い値であり、Kubeletプロセスが最後まで生存するように設計されている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | policy.go | `pkg/kubelet/qos/policy.go` | OOMスコア調整の定数定義（28-35行目） |

**読解のコツ**: OOMスコア調整値の範囲はLinuxカーネルの仕様（-1000〜1000）に基づく。-999はKubelet自身の保護値、-997はGuaranteed Pod用。

#### Step 2: メイン関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | policy.go | `pkg/kubelet/qos/policy.go` | GetContainerOOMScoreAdjust関数（45-120行目） |

**主要処理フロー**:
1. **46-49行目**: ノードクリティカルPod判定
2. **51-57行目**: QoSクラス別の分岐
3. **67行目**: コンテナメモリ要求値の取得
4. **77-85行目**: PodLevelResources機能有効時の分岐計算
5. **89-108行目**: サイドカーコンテナの特別処理
6. **112-119行目**: 境界値チェックと最終値の返却

#### Step 3: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | helpers.go | `pkg/kubelet/qos/helpers.go` | minRegularContainerMemory関数（36-44行目） |
| 3-2 | helpers.go | `pkg/kubelet/qos/helpers.go` | remainingPodMemReqPerContainer関数（56-71行目） |
| 3-3 | policy.go | `pkg/kubelet/qos/policy.go` | isSidecarContainer関数（126-135行目） |

**読解のコツ**: `isSidecarContainer`はInitContainerでRestartPolicy=Alwaysが設定されているコンテナをサイドカーと判定する。v1.Containerに直接的なサイドカーフラグはない。

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

```
GetContainerOOMScoreAdjust(pod, container, memoryCapacity)
    |
    +-- types.IsNodeCriticalPod(pod)
    |
    +-- v1qos.GetPodQOS(pod)
    |
    +-- [Burstable分岐]
    |       +-- container.Resources.Requests.Memory().Value()
    |       +-- utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)
    |       +-- resourcehelper.IsPodLevelRequestsSet(pod)
    |       +-- remainingPodMemReqPerContainer(pod)
    |       |       +-- resourcehelper.AggregateContainerRequests(pod, ...)
    |       |
    |       +-- isSidecarContainer(pod, container)
    |       +-- minRegularContainerMemory(pod)
    |
    +-- 境界値チェック
```

### データフロー図

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

Pod ------------------> QoSクラス判定 -----------> oom_score_adj (int)
Container ------------> メモリ要求値取得               |
memoryCapacity -------> OOMスコア算出                  +-> コンテナランタイム設定
                        サイドカー調整
                        境界値チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| policy.go | `pkg/kubelet/qos/policy.go` | ソース | OOMスコア調整値算出のメインロジック |
| helpers.go | `pkg/kubelet/qos/helpers.go` | ソース | 補助計算関数（最小メモリ、残余メモリ配分） |
| doc.go | `pkg/kubelet/qos/doc.go` | ソース | パッケージドキュメント |
| policy_test.go | `pkg/kubelet/qos/policy_test.go` | テスト | OOMスコア算出のテストケース |
