前回、前々回に引き続き、社内kubernetes勉強会が開催されました。
今回のテーマはkube-scheduler!
アジェンダはこちらです。
「要件に合った自分好みのScheduler Extenderを作るにしても、
まずは通常のSchedulerの処理を理解したいよね」
というのがモチベーションです。
kube-schedulerの概要
kube-shcedulerの主な役割は
podが起動するNodeを割り当てること
ではどのような基準でNodeを選定しているのでしょうか?
Nodeの選定には
- predicate(デプロイ条件満たすか)
- prioritize(ノードの選定のための点数審査)
という処理が行われています。
では実際はどのように判定されているのか、実装を見ていきたいと思います。
※以下のPFN大村さんの記事が大変参考になりました。先人の業績に感謝。。 qiita.com
kube-schedulerの実装
今回読んでみたコードはこの辺りです。
- kubernetes/cmd/kube-scheduler (*binaryのentrypoint etc...)
- kubernetes/pkg/scheduler (*実際の実装はだいたいこっち)
Node選定の判定処理はそれぞれ1つの関数として実装されています。
kubernetes/defaults.go at master · kubernetes/kubernetes · GitHub
毎度のことですが、参照に渡る参照でデータ構造を把握するのが大変ですが、
struct genericSchedulerがSchedule()
の実体を持っています。
関連の深い箇所だけ抜粋すると以下のような形で実装されています。
Predicateの実装
Predicateでは各ノードに対して、
predicateルールに基づいたチェックが実行しその合否をboolean
で返して、
全てのチェックがtrue
だったNodeがfilteredという合格したノードのリストとして次のPrioritizeの処理に移されます。
例えばCheckNodeDiskPressureであればnodeInfo.diskPressureCondition()
の結果で判定しています。
Prioritizeの実装
PrioritizeもPredicateのように各ルールに基づいたチェックを実行しますが、
PriorityConfig.Wight
にある重みを掛けたスコアをNode毎に合算しています。
その後、最高のスコアのNodeが選定される、という処理になっています。
Scheduler Extender
最後にschedulerの拡張であるScheduler Extenderですが、
- Predicate
- Prioritize
- Preempt
- Bind
の4つの工程に任意の処理を追加できます。
やり方としては、custom-schedulerをWeb APIサーバとして立て、
各Scheduler処理に対応したURLに対してリクエストしてAPIサーバ側がHandlerを処理しレスポンスを受け取る、
ということを行います。
設定方法としては、podのマニフェストに
pod.spec.SchedulerName
としてCustomScheduler名を指定するとConfigMapのconfig.yamlが参照され、
config.yamlにPolicy名として書かれたConfigMapのconfig.cfgの指定されたCustomSchedulerの処理を追加する、という流れになります。
実際のExtenderの実装については、
PFN大村さんが書かれているサンプル実装を読んでみると良さそうです。
勉強会は以上になります。
まだコードを読みきれていない部分もありますが、大枠の流れは掴めたように思います。