1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Topology Spread Constraints の落とし穴:Pod が偏るケースと対策

1
Posted at

Topology Spread Constraints(TSC)は、Deployment や StatefulSet が作成する Pod を、Node や Zone に分散させるための仕組みです。冗長性を高めるうえで便利ですが、分散先の Node が一時的に減ると、意図せず Pod が 1 Node に集約されることがあります。

この記事では、その後に Node が追加されても自動では再分散されない理由と、minDomains による防ぎ方を説明します。

今回の Deployment

ワークロードを配置できる Node が 3 台あるクラスタを考えます。以下の Deployment は 2 replicas で、hostname ごとに Pod を分散させます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-a
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deployment-a
  template:
    metadata:
      labels:
        app: deployment-a
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: deployment-a
      containers:
        - name: nginx
          image: nginx:1.29

topologyKey: kubernetes.io/hostname は Node 単位で分散する指定です。maxSkew: 1 と DoNotSchedule により、配置数の差が大きくなる新規 Pod はスケジュールされません。

デプロイ直後は、2 Pod が別々の Node に配置されます。配置数は 1 / 1 / 0 で、最大差は 1 です。

01-initial-spread.png

Node が 2 台削除される

ここでは、Pod がない Node 3 と、Pod がある Node 2 が完全に削除される状況を想定します。Node 2 上の Pod は終了します。

02-nodes-deleting.png

Deployment は replicas を 2 に保とうとするため、終了した Pod を作り直します。しかし残っている Node は Node 1 だけです。そのため、新しい Pod も Node 1 に配置され、2 Pod が同じ Node に集約されます。

03-pods-consolidated.png

この時点では、TSC が配置先として数える Node のまとまり(配置対象となるドメイン)が Node 1 の 1 つだけです。比較対象となる別の配置対象となるドメインがないため、TSC はこの配置を拒否しません。

Node が追加されても Pod は自動で移動しない

Node 4 と Node 5 が追加され、再び 3 Node になったとしても、Node 1 上の 2 Pod はそのままです。

04-nodes-added-no-rebalance.png

TSC は Pod をスケジュールする時点で評価される制約です。既に Running になっている Pod を検知して、より均等な Node へ移動させる機能ではありません。したがって、Node が増えても既存 Pod の 2 / 0 / 0 配置は自動では解消されません。

minDomains: 2 を指定する

今回の要件は「2 replicas を同じ Node に置かない」ことです。この場合、TSC に minDomains: 2 を追加します。

topologySpreadConstraints:
  - maxSkew: 1
    minDomains: 2 # 追加
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: deployment-a

minDomains は、分散先として最低限必要な配置対象となるドメイン数を指定します。配置対象となるドメイン数が minDomains 未満の場合、スケジューラは global minimum を 0 として skew を計算します。

minDomains を含む TSC の詳しい仕様は、Pod のトポロジー分散制約の公式ドキュメントを参照してください。

Node が 1 台だけの状態では、2 個目を Node 1 に置くと skew が 2 となり、maxSkew: 1 を超えます。そのため、2 個目の Pod は Pending になります。Node 4・5 が追加されれば、Pending だった Pod は追加 Node に配置され、分散した状態へ戻れます。

05-min-domains-2.png

まとめ

minDomains: 2 は、分散先が 1 つしかないときに replicas を 1 Node へ集約しないための設定です。その代わり、Node 不足の間は 2 個目の Pod が Pending となり、稼働 Pod 数は減ります。

可用性を優先して 1 Node でも全 replicas を動かすのか、Node が不足している間は Pod 数を減らしてでも分散を守るのかを決めたうえで、minDomains の値を選ぶ必要があります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?