Kubernetesで複数定義されたDesired Stateに矛盾があった場合、どのような判定が下され、どのような挙動になりますか?

freja-nelson-vDJ0LQJkp6s-unsplash.jpg

質問

Kubernetesで複数定義されたDesired Stateに矛盾があった場合、どのような判定が下され、どのような挙動になりますか?
対策も挙げてください。


解答

非常に良い質問です。
Kubernetesの「Desired State(望ましい状態)」は、宣言的構成管理の中核にあたる概念であり、

複数のリソース定義(YAMLマニフェスト)が同じ対象に異なる状態を要求すると、最終的にどの状態が採用されるかは非常に重要です。

以下では、

  1. 判定の仕組み

  2. 実際の挙動

  3. 代表的な矛盾ケース

  4. 対策方法
    を体系的に解説します。


【1】Kubernetesの「Desired State」判定の仕組み

Kubernetesは「最後に適用されたマニフェストがクラスタの真実(Source of Truth)になる」という原則に基づきます。
この原則を**“last write wins(最後の書き込みが勝つ)”**と呼びます。

  • 各リソース(Pod、Deployment、Serviceなど)はetcdにJSONとして保存されます。

  • 同じリソース名・Namespaceを持つオブジェクトに複数の「Desired State」をkubectl applyやAPI経由で投入した場合、最後に適用されたものがetcd上で上書きされます。

  • Controller ManagerやSchedulerは、etcd内の最新状態を「正」として同期をとります。

つまり、矛盾があっても競合エラーではなく「上書き更新」として処理されるのが基本です。


【2】実際の挙動の例

例:同一Deploymentを別YAMLで異なる設定

deployment-a.yaml

spec:  replicas: 3  template:    spec:      containers:      - name: app        image: nginx:1.21

deployment-b.yaml

spec:  replicas: 5  template:    spec:      containers:      - name: app        image: nginx:1.25

両方を同じDeployment名で適用した場合:

kubectl apply -f deployment-a.yamlkubectl apply -f deployment-b.yaml

結果:

  • replicas: 5

  • image: nginx:1.25

  • deployment-b.yamlの内容で完全に上書きされる。

Kubernetesは衝突検出をしない。最後の宣言を正とみなす。


【3】代表的な「矛盾」パターン

矛盾の種類内容挙動
同一リソースを複数マニフェストで管理例:同じDeployment名でreplicasやimageが異なる後からapplyした内容で上書き(last write wins)
異なるController間の競合DeploymentがPodを作り、同名のPodを別Jobも作成コントローラ間で衝突。Pod再作成のループが発生する可能性
Service/Ingress競合同じService名で異なるPort定義上書き。通信経路が一時的に不安定化
ConfigMap/Secret競合同じ名前で異なるデータキー直近のapplyが反映。既存値は消える。
Namespace重複定義同名Namespaceをapply2回目は無視(Namespaceは一意)

【4】内部的な判定フロー

  1. API Serverがリソースを受理し、metadata.namemetadata.namespaceで一意性を確認。

  2. 既に存在する場合は「更新」とみなし、etcd上のオブジェクトを上書き。

  3. Controller Managerが新しいspecとの差分を検知して調整(Podの再起動やスケーリング)。

  4. Reconciler Loopにより、etcd上の最新specと実際のクラスタ状態を一致させる。

→ Kubernetesは「矛盾検知」ではなく「再調整(reconciliation)」を行うアーキテクチャです。


【5】対策方法

1リソース=1管理単位の原則

  • 同じリソース名を複数YAMLで定義しない。

  • 複数人・複数ツールから同じDeploymentを変更しない。
    (例:手動kubectl applyとGitOpsの両方で更新しない)

GitOpsで単一のSource of Truthを確保

  • ArgoCDやFluxCDを使い、YAMLの管理をリポジトリに一元化。

  • 手動変更を禁止して「宣言的整合性」を保つ。

Namespace・Labelで責務分離

  • チームやアプリごとにNamespaceを分ける。

  • ControllerやDeployment名の重複を避ける。

kubectl diffserver-side apply の活用

  • 変更前に差分を確認:

    kubectl diff -f deployment.yaml
  • Server-Side Applyでは「フィールド単位の所有権管理」が行われる。
    → 複数ツールから同時管理しても安全性が高い。

ResourceQuotasやAdmission Policyの導入

  • 特定のNamespaceでリソース定義の上書きを制限。

  • OPA GatekeeperKyvernoでポリシー制御。


【6】まとめ

観点内容
衝突時の原則last write wins(最後のapplyが有効)
Kubernetesの挙動矛盾検知はせず、自動的に最新specで再調整
リスク意図しない上書きやPod再起動、設定消失
主な対策GitOps、Namespace分離、server-side apply、ポリシー管理




Kubernetesで実践するクラウドネイティブDevOps [ John Arundel ]

価格:3850円
(2025/11/11 22:09時点)
感想(0件)


コンピュータシステムの理論と実装 モダンなコンピュータの作り方/NoamNisan/ShimonSchocken/斎藤康毅【1000円以上送料無料】

価格:4400円
(2025/10/19 21:21時点)
感想(0件)


 



この記事へのコメント

広告です。クリックいただけると励みになります。