Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

2020 年の秋、改めて学ぶ Scheduling Framework #k8sjp / Ku...

y_taka_23
October 28, 2020

2020 年の秋、改めて学ぶ Scheduling Framework #k8sjp / Kubernetes Meetup Tokyo 35th

Kubernetes Meetup Tokyo #35 で使用したスライドです。

Kubernetes において Pod を配置する Node を決定する手続きをスケジューリングと呼びます。多くのユースケースではデフォルトのスケジューリングで充分ですが、機械学習基盤や大規模なネットワークストレージとの併用など、一部の用途ではドメイン知識を反映したスケジューリングが必要になります。

このような場合、従来は JSON Webhook で動作する Scheduler Extender が使用されていましたが、拡張性の乏しさや実行時オーバヘッドに課題がありました。今回紹介する Scheduler Framework は、この問題を解決するために SIG Scheduling により実装が進められてきたプロジェクトです。

前回、2019 年の 2 月の段階 (https://speakerdeck.com/ytaka23/kubernetes-meetup-tokyo-16th) ではプロジェクトの大部分が未実装な状態でした。それから 一年半が経過し、v1.19.0 の段階では、既存の kube-scheduler については Scheduling Framework ベースに移行が完了、また out-of-tree なオリジナル実装も可能な状態まで整備されています。

イベント概要:https://k8sjp.connpass.com/event/191298/
録画:https://youtu.be/sOAOazECemA?t=6453

y_taka_23

October 28, 2020
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

  1. #k8sjp Pod 配置へのドメイン知識の反映 • Scheduler Extender ◦ JSON Webhook で外部サービスに問い合わせ

    ◦ 拡張点が限定的(4 箇所)、実行時オーバヘッドも大きい • Scheduler Framework ◦ Go で指定の Interface を実装して本体と同時にビルド ◦ 自由度は高く(12 箇所)、パフォーマンスは良い
  2. #k8sjp 拡張点ごとのインタフェース // 条件に合う Node の候補をリストアップする Plugin type FilterPlugin interface

    { Name() string Filter(ctx context.Context, state *CycleState, pod *v1.Pod nodeInfo *NodeInfo) *Status } // その中からベストな Node を選ぶための比較用 Plugin type ScorePlugin interface { Name() string Score(ctx context.Context, state *CycleState, pod *v1.Pod nodeInfo *NodeInfo) (int64, *Status) }
  3. #k8sjp Scheduling Cycle Plugin A Plugin B Plugin C PreFilter

    Filter Score 共通条件 重み付き合計
  4. #k8sjp Scheduling Cycle Plugin A Plugin B Plugin C PreFilter

    Filter Score CycleState 任意の Key-Value 事前計算 参照 参照
  5. #k8sjp Scheduling Framework の進捗 • 提案されていた拡張点の実装完了 ◦ 既存のロジックも Plugin として移植済み

    • Plugin を組み合わせて Scheduling Profile を定義 ◦ ひとつのスケジューラに複数の Profile を定義可能 • Out-of-Tree のスケジューラ実装が可能に ◦ Framework を外部から呼び出せば Fork は不要
  6. #k8sjp Scheduling Framework の進捗 • 提案されていた拡張点の実装完了 ◦ 既存のロジックも Plugin として移植済み

    • Plugin を組み合わせて Scheduling Profile を定義 ◦ ひとつのスケジューラに複数の Profile を定義可能 • Out-of-Tree のスケジューラ実装が可能に ◦ Framework を外部から呼び出せば Fork は不要
  7. #k8sjp Scheduling Framework の進捗 • 提案されていた全箇所の拡張点の実装完了 ◦ 既存のロジックも Plugin として移植済み

    • Plugin を組み合わせて Scheduling Profile を定義 ◦ ひとつのスケジューラに複数の Profile を定義可能 • Out-of-Tree のスケジューラ実装が可能に ◦ Framework を外部から呼び出せば Fork は不要
  8. #k8sjp Scheduler の設定ファイル apiVersion: kubescheduler.config.k8s.io/v1beta1 kind: KubeSchedulerConfiguration profiles: - schedulerName:

    binpack-scheduler plugins: score: enabled: - name: NodeResourceMostAllocated disabled: - name: NodeResourceLeastAllocated - name: NodeResourceBalancedAllocation - schedulerName: another-scheduler ...
  9. #k8sjp Scheduler の設定ファイル apiVersion: kubescheduler.config.k8s.io/v1beta1 kind: KubeSchedulerConfiguration profiles: - schedulerName:

    binpack-scheduler plugins: score: enabled: - name: NodeResourceMostAllocated disabled: - name: NodeResourceLeastAllocated - name: NodeResourceBalancedAllocation - schedulerName: another-scheduler ... apiVersion: v1 kind: Pod metadata: name: my-pod spec: schedulerName: binpack-scheduler container: - name: my-app image: ytaka23/my-app:v1.0.0 ...
  10. #k8sjp Scheduling Framework の進捗 • 提案されていた全箇所の拡張点の実装完了 ◦ 既存のロジックも Plugin として移植済み

    • Plugin を組み合わせて Scheduling Profile を定義 ◦ ひとつのスケジューラに複数の Profile を定義可能 • Out-of-Tree のスケジューラ実装が可能に ◦ Framework を外部から呼び出せば Fork は不要
  11. #k8sjp Out-of-Tree スケジューラの実装 import scheduler "k8s.io/kubernetes/cmd/kube-scheduler/app" func main() { command

    := scheduler.NewSchedulerCommand( scheduler.WithPlugin("my-plugin-1", MyPlugin1), scheduler.WithPlugin("my-plugin-2", MyPlugin2), ..., ) if err := command.Execute(); err != nil { fmt.Printf(os.Stderr, "%v\n", err) os.Exit(1) } }
  12. #k8sjp Out-of-Tree スケジューラの実装 import scheduler "k8s.io/kubernetes/cmd/kube-scheduler/app" func main() { command

    := scheduler.NewSchedulerCommand( scheduler.WithPlugin("my-plugin-1", MyPlugin1), scheduler.WithPlugin("my-plugin-2", MyPlugin2), ..., ) if err := command.Execute(); err != nil { fmt.Printf(os.Stderr, "%v\n", err) os.Exit(1) } } トップレベルから Plugin の注入が可能に
  13. #k8sjp Out-of-Tree の実験的 Plugin • QoS (QueueSort) ◦ スケジュールの順番を Pod

    の Priority から QoS に変更 • CrossNodePreemption (PostFilter) ◦ 複数の Node 上の Pod を合わせて追い出す • CoScheduling (QueueSort, PreFilter, Permit, Reserve) ◦ 特定個数の Pod が集まるまで待機して all or nothing で配置
  14. #k8sjp まとめ • スケジューリングのカスタマイズ問題 ◦ 実行時のオーバヘッドを抑えつつ拡張点を提供 • Plugin 方式の Scheduling

    Framework ◦ スケジューラとまとめてひとつのバイナリにビルド • 2019 年後半から 2020 年にかけて大きく進展 ◦ 既存ロジックの移植完了、Out-of-Tree でもビルド可能に