フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

トポロジー単位でpodの割り当てを管理するTopologySpreadConstraintsについて

この記事で紹介されていた「TopologySpreadConstraints」について備忘がてらまとめます。

kubernetes.io

TopologySpreadConstraints とは?

指定したLabelに対してPodの配置をバランシングするための制約です。こう聞くと意味が分かりづらいと思うので実用例を交えて補足します。

AWSやGCPではデータセンター単位にZoneと呼ばれるものが存在します。これはデータセンターレベルの障害を回避するために各ベンダが用意している概念で、複数のZoneにまたがってサービスを構築することで可用性を向上させることができます。

Kubernetesを動かすVMでもこれを考慮する必要があるのですが、残念ながらKubernetes自体には物理層がどこのZoneに存在しているのか?を判別する機能は備わっていません。

しかし利用する立場からするといくら複数のVMにPodが分散して起動していたとしても、データセンター障害を考えると同じZoneで動かれていては困るわけです。Zoneだけではなく、同じ物理サーバ上で動く仮想サーバやリージョンといった単位で考えても構いません。

なんにせよPodはなるべくお互い関係ない場所で動いてほしいわけですが、それをがんばって達成するための機能がTopologySpreadConstraintsです。


f:id:lirlia:20210712034039p:plain

この図ではzoneというラベルをもった2種類のVMが存在していると考えてください。この時にtopologyKeyにてzoneを指定すると、各Zoneに対して均等にPodを振り分けることができるようになります。

つまり人手(AWSでは勝手にZone情報などはラベルに付与されている)でラベルをつけることさえできれば、それを利用することでKubernetes は勝手にPodをいい感じにバランシングして配置してくれるというわけです。

参考: EKSに参加しているNodeにはこんなラベルが勝手に付きます

Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/instance-type=t3.medium
                    beta.kubernetes.io/os=linux
                    eks.amazonaws.com/capacityType=ON_DEMAND
                    eks.amazonaws.com/nodegroup-image=ami-xxxx
                    failure-domain.beta.kubernetes.io/region=ap-northeast-1
                    failure-domain.beta.kubernetes.io/zone=ap-northeast-1c
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=ip-10-0-x-x.ap-northeast-1.compute.internal
                    kubernetes.io/os=linux
                    node.kubernetes.io/instance-type=t3.medium
                    topology.kubernetes.io/region=ap-northeast-1
                    topology.kubernetes.io/zone=ap-northeast-1c

ちなみにmaxSkewとはバランシングの制限の一つで、どの程度の数のPodの差を許容するのか?という設定です。

NodeSelectorやNodeAffinityとの併用

指定のNodeでPodを起動させる方法としてSelectorやAffinityが存在しますが、TopologySpreadConstraintsはこれらと併用可能です。

f:id:lirlia:20210712034611p:plain

上記の例の場合は、最初にenvがqaであるというフィルターで制限されたのちにzoneラベルでバランシングされます。

Multiple TopologySpreadConstraints

複数のラベルでのバランシングを見ていきます。

f:id:lirlia:20210712034850p:plain

例ではzoneとnode名のラベルを使用して以下のようなロジックでバランシングが行われています。

  • 「zone」でバランシングを行う→Zone1に置くとmaxSkewを超えるのでZone2に置く。そのため選択肢はnodeXかYになる
  • 「node」でバランシングが行う→nodeBとXはPodが多いのでAかYに置く

両者の条件を組み合わせるとnodeXしか無いのでここに置く

NodeSelector&AffinityとMultiple TopologySpreadConstraintsの違い

以下のように評価方法が違うので使う際には注意をしましょう。

  • Selector & Affinity : 条件を満たすNode群を検索対象にする→その中でTopologykeyが評価される
  • Multiple TopologySpreadConstraints : すべてのNodeを対象としてラベルの評価が行われそれぞれの結果を突合する