Kubernetes Meetup Tokyo #48 https://k8sjp.connpass.com/event/237734/
Pod Topology Spreadの超最前線 MinDomains(仮)、NodeInclusionPolicies(仮)について Kensei Nakada @sanposhiho 1
View Slide
自己紹介 中田 健誠 / Kyoto Uni (4th year) 趣味でKubernetes(kube-scheduler)や 周辺エコシステムにcontributeしています。 Twitter: さんぽし (@sanpo_shiho) GitHub: @sanposhiho member of Kubernetes / Kubernetes SIGs
今日話すこと Kubernetesのv1.24でPod Topology Spreadに新たに二つのAPIが追加されます。 今日はそれぞれのAPIの提案内容と、現状のPod Topology Spreadにおける課題点/問題点や関連する細かい仕様を紹介します。 「v1.24だったらまだ先だしキャッチアップはまだ大丈夫だね〜」と思っているそこのあなた、 Pod Topology Spreadで痛い目を見る可能性がありますよ 👀👀
注意点 今日話すMinDomainsとNodeInclusionPoliciesに関しては、 現時点(2022/02/21)で、KEPがImplementableになり、alphaとしてv1.24で公開される予定となっているものです。 しかし、予定に狂いが生じたり、現在の提案に変更が加わる可能性があります。 実際にリリースされた時には、この資料ではなく、公式のドキュメントを参考にして下さい。
もくじ 1. Pod Topology Spreadってなんだっけ? 2. 現在のPod Topology Spreadの仕様における問題点/課題点 (1) 3. NodeInclusionPoliciesについて 4. 現在のPod Topology Spreadの仕様における問題点/課題点 (2) 5. MinDomainsについて
Pod Topology Spreadってなんだっけ? 6
Pod Topology Spreadってなんだっけ? ゾーンやノードなどの任意のドメイン間でPodをどのように分散させるかを 制御できる機能。 Kubernetes v1.19で追加された比較的新しい機能です。
Pod Topology Spreadってなんだっけ? pod.spec.topologySpreadConstraintsを通して設定する。 (KubeSchedulerConfigurationにてデフォルト値を設定することも可能 (beta)) 公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用
topologyKey Nodeのラベルのkeyを示している、 特定のラベルの値が同じNodeたちが一つのドメインとして扱われる。
topologyKey well-known labelと呼ばれるものがあり、それが使用されてることが多い (多分) 例: kubernetes.io/hostname: Nodeの名前を示すラベル topology.kubernetes.io/zone: どのzoneに存在するかを示すラベル
topologyKey well-known labelと呼ばれるものがあり、それが使用されてることが多い (多分) 例: kubernetes.io/hostname: Nodeの名前を示すラベル → 一つのNode = 一つのドメイン になる topology.kubernetes.io/zone: どのzoneに存在するかを示すラベル → 一つのZoneに存在する全てのNode = 一つのドメイン になる
labelSelector そのConstraintで対象とするPodを見つけるためのlabelSelector。 labelSelectorと一致するPodはPod Topology Spreadの内部実装では ”matching Pod”と呼ばれることがある。 つまり: “matching Pod” = labelSelectorに一致するPodで、すなわちそのConstraintで対象となるPod
whenUnsatisfiable DoNotSchedule と ScheduleAnyway のどちらかの値を取る。 DoNotSchedule: 制約を満たせないNodeには絶対にPodをスケジュールしない ScheduleAnyway: 制約を満たせないNodeにはPodをスケジュールしないように頑張る。(= 制約を満たせないNodeにPodがスケジュールされることもある) (Scheduling Framework的には、FilterするかScoreするかという違いです。)
maxSkew ドメイン間のmatching Podの偏りをどれだけ許容するかを示す。 skew = (最もmatching Podが多く存在しているドメインにおけるPodの総数) - (最もmatching Podが少なく存在しているドメインにおけるPodの総数)
maxSkew ドメイン間のmatching Podの偏りをどれだけ許容するかを示す。 skew = (最もmatching Podが多く存在しているドメインにおけるPodの総数) - (最もmatching Podが少なく存在しているドメインにおけるPodの総数) 最もmatching Podが少なく存在しているドメインにおけるPodの総数のことを、内部実装的にはglobal minimumと呼んでいる。
maxSkew maxSkewが1で、whenUnsatisfiableはDoNotScheduleとする。 (青色で示されているPodはmatching Pod。) 公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用
maxSkew 新しいmatching Pod(mypod)を作ったとする もし、zoneAにPodがスケジュールされると、 zoneAのmatching Podの数: 3 zoneBのmatching Podの数: 1 になる。Podの数の差は 3-1 > maxSkew(= 1) になってしまう。 これはmaxSkewの制約に反するのでmypodは必ずzoneBのどちらかに行く
maxSkew zoneBのどちらかに スケジュールされれば、 zoneAのmatching Podの数: 2 zoneBのmatching Podの数: 2 になる。 2-2 < maxSkew(= 1) なのでOK ↑OR↓ になる 公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用
現在のPod Topology Spreadの仕様における 問題点/課題点 (1) 19
Skew計算時に対象にするNodeについて nodeAffinity/nodeSelectorはSkewの計算時に考慮される。 例: PodがnodeAffnityで絶対にNode4にスケジュールされないようになっている場合 ↓ Node4がドメインの中に入っていたとしても、Skewの計算から弾かれる
Skew計算時に対象にするNodeについて nodeAffinityでNode4が弾かれる場合、Skewの計算に入れてしまうと…? → matching Podの数が増えてもNode4のmatching Pod数は絶対に0(最小値) → topologyKey: kubernetes.io/hostname で DoNotSchedule を使用している場合、matching Podの数が増えていくと、maxSkewに反するようになり、どのNodeにもスケジュールできなくなる。
Skew計算時に対象にするNodeについて スケジュールできなくなる例: 右下の図だと、 - nodeAffinityでNode4が弾かれる - topologyKey: kubernetes.io/hostname - DoNotSchedule - maxSkew: 1 の場合どこにも行けなくなる。 公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用
Skew計算時に対象にするNodeについて しかし、TaintsとTolerationsは現状考慮されない。 一応ドキュメントの一番下にちっちゃく一行で 「tainted Node上のPodは考慮されます」 (= 言い換えると、普通のNodeと同じように扱う ということですね) って書かれている。
TaintsとTolerationsが考慮されないと何が起こる? 1. Podに topologyKey: kubernetes.io/hostname と DoNotSchedule を使っている 2. 何らかの理由(drain等)でNodeAにNoScheduleのtaintが付く。 3. 全てのPodはNodeAからevict(退去)される。 4. evictされたPodがreplicasetなどの影響で再度作成され、スケジュールが開始。 5. NodeAにはmatching Podが0個存在する。これによって、(matching Podの数が十分に多い場合) maxSkewの制約を満たすために、Pod Topology Spreadは常にNodeAにスケジュールしようとするようになる 6. しかし、NodeAはUnschedulable taintがついているのでスケジュールできない 7. NodeAがクラスタから削除される/taintが外れるまでPodが起動できない(ずっとPending)
NodeInclusionPoliciesについて 27
NodeInclusionPolicies (KEP-3094) Pod Topology SpreadのそれぞれのConstraintにおいて、 どのNodeを対象とするのかを指定できる機能 PodSpec.TopologySpreadConstraintにNodeInclusionPolicies APIが新たに追加され、 NodeAffinityとNodeTaintをそれぞれ適応するかどうかを指定できる。
↓こんな感じ
先程の問題 先程の問題はNodeInclusionPoliciesでNodeTaintをRespectに指定することで、解決できる (後方互換性のために、提案ではNodeInclusionPoliciesのNodeTaintに関しては、デフォルトがIgnoreになる。)
現在のPod Topology Spreadの仕様における 問題点/課題点 (2) 32
[再掲] Pod Topology Spreadってなんだっけ? ゾーンやノードなどの任意のドメイン間でPodをどのように分散させるかを 制御できる機能。 Kubernetes v1.19で追加された比較的新しい機能です。
maxSkewに関して Skewは存在しているドメイン間のmatching Podの数の差で計算される。 ↓ maxSkewはあえて抽象的に言うと 「すでに存在しているドメインの間で、どのようにPodを拡散するか」 を制御するAPIである。
maxSkewに関して Skewは存在しているドメイン間のmatching Podの数の差で計算される。 ↓ maxSkewはあえて抽象的に言うと 「すでに存在しているドメインの間で、どのようにPodを拡散するか」 を制御するAPIである。 ↓ ドメイン自体の数を制御(増やしたり減らしたり)したい場合はどうするの…?
MinDomains について 37
MinDomains (KEP-3022) Pod Topology SpreadのそれぞれのConstraintにおいて、 ドメインの最小値を指定できる機能。 PodSpec.TopologySpreadConstraintにMinDomains APIが新たに追加される。 DoNotScheduleのみで使用可能。
[再掲] maxSkew ドメイン間のmatching Podの偏りをどれだけ許容するかを示す。 skew = (最もmatching Podが多く存在しているドメインにおけるPodの総数) - (最もmatching Podが少なく存在しているドメインにおけるPodの総数) 最もmatching Podが少なく存在しているドメインにおけるPodの総数のことを、内部実装的にはglobal minimumと呼んでいる。
MinDomains (KEP-3022) MinDomainsが指定された場合、ドメインの数が、MinDomainsよりも少ない場合に、globalminimumが常に0となる。
例 topologyKey: kubernetes.io/hostname, DoNotSchedule, maxSkew: 1, minDomains: 5 とする。 4つ目まではスケジュールできるが、 5つ目のmatching Podはスケジュールに 失敗する。 図は公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用 ↓
例 4つのPodが置かれた時点で、 どのNodeに次のPodをおいても、 ドメイン上で2つ目のPodになる。 MinDomainsにより、 global minimumが0になっている。 → skew = 2 - 0 > maxSkew (=1) なので、maxSkewに反してしまう。 図は公式ドキュメント( https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ) より引用 ↓
具体的にどのようなことができるようになるか ClusterAutoscalerが使用されている場合で、複数のドメインにPodを配置したい場合、強制的にNodeを増やすといったことができるようになります。 例えば、 - topologyKey: kubernetes.io/hostname - DoNotSchedule - maxSkew: 1 - minDomains: 5 の時に、スケジュール可能なNodeが4つしか存在しない場合、5つ目のmatching Podのスケジュールは失敗する。こうして、matching Podのスケジュールを失敗させることで、CAにNodeを増やさせることができる。
MaxDomainsはないの? 現状はないです。 議論のテーブルには上がりましたが、「強く必要とされるようなユースケースが思いつかんし、一旦おいとこ」となっています。
何でScheduleAnywayで使えないの? 技術的な面で言うとパフォーマンス的なところで心配があったためです。 (現在のドメイン数を計算するのがちょっと大変で、PreScoreでその計算を挟むことに懸念があった。) また、その技術面の懸念を押し切るほど有用なユースケースがないためでもあります。
まとめ - Pod Topology SpreadにTaintsを考慮させることが現状はできないことから、v1.24でNodeInclusionPoliciesが導入される。 - 現時点でDoNotScheduleを使っている人は Nodeの削除時などtaintsの扱いに注意が必要 。 - Pod Topology Spreadにドメイン自体の数を制御させることができないことから、v1.24でMinDomainsが導入される。