基于scheduler framework开发自定义调度器

发布时间 2023-08-12 20:17:23作者: 王景迁

k8s v1.19.0
基于scheduler framework开发插件,本质上是实现接口。

下载代码

mkdir sigs.k8s.io
cd sigs.k8s.io
git clone https://github.com/kubernetes-sigs/scheduler-plugins.git
cd scheduler-plugins
git checkout release-1.19

新增代码

pkg目录下新增label_a_b目录

package label_a_b

import (
	"context"
	"log"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
)

// Name is the name of the plugin used in the plugin registry and configurations.
const Name = "labelAB"

type labelAB struct{}

var _ framework.FilterPlugin = &labelAB{}
var _ framework.PreScorePlugin = &labelAB{}

// New initializes a new plugin and returns it.
func New(_ runtime.Object, _ framework.FrameworkHandle) (framework.Plugin, error) {
	return &labelAB{}, nil
}

// Name returns name of the plugin.
func (pl *labelAB) Name() string {
	return Name
}

func (pl *labelAB) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
	log.Printf("filter pod: %v, node: %v", pod.Name, nodeInfo)
	log.Println(state)
	// 排除没有a=b标签的节点
	if nodeInfo.Node().Labels["a"] != "b" {
		return framework.NewStatus(framework.Unschedulable, "Node: "+nodeInfo.Node().Name)
	}
	return framework.NewStatus(framework.Success, "Node: "+nodeInfo.Node().Name)
}

func (pl *labelAB) PreScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodes []*v1.Node) *framework.Status {
	log.Println(nodes)
	return framework.NewStatus(framework.Success, "Node: "+pod.Name)
}

cmd/scheduler/main.go

注册自己的插件,注释其他

编译二进制

cd cmd/scheduler
go build -o label_a_b main.go
chmod +x label_a_b

构建镜像

cd scheduler-plugins
cat > Dockerfile <<EOF
FROM busybox:1.36
WORKDIR /
COPY label_a_b /usr/bin
CMD ["label_a_b"]
EOF
docker build --load -t label_a_b:v1 .

创建RBAC和ConfigMap以及deploy

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: label-a-b-sa
  namespace: kube-system
EOF

cat <<EOF | kubectl create -f -
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sample-scheduler-clusterrolebinding
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: label-a-b-sa
  namespace: kube-system
EOF

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: scheduler-config
  namespace: kube-system
data:
  scheduler-config.yaml: |
    apiVersion: kubescheduler.config.k8s.io/v1beta1
    kind: KubeSchedulerConfiguration
    leaderElection:
      leaderElect: false
    profiles:
    - schedulerName: label_a_b
      plugins:
        filter:
          enabled:
          - name: labelAB
        preScore:
          enabled:
            - name: labelAB
          disabled:
            - name: "*"
EOF

cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: label-a-b
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      component: label_a_b
  template:
    metadata:
      labels:
        component: label_a_b
    spec:
      serviceAccount: label-a-b-sa
      priorityClassName: system-cluster-critical
      volumes:
      - name: scheduler-config
        configMap:
          name: scheduler-config
      containers:
      - name: label-a-b
        image: label_a_b:v1
        command:
        - /usr/bin/label_a_b
        - --config=/etc/kubernetes/scheduler-config.yaml
        - --v=3
        volumeMounts:
        - name: scheduler-config
          mountPath: /etc/kubernetes
EOF

验证

cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      schedulerName: label_a_b
      containers:
      - image: busybox:1.36
        name: nginx
EOF

node1打上a:b标签后调度到该节点上。

参考资料

https://www.helloworld.net/p/5208016489