mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-24 10:23:43 +08:00
124 lines
3.6 KiB
Go
124 lines
3.6 KiB
Go
// Copyright 2019 Yunion
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
gin "github.com/gin-gonic/gin"
|
|
v1 "k8s.io/api/core/v1"
|
|
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api/v1"
|
|
|
|
"yunion.io/x/log"
|
|
|
|
k8spredicates "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates/k8s"
|
|
schedman "yunion.io/x/onecloud/pkg/scheduler/manager"
|
|
)
|
|
|
|
func InstallK8sSchedExtenderHandler(r *gin.Engine) {
|
|
r.POST("/k8s/predicates", timer(k8sPredicatesHandler))
|
|
//r.POST("/k8s/priorities", timer(k8sPrioritizeHandler))
|
|
}
|
|
|
|
func k8sPredicatesHandler(c *gin.Context) {
|
|
if !schedman.IsReady() {
|
|
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("Global scheduler not init"))
|
|
return
|
|
}
|
|
|
|
var extenderArgs schedulerapi.ExtenderArgs
|
|
var extenderFilterResult *schedulerapi.ExtenderFilterResult
|
|
|
|
if err := json.NewDecoder(c.Request.Body).Decode(&extenderArgs); err != nil {
|
|
extenderFilterResult = &schedulerapi.ExtenderFilterResult{
|
|
Nodes: nil,
|
|
FailedNodes: nil,
|
|
Error: err.Error(),
|
|
}
|
|
} else {
|
|
extenderFilterResult = k8sPredicateFunc(extenderArgs)
|
|
}
|
|
c.JSON(http.StatusOK, extenderFilterResult)
|
|
}
|
|
|
|
func k8sPredicateFunc(args schedulerapi.ExtenderArgs) *schedulerapi.ExtenderFilterResult {
|
|
pod := args.Pod
|
|
canSchedule := make([]v1.Node, 0, len(args.Nodes.Items))
|
|
canNotSchedule := make(map[string]string)
|
|
for _, node := range args.Nodes.Items {
|
|
result, err := doK8sPredicates(pod, &node)
|
|
if err != nil {
|
|
canNotSchedule[node.Name] = fmt.Sprintf("%s: %v", node.Name, err)
|
|
} else {
|
|
if result {
|
|
canSchedule = append(canSchedule, node)
|
|
}
|
|
}
|
|
}
|
|
return &schedulerapi.ExtenderFilterResult{
|
|
Nodes: &v1.NodeList{
|
|
Items: canSchedule,
|
|
},
|
|
FailedNodes: canNotSchedule,
|
|
Error: "",
|
|
}
|
|
}
|
|
|
|
func doK8sPredicates(pod *v1.Pod, node *v1.Node) (bool, error) {
|
|
hosts, err := schedman.GetK8sCandidateHosts(node.Name)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if len(hosts) == 0 {
|
|
return false, fmt.Errorf("Not found candidate host %s", node.Name)
|
|
}
|
|
k8sCli, err := schedman.GetK8sClient()
|
|
if err != nil {
|
|
log.Warningf("Get k8s client error: %v, some predicates will not execute", err)
|
|
}
|
|
return k8spredicates.PredicatesManager.DoFilter(k8sCli, pod, node, hosts[0])
|
|
}
|
|
|
|
func k8sPrioritizeHandler(c *gin.Context) {
|
|
var extenderArgs schedulerapi.ExtenderArgs
|
|
var hostPriorityList *schedulerapi.HostPriorityList
|
|
|
|
if err := json.NewDecoder(c.Request.Body).Decode(&extenderArgs); err != nil {
|
|
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("Decode json body: %v", err))
|
|
return
|
|
}
|
|
hostPriorityList, err := k8sPrioritizeFunc(extenderArgs)
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("Prioritize error: %v", err))
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, hostPriorityList)
|
|
}
|
|
|
|
// TODO: support priority extender
|
|
func k8sPrioritizeFunc(args schedulerapi.ExtenderArgs) (*schedulerapi.HostPriorityList, error) {
|
|
nodes := args.Nodes.Items
|
|
var priorityList schedulerapi.HostPriorityList = make([]schedulerapi.HostPriority, 0)
|
|
for _, node := range nodes {
|
|
priorityList = append(priorityList, schedulerapi.HostPriority{
|
|
Host: node.Name,
|
|
Score: 0,
|
|
})
|
|
}
|
|
return &priorityList, nil
|
|
}
|