はじめに
Kubernetes v1.19 がリリース されてから1ヶ月程経ちましたね! みなさんv1.19は活用されているでしょうか!? 少しリリースから時間が立ってしまいましたが、Kubernetes 1.19.0のCHANGELOG をベースにSIG Schedulingにおける変更内容について紹介します。
v1.19における変更で一番の注目はやはり__Scheduling Frameworkでの PostFilter
拡張点の新規導入__です。この拡張点を利用することで__Preemptionのロジックが自由にカスタマイズできるようになります。__
以前のkube-schedulerでは Priority and Preemptionにおける Preemption(低優先度のPodを高優先度のPodをスケジュールするために停止)処理、つまりどの低優先度Podを犠牲にするか?、のロジックがscheduler内にほぼすべてハードコードされていました。このおかげで、scheduler policyを柔軟にチューニングしていても、Preemptionが発生すると、チューニングしたscheduler policyを考慮しない低優先度Podが犠牲となってしまい、その引き金となった高優先度Podは基本的にその犠牲となったPodのスケジュールされたnodeへスケジュールされる(保証はされない)ため、チューニングの効果が限定されてしまうという問題がありました。
PostFilter
拡張点はSchedulerにおけるFilter(Podを配置可能なノードを選択する内部フェーズ)失敗時の調停フェーズをPluginとして拡張する機構を提供することで、これをより一般的な形で解決しています(ハードコードされていたpreemptionロジックはPostFilterプラグインとしてデフォルトで有効化されています)。これでforkせずにPreemptionロジックを変更できるようになりますね💪💪!
私は以前からこの問題を認識していてKubeCon+CloudNativeCon 2019 NA(San Diego)にてSIG SchedulingのchairであるHuang-Wei, ahg-gとのディスカッションを通してPreemptionにおける犠牲Pod選択戦略のカスタマイズという#85871を提起させていただき、その後、SIG Schedulingコミュニティでの議論(#90025)を経て、PostFilter
拡張点としてリリースされたものなので大変に嬉しく思っています。
がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。
What's New (新情報)
KubeSchedulerConfiguration が beta へ
SIG Scheduling は KubeSchedulerConfiguration
を Beta へ昇格しました。KubeSchedulerConfiguration
機能により kube-scheduler のアルゴリズムや特定の設定をチューニングできます。選択したスケジューリングフェーズの特定の機能(プラグインに含まれる)を簡単に有効化したり無効化したりすることができます。さらに、一つの kube-scheduler インスタンスから、プロファイルと呼ばれる異なる設定を提供することができます。Podは .spec.schedulerName
フィールドでスケジュールしたいプロファイルを選択することができます。
古くは kube-schedulerの設定ファイルの kind
だった componentconfig/v1alpha1
でしたが、v1.12で kubescheduler.config.k8s.io/v1alpha1
となり、v1.18で kubescheduler.config.k8s.io/v1alpha2
にバージョンアップ しました。 この v1alpha2
から 複数プロファイルがサポートされ、今回めでたく beta に昇格しました。 複数プロファイルを使うと、一つのkube-schedulerインスタンスで複数のスケジュール戦略をホストできます。複数プロファイルの詳細については KEP-1451 を参照してください。尚、 このbeta昇格に関する Urgent Upgrade Notes(必ず一読してからアップグレードしなければならない事項) もありますので要確認です。
複数プロファイルと複数スケジューラの違いって何?と思われるかもしれません。一番の大きな違いは、scheduler内部のキューをプロファイル横断で共有できる点だと個人的には思っています。 kube-schedulerでは Priority and Preemption機能をつかって、クラスタに空きがない場合でもPreemption(高Priority Podをスケジュールするために低Priority Podを停止)を行うことで高Priority Podをスケジュールすることができます。が、この機能は cross-scheduler preemptionとでも呼べる挙動となっています。つまり、 scheduler名が異なる Podも一律に preemption対象とされてしまいます。 これを効率的に機能させるためには「基本的に高 Priority Pod は低 Priority Pod よりも前にスケジュールしておく」必要があります。これを行わない場合、スケジュールされた低 Priority Pod がすぐに Preemption されるといった、無用な Preemption が起こる可能性があるからです。複数schedulerインスタンスをデプロイすると、それぞれのインスタンスがそれぞれのタイミングでスケジュールを行うので、無用なPreemptionが増えてしまいます。一方で、複数プロファイルを使えば、kube-scheduler内部のキューを複数プロファイルで共有できるため無用なPreemptionを効果的に減らすことができます。
Storage capacity tracking
これまで、Kubernetesのスケジューラは、追加の永続ストレージがクラスタ内のどこでも利用可能且つ無限の容量をもっているという想定でした。
トポロジーの制約により前者には対応しましたが、しかし、今までのPod スケジューリングは、ストレージの残り容量が新しいPodをスタートさせるのに十分でない可能性があることを考慮していませんでした。
ストレージ容量のトラッキング(アルファ機能)は、CSIドライバー向けにストレージ容量をレポートするAPIを追加することで、KubernetesのスケジューラがPodの新しいノードを選択する際に、この情報を使えるようになりました。
この機能は、容量が制限されるLocal Volumeや他のVolumeタイプのダイナミックプロビジョニングをサポートするための、足がかりとして提供します。
Urgent Upgrade Notes(必ず一読してからアップグレードしなければならない事項)
-
kubescheduler.config.k8s.io/v1alpha2
からkubescheduler.config.k8s.io/v1beta1
へアップグレードしてください。-
.bindTimeoutSeconds
はprofile毎に設定できるVolumeBinding
pluginの設定の一部となりました。 -
.extenders
はAPI 標準を満たすように更新されています。 特に-
.extenders
は case-sentive に decodeされるようになります。全てのフィールドが対象です。 -
.extenders[*].httpTimeout
はmetav1.Duration
型になります。 -
.extenders[*].enableHttps
は.extenders[*].enableHTTPS
に変更になります。
-
-
-
RequestedToCapacityRatio
の設定は case sensitiveにdecodeされるようになります。全てのフィールドが対象です。 -
DefaultPodTopologySpread
plugin はSelectorSpread
という名前に変更になります。 -
Unreserve
拡張点は Profile定義から削除されます。すべてのReserve
pluginはUnreserve
呼び出しを実装するようになります。 -
.disablePreemption
は削除されました。 "DefaultPreemption" PostFilter pluginを無効にすることでpreemptionを無効にできます。(#91420, by pancernik) [SIG Scheduling]
Deprecation (非推奨)
- Schedulerのalpha機能である
ResourceLimitsPriorityFunction
はあまり利用されてないため削除されました。(#91420, by pancernik) [SIG Scheduling]
API Change(API の変更)
-
schuler設定である
KubeSchedulerConfiguration
からBindTimeoutSeconds
を削除。 (#91580, by cofyc) [SIG Scheduling and Testing] -
kubescheduler.config.k8s.io/v1alpha1 を削除。 (#89298, by gavinfish) [SIG Scheduling]
-
Reserve Pluginでreserveに失敗したらunreserveをtriggerする。 (#92391, by adtac) [SIG Scheduling and Testing]
-
scheduler pluginのUnreserve拡張点をReserve拡張点に統合。 (#92200, by adtac) [SIG Scheduling and Testing]
-
NodeResourcesLeastAllocated
とNodeResourcesMostAllocated
で CPUとMemoryのカスタムweightをサポート。 (#90544, by chendave) [SIG Scheduling] -
scheduler component config APIのversion v1beta1に
PostFilter
タイプを追加。 (#91547, by Huang-Wei) [SIG Scheduling] -
RequestedToCapacityRatioArgs
エンコーディングをstrictに行う。 (#91603, by pancernik) [SIG Scheduling] -
v1beta1
SchedulerExtender
エンコーディングをcase-sensitiveに (v1alpha1
/v1alpha2
はcase-insensitiveだった),httpTimeout
フィールドでdurationエンコーディングに(例えば1秒は"1s"
),v1alpha1
/v1alpha2
ではenableHttps
フィールドだったのをenableHTTPS
に名前を変更する。 (#91625, by pancernik) [SIG Scheduling]
Feature (機能)
- これまでhard-codeされていたPod preemptionロジックを defaultpreemption pluginとして登録し、schedulerで有効化する。 (#92049, by Huang-Wei) [SIG Scheduling and Testing]
-
PostFilter
拡張点をscheduler framwrokに新しく追加。Filter phase後にfilterの失敗を解決するために実行される。典型な実装とはpreeptionロジックがある。 (#91314, by Huang-Wei) [SIG Scheduling and Testing] - 詳細なscheduler scoring結果をverbose level 10で表示可能にする。 (#89384, by Huang-Wei) [SIG Scheduling]
- DefaultPodTopologySpread feature gateの有効化でPodTopologySpreadを使う。この場合DefaultPodTopologySpread pluginは無効にする。 (#91793, by alculquicondor) [SIG Scheduling]
- より良いspreadingを実現するPodTopologySpreadingの新スコアリング(#90475, by alculquicondor) [SIG Scheduling]
- PodTolerationRestriction: Error時にWhitelist Scopeを明示する。 (#87582, by mrueg) [SIG Scheduling]
- PodTopologySpreading で maxSkewが増加した際に差分をへらすようなScore。 (#90820, by alculquicondor) [SIG Scheduling]
- PodTopologySpread schduling ScoreのWeightを2倍に変更。 (#91258, by alculquicondor) [SIG Scheduling]
- scheduler plugin開発者が クラスタレベルのeventを記録するために利用できるように
EventRecorder()
をFrameworkHandle
インターフェースにexposeする。 (#92010, by Huang-Wei) [SIG Scheduling] - 複数のイメージを持つpodのnode優先度を適切に判断するために、
ImageLocality
pluginのmaxThreshold
をpod内のイメージ数に比例させる。 (#91138, by chendave) [SIG Scheduling]
Bug or Regression(バグまたはリグレッション)
- Podがスケジュールされているにもかかわらずanotation変更によって発生する不要なscheduling churnを回避する。 (#90373, by fabiokung) [SIG Scheduling]
- requiredなaffinity termをもつ最初のPodをtopology keyを満たすノードにのみスケジュールする。 (#91168, by ahg-g) [SIG Scheduling]
- nodeをそのnodeのpodよりも前に削除したときに発生するscheduler crashを修正。 (#89908, by alculquicondor) [SIG Scheduling]
- nodeの削除時にPodのnominatedNodeNameがクリアされない問題を修正。 (#91750, by Huang-Wei) [SIG Scheduling and Testing]
- HA環境において、standby schedulerでAPI serverとの接続が切れている間にPodが削除&再作成され、その後そのstandby schedulerがmasterになった場合にscheduler cacheが壊れる問題を修正。(#91126, by Huang-Wei) [SIG Scheduling]
- schedule再試行時にPod Conditionの更新をスキップ。 (#91252, by alculquicondor) [SIG Scheduling]
- PolicyからCCへの移行を援助するため、Scheduler v1 Policy config または algorithm-provider設定を v1beta1 ComponentConfigに渡せるようにする。 (#92531, by damemi) [SIG Scheduling]
- 利用可能なnodeが存在しない場合のScheduling失敗を
schedule_attempts_total
メトリックのunschedulableとして記録する。 (#90989, by ahg-g) [SIG Scheduling]