OpenShiftのデフォルトスケジューラにおけるSelectorSpreadPriorityのスコア

OpenShift 4.6までの古い内容です。OpenShift 4.7からはSelectorSpreadではなくPodTopologySpreadとなります。

Red HatでOpenShiftのサポートをしているid:nekopです。OpenShift 全部俺 Advent Calendar 2018 - Qiitaの2日目のエントリです。投稿日は12/3ですが細かいことは気にしないでゆるゆるやっていくポリシーです。

OpenShiftのデフォルトのスケジュール設定は/etc/origin/master/scheduler.jsonにあり、プライオリティは以下の定義となっています。ファイル形式はjsonですがjsonだと行数かさむのでyaml形式に変換して転記しています。

priorities:
- name: SelectorSpreadPriority
  weight: 1
- name: InterPodAffinityPriority
  weight: 1
- name: LeastRequestedPriority
  weight: 1
- name: BalancedResourceAllocation
  weight: 1
- name: NodePreferAvoidPodsPriority
  weight: 10000
- name: NodeAffinityPriority
  weight: 1
- name: TaintTolerationPriority
  weight: 1
- argument:
    serviceAntiAffinity:
      label: zone
  name: Zone
  weight: 2

SelectorSpreadPriorityによってノード障害耐性を高めるために同種Podは同一ノードにスケジュールされない、というところが基本にはなるのですが、LeastRequestedPriorityなどリソースの都合によってはこの「同種Podは同一ノードにスケジュールされない」というプライオリティが常に動作しない状況になったりしないか?という疑問が残ります。

裏をとるためSelectorSpreadPriorityのソースコードを見てみましょう。k8s 1.11です。

https://github.com/kubernetes/kubernetes/blob/release-1.11/pkg/scheduler/algorithm/priorities/selector_spreading.go#L278

計算式を自然言語で記述すると以下のようになります。

10 * (既にスケジュールされている対象Pod数 - このノード上の対象Pod) / 既にスケジュールされている対象Pod数

nodeA, nodeBがあり、1 podが既にnodeAにスケジュールされているときの2 pod目のスケジュールを考えてみます。nodeAのプライオリティスコアは10 * (1 - 1) / 1 = 0となるので0になります。一方nodeBは10 * (1 - 0) / 1 = 10となるので、満点の10が返却されます。

比較対象として、ノードのリソースを考慮するLeastRequestedPriorityなどを見てみます。

https://github.com/kubernetes/kubernetes/blob/release-1.11/pkg/scheduler/algorithm/priorities/least_requested.go#L27

CPUとメモリについて以下の計算を行って平均しているので、例えば80%使用中のノードに10%利用するリクエストのPodをスケジュールする場合は(20 - 10) * 10 / 20 = 5となります。残キャパシティが50%であれば8ですね。相当埋まっていてもそこそこのプライオリティスコアが返却されるようです。

(残キャパシティ - 対象Podのリクエスト) * 10 / 残キャパシティ

というわけで、SelectorSpreadPriorityのキモは2 pod目のスケジュールです。2 pod目のスケジューリング時に少なくとも既にスケジュールされているノードとそうでないノードとのプライオリティスコアが10という大差がつくので、2 pod目で2ノードにきちんと分散される、ということがわかります。もちろん他のプライオリティで10以上の差が出るようなスコアが算出されない限り、という条件はつきますが、他のプライオリティはここまで極端な差はでないので問題なさそうです。3 pod目以降のケースでは、リソース利用がかたよっている場合にプライオリティスコアが逆転するので偏ったスケジュール結果になることもありそうですし、実際やってみたら偏りました。これを防止するにはプライオリティのweightを調整すればできそうです。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。