はじめに
Kubernetes 1.22がリリースされましたね
今回もKubernetes v1.22のCHANGELOGをベースにSIG Schedulingに関する機能について紹介していきます。
所感
v1.22では大きな機能追加はなく改善とバグ修正がメインとなっています。
- Score Pluginにおけるextended resource(GPU等)を考慮した改善
- schedulerは空き容量に応じてschedule可能なNodeのscoreを計算して最適なNodeを選択しますが、
NodeResources{LeastAllocated, MostAllocated, RequestedToCapacityRatio, BalancedAllocation}
といった典型的なnode score pluginでのGPU等のextended resourceの考慮が改善されました。
- schedulerは空き容量に応じてschedule可能なNodeのscoreを計算して最適なNodeを選択しますが、
-
Scheduling Frameworkの機能拡充
- SchedulerのComponentConfigで指定された
kubeconfig
がOut-of-tree pluginから利用可能に - Pluginから明示的にPodをBackoffQueue→ActiveQueueに移動させられることが可能に
- PluginでScheduler初期化時のevent handlerを登録できることが可能に
- 等、Pluginで実装できる範囲が広がりより柔軟なPlugin実装が可能になっています。
- SchedulerのComponentConfigで指定された
- kube-schedulerのComponentConfig
v1beta2
- 新しいVersionのComponentConfigですが、apiが大きく変わっているわけではなく、pluginのdeprecation/新規追加が主な目的です。
- (追加)
NodeResourcesFit
という新しいpluginが導入され、NodeResourcesLeastAllocated, NodeResourcesMostAllocated, RequestedToCapacityRatio
と別々のpluginで実装されていたものが統合されました。これらの相反するポリシーをユーザが誤って設定することがなくなってより安全な設定が可能になっています。 - (deprecation)
NodeResourcesLeastAllocated, NodeResourcesMostAllocated, RequestedToCapacityRatio, NodeLabel, ServiceAffinity, NodePreferAvoidPods
pluginがdeprecatedになり、v1beta1
では利用できなくなっています。
下記 がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。
What's New (新情報)
Urgent Upgrade Notes(必ず一読してからアップグレードしなければならない事項)
- Scheduler内の
CycleState
のRead()
,Write()
関数の内部でread/writeロックを取得するようになりました。 その結果Lock()
,Unlock()
関数が削除されました。Scheduler Plugin開発者はCycleState#Lock()
,CycleState#Unlock()
の呼び出しを除去して、スレッドセーフなRead()
,Write()
を呼び出すように変更する必要があります。(#101542, @Huang-Wei)
Deprecation (非推奨)
-
kube-scheduler
から既にdeprecatedだった--hard-pod-affinity-symmetric-weight
,--scheduler-name
が削除されました。 これらのパラメータを設定するには代わりにComponentConfig
を利用してください。(#102805, @ahg-g)
API Change (API の変更)
-
NodeResourcesLeastAllocated
,NodeResourcesMostAllocated
,RequestedToCapacityRatio
pluginがv1beta2
でdeprecatedとなり、新しいNodeResourcesFit
score extentionにマージされました。v1beta1
ではこれら3つのpluginは利用可能ですが、NodeResourcesFit
pluginと同時には利用できません。(#101822, @yuzhiquan)
KEP-2458: Resource Fit Scoring Strategyで提案されたものです。これら3つのscore pluginはお互いに相反する戦略を実装しているため、これらは同時に有効化されるべきではないにもかかわらず、個別のpluginとして提供されているため、同時に有効化することが可能となっていました。この変更にともなって各戦略は下記のようにNodeResourcesFit
pluginのscoringStragey
というplugin argsで指定するようになりました。詳細な設定項目はこちらを参照ください。また、deprecatedされたpluginはv1beta1
でしか設定できなくなっています。
設定例
apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-schedler
plugins: ...
pluginConfig:
- name: NodeResourcesFit
args:
ignoredResources: [ "some-special/device" ]
scoringStrategy:
type: LeastAllocated | MostAllocated | RequestedToCapacityRatio
resources:
- {"name": "cpu", "weight": 1}
- {"name": "memory", "weight": 1}
- PersistentVolumesとPersistentVolumeCaimsにReadWriteOncePodアクセスモードを追加します。単一ノード上の単一Podへのボリュームアクセスを制限します。(#102028, @chrishenzie) [SIG Apps, CLI, Node, Scheduling and Storage]
これまでのReadWriteOnce
アクセスモードは、あくまで1つのノードからRead/Writeでマウントする仕様でした。今回追加されたReadWriteOncePod
により、1 PodからのみRead/Write可能になります。Kubernetes 1.22: SIG Storageの変更内容 でも解説されていますのでそちらを御覧ください。
-
ComponentConfig
のv1beta2
では明示的に有効したpluginはdefaultの設定よりも優先されるようになります。これによって、デフォルトで有効なpluginの設定を変更する場合にdisableする必要がなくなります。(#99582, @chendave)
書かれているとおりですが、v1beta1
では、defaultプラグインの設定を変更する場合には一旦disable
してからenable
しなけれいけない、といいう、ユーザにとってわかりにくい挙動だったのが改善されました。
設定例
# v1beta1ではわざわざdisableしないと設定が有効にならない
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler
plugins:
score:
# NodeAffinity score pluginのweightを変更
enabled:
- name: NodeAffinity
weight: 100
disabled:
- name: NodeAffinity
---
# v1beta2ではこれでOK
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler
plugins:
score:
# NodeAffinity score pluginのweightを変更
enabled:
- name: NodeAffinity
weight: 100
-
NodeResourcesBalancedAllocation
score pluginで、CPU、メモリ以外のGPU等のリソースを考慮する設定が可能になります。 (#101946, https://github.com/chendave)
設定例
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler
plugins:
score:
enabled:
- name: NodeResourcesBalancedAllocation
weight: 1
pluginConfig:
- name: NodeResourcesBalancedAllocation
args:
resources:
- name: cpu
weight: 1
- name: memory
weight: 0
- name: nvidia.com/gpu
weight: 1
-
kube-scheduler
component configのv1beta2
APIが利用可能になりました。それに伴ってNodeLabel, ServiceAffinity, NodePreferAvoidPods
の3つのpluginがdeprecatedになりました。 (#99597, @adtac)
deprecatedされたpluginはv1beta1
でしか設定できなくなります。 それぞれ NodeLabel
→NodeAffinity
, ServiceAffinity
→InterPodAffinity
, NodePreferAvoidPods
→Node Taint、で代用することが想定されています。これらのpluginを利用している場合にはwarning logが出力されます。このPRではこの3つのpluginがdeprecatedになっていますが、この他に上で取り上げたNodeResourcesLeastAllocated
,NodeResourcesMostAllocated
,RequestedToCapacityRatio
pluginもdeprecatedにっており、v1.21で合計6個のpluginがdepreatedになっています。deprecatedなpluginの完全なリストはこちらを御覧ください。
- Pod Affinityにおける
NamespaceSelector
とそれに関するCrossNamespaceAffinity
quota scopeがbetaになり、デフォルトで有効になりました。 (#101496, @ahg-g) - 既にdeprecatedな
--algorithm-provider
フラグがkube-scheduler
から削除されました。代わりにComponentConfig
のplugin setを定義するようにしてください。(#102239, @Haleygo)
Feature (機能)
-
LeastAllocated
,MostAllocated
,RequestedToCapacityRatio
pluginに設定されているextended resoruceは、そのリソースを要求していないPodではbypassされるようになります。(#103169, @Huang-Wei)
これらのプラグインでは、extended resource(ここではGPUを例に説明します)を考慮するように設定が可能ですが、以前は、考慮するように設定してしまうと、GPUを要求していないPodでも、Node ScoreにGPUの割当状況が反映されたスコアが計算されるようになっていました。これだと、#103383で報告されているように、GPU 要求していないPodがGPUノードに割り当てられやすくなってしまい(GPUの割当状況がスコアに勘案されるため)、それによってGPUを要求するPodが将来的にスケジュールされにくくなってしまうという問題がありました。この機能が入ることで、GPUをPodが要求していないPodのNode ScoreではGPUの割当状況を計算しないようにbypassすることでこの状況が改善されるようになっています。
- Schedulerにいて、Plugin開発者がPodをactiveQに明示的に移動させることができるようになりました。(#103383, @Huang-Wei)
kube-schedulerではスケジュール可能なNodeが見つからないPodはscheduler内部のBackoffQueueにおかれてschedule試行の間隔が調整されています。これだと、Co-Scheduling等(aka Gang Scheduling)のユースケースでは、PodGroup内の全PodがActiveQueueに存在しない場合があり効率が悪くなってしまいます。この機能によって、Plugin開発者が、明示的にBackoffQueueからActiveQueueに強制的にPodを移動させられるようになるため、Co-Schedulingのようなユースケースで効率よくスケジューリングができるようになります。
- scheduler framework handleでkubeconfigがexposeされるようになります。これによってOut-of-tree pluginが容易にCRD inforemerを作れるようになります。(#100644, @Huang-Wei) [SIG Apps, Scheduling and Testing]
これまでOut-of-tree pluginを実装する場合に、schedulerに設定されたkubeconfigが受け取れないため毎回pluginの設定で自分でkubeconfigパスを指定する必要があり煩雑だったのですが、この変更で安全にschedulerにセットされたconfigが受け取れるようになりました。地味ですがplugin開発者にとっては結構嬉しい変更です。
-
PreferNominatedNode
がBetaに昇格しデフォルトで有効になります。(#102201, @chendave) - Schedulerにおいてevent handlerが動的に登録できるようになります。 (#101394, @Huang-Wei)
Documentation
ありません。
Failing Test (失敗しているテスト)
ありません。
Bug or Regression (バグまたはリグレッション)
- scheduler内にphantomなpreemptor podが存在してしまうバグを修正しました。(#102498, @Huang-Wei)
このバグによって実際は空きがあるNodeにもかかわらずPodがスケジュールされない状況が発生してしまいます。この修正はv1.19以降のすべてのマイナーバージョンにbackportされています。これらのバージョンを利用されている場合は最新のマイナーバージョンへバージョンアップをおすすめします。
-
NodeResourcesMostAllocated
,NodeResourcesBalancedAllocation
pluginで、nodeがrequests
を持たないコンテナが存在する場合のScore計算を修正しました。 この修正によって小規模なNodeで発生していしまう利用率が低くなってしまう状況を改善しています。(#102925, @alculquicondor)
requests
節を持たないPodでは、小さなdefault値を与えてscoreを計算していましたが、これだと、小規模なNodeに大量のrequests
節を持たないPodがスケジュールされると、それらが積み上がってscheduleされない状況が発生していましたが、この修正ではそれが改善されています。この修正はv1.19以降のすべてのマイナーバージョンにbackportされています。これらのバージョンを利用されている場合は最新のマイナーバージョンへバージョンアップをおすすめします。
- Preemption時にscheduler extenderが呼ばれなかったバグを修正しました。(#103019, @ordovicia)
この修正はv1.20以降のすべてのマイナーバージョンにbackportされています。これらのバージョンを利用されている場合は最新のマイナーバージョンへバージョンアップをおすすめします。
schedulerはschedule結果をPodに記録する際にPod全体のmerge patchを生成するようになっていましたが、#101697に報告されているようにimagePullSecrets: [{}]
のようなspecを含むPodで、mergeに失敗し続けてしまい、scheduleされないバグがありました。このPRでpod statusのみに絞ってmerge patchを変更することでこれを修正しています。この修正はv1.19以降のすべてのマイナーバージョンにbackportされています。これらのバージョンを利用されている場合は最新のマイナーバージョンへバージョンアップをおすすめします。
Other (その他の修正)
ありません。