kube-scheduler-simulatorを本物のK8sクラスターに繋いでスケジューラ実装のデモを行う

English version here.

前回の記事で、kube-scheduler-simulatorを用いて独自K8sスケジューラの開発環境を構築する方法を説明しました。 スケジューラを作ったら、本物のクラスターで試したくなるでしょう。

本稿では、kube-scheduler-simulator内で作成したスケジューラ実装を本物のクラスターに移植する方法と、 kube-scheduler-simulatorを使ってデフォルトスケジューラとの動作の違いを可視化する方法を説明します。

スケジューラを本物のクラスターにデプロイする

公式ドキュメント「Configure Multiple Schedulers」でスケジューラをデプロイする手順が紹介されています。 スケジューラというと特別なコンポーネントに思えるかもしれませんが、スケジューラもほかのコントローラと同じように動作します。 ここで重要なのは、スケジューラは実行可能ファイルだということです。

前回の記事で説明したようにkube-scheduler-simulatorツリー内でスケジューラを作成した場合、Go言語のパッケージとして実装したはずです。 これを本物のクラスターで動作させるには、main()でラップしてコマンドにする必要があります。

minischedを実行可能なコマンドとしてビルドする

前回から引き続き、愉快な例としてminisched (initial-random-schedulerバージョン)を使うことにします。 デフォルトのスケジューラと全く動作が異なるため、変化が分かりやすいでしょう。

以下にminischedを実行可能なmain()の例を示します。

package main

import (
	"context"
	"flag"
	"k8s.io/apiserver/pkg/server"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/klog/v2"
	"example.com/kube-random-scheduler/minisched"
)

func main() {
	kubeconfig := flag.String("kubeconfig", "", "kubeconfig config file")
	flag.Parse()

	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		klog.Fatalf("Error building kubeconfig: %s", err.Error())
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		klog.Fatalf("Error building example clientset: %s", err.Error())
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go func() {
		stopCh := server.SetupSignalHandler()
		<-stopCh
		cancel()
	}()
	informerFactory := informers.NewSharedInformerFactory(clientset, 0)
	sched := minisched.New(clientset, informerFactory)
	informerFactory.Start(ctx.Done())
	informerFactory.WaitForCacheSync(ctx.Done())
	sched.Run(ctx)
}

これをビルドするには、以下のツリーを作成してください。

kube-random-scheduler
├── main.go
└── minisched

ツリー内のminischedディレクトリはmini-kube-schedulerからコピーしてください。 またminisched/initialize.go内のimportを以下のように変更する必要があります。

Patch license: MIT (same as mini-kube-scheduler)

--- a/minisched/initialize.go
+++ b/minisched/initialize.go
@@ -1,7 +1,7 @@
 package minisched

 import (
-       "github.com/sanposhiho/mini-kube-scheduler/minisched/queue"
+       "example.com/kube-random-scheduler/minisched/queue"
        "k8s.io/client-go/informers"
        clientset "k8s.io/client-go/kubernetes"
 )

以下のコマンドでビルドします。

$ go mod init example.com/kube-random-scheduler
$ go mod tidy
$ CGO_ENABLED=0 go build -v -o kube-random-scheduler main.go

実行ファイルをビルドできたら公式ドキュメントのConfigure Multiple Schedulersに従ってデプロイできます。 ただし上記のmain()healthzの実装がないため、ドキュメント内のマニフェストからlivenessProbereadinessProbeを削除する必要があります。

kube-scheduler-simulatorでスケジューラの動作を可視化する

スケジューラのローレベルな動作を可視化したいのですが、Dashboardの機能では十分でないため、 kube-scheduler-simulatorのフロントエンドを使うことにしました。

kube-scheduler-simulatorはsimulator-server, simulator-etcd, simulator-frontendの3個のコンテナで動作します。 simulator-frontendはNuxt.jsアプリで、simulator-serverとREST APIで通信します。 このREST APIはオリジナルのK8sと互換性があるので、simulator-frontendを本物のクラスタで動作しているkube-apiserverと接続できます。 これにより本物のクラスタで動作しているスケジューラのローレベルな動作を可視化できるようになります。

まずkube-apiserver--cors-allowed-originsオプションを追加します。

--- kube-apiserver.yaml.orig    2022-09-01 18:06:34.983636661 +0900
+++ kube-apiserver.yaml 2022-09-01 18:06:12.459666678 +0900
@@ -13,6 +13,7 @@
   containers:
   - command:
     - kube-apiserver
+    - --cors-allowed-origins=http://*
     - --advertise-address=192.168.1.51
     - --allow-privileged=true
     - --anonymous-auth=True

次にkube-scheduler-simulatorが動作しているホスト上でkubectl proxyを実行します。

simulator-pc$ docker-compose up -d simulator-frontend
simulator-pc$ kubectl proxy

最後にウェブブラウザを動作させるホスト上でkube-scheduler-simulatorkubectl proxyへのトンネルを作成します。

frontend-pc$ ssh -L 3000:localhost:3000 -L 3131:localhost:8001 simulator-pc

うまくいったら、ブラウザ上でランダムスケジューラの動作を確認できます。

まとめ

  • スケジューラは実行可能ファイルの形式でビルドします
  • kube-scheduler-simulatorを使って本物のクラスターの動作を可視化できます

参考文献


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です