# 通知設計書 127-DNSConfigForming

## 概要

本ドキュメントは、kubelet の DNS Configurer が発行する `DNSConfigForming` イベント通知の設計を記述する。Pod の DNS 設定構成時に、ネームサーバ数や検索パス数がシステム制限を超過した場合に発行される警告イベントである。

### 本通知の処理概要

本通知は、kubelet が Pod の DNS 設定を生成する際に、DNS ネームサーバ数または DNS 検索パス数・検索リスト文字数がシステムの制限を超過した場合に発行される。超過した分は切り捨てられ、実際に適用された設定内容がイベントメッセージに記録される。

**業務上の目的・背景**：Linux の DNS リゾルバ（glibc 等）には、ネームサーバ数（最大3）、検索パス数（最大32）、検索リスト文字数（最大2048文字）に制限がある。これらを超過した場合、一部の設定が切り捨てられるため、予期しない名前解決の問題が発生する可能性がある。この通知により管理者はDNS設定の超過を早期に検知できる。

**通知の送信タイミング**：kubelet が Pod の DNS 設定を生成する `GetPodDNS` 関数内で `formDNSConfigFitsLimits` が呼ばれた際に、`formDNSNameserversFitsLimits` または `formDNSSearchFitsLimits` で制限超過を検出した時点で発行される。

**通知の受信者**：Kubernetes Event として Pod オブジェクトに対して記録される。クラスタ管理者やアプリケーション開発者が参照する。

**通知内容の概要**：超過の種類（ネームサーバ数 or 検索パス数/文字数）と、実際に適用された設定値が記録される。

**期待されるアクション**：Pod の DNS 設定（dnsConfig, dnsPolicy）やクラスタの DNS 設定を見直し、制限内に収まるように調整する。

## 通知種別

Kubernetes Event（Warning イベント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（イベント記録） |
| 優先度 | 中（Warning） |
| リトライ | なし |

### 送信先決定ロジック

Pod オブジェクトに対してイベントが記録される。

## 通知テンプレート

### メール通知の場合

本通知はKubernetes Eventであり、メール送信は行わない。

### 本文テンプレート

```
# ネームサーバ数超過時
Nameserver limits were exceeded, some nameservers have been omitted, the applied nameserver line is: <nameservers>

# 検索パス超過時
Search Line limits were exceeded, some search paths have been omitted, the applied search line is: <search paths>
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| nameservers | 適用されたネームサーバリスト | nameservers スライス（切り捨て後） | Yes（ネームサーバ超過時） |
| search paths | 適用された検索パスリスト | composedSearch スライス（切り捨て後） | Yes（検索パス超過時） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| Pod起動処理 | GetPodDNS呼び出し | ネームサーバ数 > MaxDNSNameservers | formDNSNameserversFitsLimits で検出（150行目） |
| Pod起動処理 | GetPodDNS呼び出し | 検索パス数 > MaxDNSSearchPaths | formDNSSearchFitsLimits で検出（107行目） |
| Pod起動処理 | GetPodDNS呼び出し | 個別検索パス長 > DNS1123SubdomainMaxLength | formDNSSearchFitsLimits で検出（116行目） |
| Pod起動処理 | GetPodDNS呼び出し | 検索リスト文字数 > MaxDNSSearchListChars | formDNSSearchFitsLimits で検出（125行目） |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 制限内 | すべてのDNS設定が制限内であればイベントは発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Pod起動] --> B[GetPodDNS]
    B --> C[DNS設定生成]
    C --> D[formDNSConfigFitsLimits]
    D --> E[formDNSNameserversFitsLimits]
    D --> F[formDNSSearchFitsLimits]
    E --> G{ネームサーバ数超過?}
    G -->|Yes| H[切り捨て + Warning DNSConfigForming]
    G -->|No| I[そのまま]
    F --> J{検索パス超過?}
    J -->|Yes| K[切り捨て + Warning DNSConfigForming]
    J -->|No| L[そのまま]
    H --> M[切り捨て後のDNS設定を返却]
    I --> M
    K --> M
    L --> M
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Pod（API リソース） | Pod の DNS設定取得 | pod.Spec.DNSConfig, pod.Spec.DNSPolicy |
| resolv.conf | ホストのDNS設定取得 | ファイルシステムから読み込み |

### テーブル別参照項目詳細

#### Pod

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.dnsConfig | カスタムDNS設定 | Pod起動時 |
| spec.dnsPolicy | DNSポリシー | Pod起動時 |
| metadata.namespace | クラスタDNS検索パス生成 | Pod起動時 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Event（API リソース） | INSERT | Warning イベントの記録 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | Event | Warning / DNSConfigForming | Kubernetes Event APIを通じて記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 制限超過 | DNS設定がシステム制限を超過 | 超過分を切り捨ててWarningイベント発行、処理は続行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | N/A（処理は正常続行） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Event APIのデフォルトレート制限に従う |
| 1日あたり上限 | 制限なし |

### 配信時間帯

特に制限なし。Pod起動時に発生する。

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

本イベントにはDNSネームサーバアドレスと検索ドメインが含まれる。内部ネットワーク構成の一部が露出する可能性がある。Kubernetes RBAC によりイベントの閲覧権限が制御される。

## 備考

- glibc 2.28以降ではDNS検索パスが255文字を超えるとabort()を引き起こすため、個別パス長のチェックも行われる（112-113行目のコメント参照）
- MaxDNSNameservers, MaxDNSSearchPaths, MaxDNSSearchListChars は validation パッケージで定義される定数

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dns.go | `pkg/kubelet/network/dns/dns.go` | Configurer構造体（60-74行目）の各フィールド（clusterDNS, ClusterDomain, ResolverConfig） |

**読解のコツ**: DNS設定はホストの resolv.conf、クラスタDNS設定、PodのdnsConfigの3つのソースからマージされる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dns.go | `pkg/kubelet/network/dns/dns.go` | GetPodDNS関数（386-450行目）がPod DNS設定生成のメインロジック |

**主要処理フロー**:
1. **388行目**: ホストDNS設定の取得
2. **398行目**: dnsTypeによる分岐（podDNSNone, podDNSCluster, podDNSHost）
3. **446-448行目**: dnsConfig のマージ（appendDNSConfig）
4. **449行目**: formDNSConfigFitsLimits で制限チェック

#### Step 3: 制限チェックロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dns.go | `pkg/kubelet/network/dns/dns.go` | formDNSNameserversFitsLimits（149-157行目）でネームサーバ数チェック |
| 3-2 | dns.go | `pkg/kubelet/network/dns/dns.go` | formDNSSearchFitsLimits（102-147行目）で検索パス数・長さチェック |

**主要処理フロー（formDNSSearchFitsLimits）**:
- **107行目**: 検索パス数 > MaxDNSSearchPaths のチェック
- **116行目**: 個別パス長 > DNS1123SubdomainMaxLength のチェック
- **125行目**: 検索リスト合計文字数 > MaxDNSSearchListChars のチェック
- **141-144行目**: limitsExceeded 時に Warning DNSConfigForming イベント発行

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

```
Configurer.GetPodDNS (386行目)
    |
    +-- getHostDNSConfig (388行目)
    +-- getPodDNSType (393行目)
    +-- appendDNSConfig (447行目)
    +-- formDNSConfigFitsLimits (449行目)
           |
           +-- formDNSNameserversFitsLimits (149行目)
           |      +-- recorder.Event("DNSConfigForming") (153行目)
           |
           +-- formDNSSearchFitsLimits (102行目)
                  +-- recorder.Event("DNSConfigForming") (143行目)
```

### データフロー図

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

ホストresolv.conf ───┐
                      +──> GetPodDNS ───> formDNSConfigFitsLimits ───> Event記録
Pod.spec.dnsConfig ──┘                   (制限チェック + 切り捨て)      (DNSConfigForming)
ClusterDNS設定 ──────┘                                                   |
                                                                          v
                                                                     runtimeapi.DNSConfig
                                                                     (切り捨て後)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dns.go | `pkg/kubelet/network/dns/dns.go` | ソース | Configurer, GetPodDNS, formDNS*FitsLimits |
| dns_test.go | `pkg/kubelet/network/dns/dns_test.go` | テスト | DNS設定制限チェックのテスト |
