mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-09 16:07:36 +08:00
refactor(scheduler): remove unused k8s predicates code
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
// 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 k8s // import "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates/k8s"
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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 k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates/guest"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
|
||||
)
|
||||
|
||||
type HostStatusPredicate struct{}
|
||||
|
||||
func (p *HostStatusPredicate) Clone() IPredicate {
|
||||
return &HostStatusPredicate{}
|
||||
}
|
||||
|
||||
func (p *HostStatusPredicate) Name() string {
|
||||
return "host_status"
|
||||
}
|
||||
|
||||
func (p *HostStatusPredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *HostStatusPredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) {
|
||||
if host.Status != guest.ExpectedStatus {
|
||||
return false, fmt.Errorf("Host status is %s", host.Status)
|
||||
}
|
||||
|
||||
if !host.GetEnabled() {
|
||||
return false, fmt.Errorf("Host is disabled")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
// 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 k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
|
||||
)
|
||||
|
||||
var PredicatesManager *SPredicatesManager
|
||||
|
||||
func init() {
|
||||
PredicatesManager = newPredicatesManager()
|
||||
|
||||
PredicatesManager.Register(
|
||||
&HostStatusPredicate{},
|
||||
&NetworkPredicate{},
|
||||
&LocalVolumePredicate{},
|
||||
)
|
||||
}
|
||||
|
||||
type IPredicate interface {
|
||||
Name() string
|
||||
Clone() IPredicate
|
||||
PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool
|
||||
Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error)
|
||||
}
|
||||
|
||||
type SPredicatesManager struct {
|
||||
predicates []IPredicate
|
||||
}
|
||||
|
||||
func newPredicatesManager() *SPredicatesManager {
|
||||
man := &SPredicatesManager{
|
||||
predicates: make([]IPredicate, 0),
|
||||
}
|
||||
return man
|
||||
}
|
||||
|
||||
func (man *SPredicatesManager) Register(pres ...IPredicate) *SPredicatesManager {
|
||||
for _, pre := range pres {
|
||||
if !man.Has(pre) {
|
||||
man.predicates = append(man.predicates, pre)
|
||||
}
|
||||
}
|
||||
return man
|
||||
}
|
||||
|
||||
func (man *SPredicatesManager) Has(newPre IPredicate) bool {
|
||||
if len(man.predicates) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, pre := range man.predicates {
|
||||
if pre.Name() == newPre.Name() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (man *SPredicatesManager) DoFilter(
|
||||
k8sCli *kubernetes.Clientset,
|
||||
pod *v1.Pod,
|
||||
node *v1.Node,
|
||||
host *candidate.HostDesc,
|
||||
) (bool, error) {
|
||||
for _, pre := range man.predicates {
|
||||
tmpPre := pre.Clone()
|
||||
if !tmpPre.PreExecute(k8sCli, pod, node, host) {
|
||||
continue
|
||||
}
|
||||
fit, err := tmpPre.Execute(k8sCli, pod, node, host)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !fit {
|
||||
return false, fmt.Errorf("Filtered by %s", tmpPre.Name())
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
// 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 k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"yunion.io/x/pkg/util/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/api"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
|
||||
)
|
||||
|
||||
const (
|
||||
// k8s annotations for create pod
|
||||
YUNION_CNI_NETWORK_ANNOTATION = "cni.yunion.io/network"
|
||||
YUNION_CNI_IPADDR_ANNOTATION = "cni.yunion.io/ip"
|
||||
)
|
||||
|
||||
type NetworkPredicate struct {
|
||||
network string
|
||||
ipAddr string
|
||||
}
|
||||
|
||||
func (p *NetworkPredicate) Clone() IPredicate {
|
||||
return &NetworkPredicate{}
|
||||
}
|
||||
|
||||
func (p *NetworkPredicate) Name() string {
|
||||
return "network"
|
||||
}
|
||||
|
||||
func (p *NetworkPredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool {
|
||||
net, netCont := pod.Annotations[YUNION_CNI_NETWORK_ANNOTATION]
|
||||
ipAddr, ipCont := pod.Annotations[YUNION_CNI_IPADDR_ANNOTATION]
|
||||
p.network = net
|
||||
p.ipAddr = ipAddr
|
||||
return netCont || ipCont
|
||||
}
|
||||
|
||||
func (p *NetworkPredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) {
|
||||
hostNets := host.Networks
|
||||
if p.network != "" {
|
||||
err := p.checkByNetworks(hostNets)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if p.ipAddr != "" {
|
||||
err := p.checkNetworksIP(p.ipAddr, hostNets)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (p NetworkPredicate) checkByNetworks(nets []*api.CandidateNetwork) error {
|
||||
if len(nets) == 0 {
|
||||
return fmt.Errorf("Network is empty")
|
||||
}
|
||||
errs := make([]error, 0)
|
||||
for _, net := range nets {
|
||||
err := p.checkByNetwork(net.SNetwork)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func (p NetworkPredicate) checkByNetwork(net *models.SNetwork) error {
|
||||
if net.GetPorts() <= 0 {
|
||||
return fmt.Errorf("Network %s no free IPs", net.Name)
|
||||
}
|
||||
if !(p.network == net.Name || p.network == net.Id) {
|
||||
return fmt.Errorf("Network %s:%s or id not match %s", net.Name, net.Id, p.network)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p NetworkPredicate) checkNetworksIP(ip string, nets []*api.CandidateNetwork) error {
|
||||
if len(nets) == 0 {
|
||||
return fmt.Errorf("Network is empty")
|
||||
}
|
||||
errs := make([]error, 0)
|
||||
for _, net := range nets {
|
||||
err := p.checkNetworkIP(ip, net.SNetwork)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func (p NetworkPredicate) checkNetworkIP(ip string, net *models.SNetwork) error {
|
||||
ipAddr, err := netutils.NewIPV4Addr(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok := net.GetIPRange().Contains(ipAddr); !ok {
|
||||
return fmt.Errorf("Network %s not contains ip %s", net.Name, ip)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
// 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 k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
|
||||
)
|
||||
|
||||
const (
|
||||
YUNION_CSI_STORAGECLASS = "csi-yunion"
|
||||
)
|
||||
|
||||
type LocalVolumePredicate struct {
|
||||
pvcs []*v1.PersistentVolumeClaim
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) Clone() IPredicate {
|
||||
return &LocalVolumePredicate{}
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) Name() string {
|
||||
return "local-volume"
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) PreExecute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) bool {
|
||||
if cli == nil {
|
||||
log.Errorf("k8s client is nil, not execute %s filter", p.Name())
|
||||
return false
|
||||
}
|
||||
pvcs := make([]*v1.PersistentVolumeClaim, 0)
|
||||
if pod.Spec.Volumes != nil && len(pod.Spec.Volumes) > 0 {
|
||||
for _, v := range pod.Spec.Volumes {
|
||||
if v.PersistentVolumeClaim == nil {
|
||||
continue
|
||||
}
|
||||
pvcName := v.PersistentVolumeClaim.ClaimName
|
||||
pvc, err := cli.CoreV1().PersistentVolumeClaims(pod.Namespace).Get(pvcName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
log.Warningf("Not found pvc %s for pod %s/%s", pvcName, pod.Namespace, pod.Name)
|
||||
return false
|
||||
}
|
||||
// pvc's StorageClassName must "csi-yunion"
|
||||
if pvc.Spec.StorageClassName != nil && *(pvc.Spec.StorageClassName) != YUNION_CSI_STORAGECLASS {
|
||||
continue
|
||||
}
|
||||
pvcs = append(pvcs, pvc)
|
||||
}
|
||||
}
|
||||
p.pvcs = pvcs
|
||||
return len(pvcs) != 0
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) getPvcRequestSize(pvc *v1.PersistentVolumeClaim) int64 {
|
||||
req := pvc.Spec.Resources.Requests[v1.ResourceStorage]
|
||||
return req.Value()
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) Execute(cli *kubernetes.Clientset, pod *v1.Pod, node *v1.Node, host *candidate.HostDesc) (bool, error) {
|
||||
var reqSize int64
|
||||
for _, pvc := range p.pvcs {
|
||||
pvName := pvc.Spec.VolumeName
|
||||
if pvName != "" {
|
||||
pv, _ := cli.CoreV1().PersistentVolumes().Get(pvName, metav1.GetOptions{})
|
||||
if pv != nil {
|
||||
// PersistentVolume already exists
|
||||
log.V(10).Debugf("PV %s already exists", pv)
|
||||
continue
|
||||
}
|
||||
}
|
||||
reqSize += p.getPvcRequestSize(pvc)
|
||||
}
|
||||
reqSizeMB := reqSize / 1024 / 1024
|
||||
return p.canHostStorageCreateVol(host, reqSizeMB)
|
||||
}
|
||||
|
||||
func (p *LocalVolumePredicate) canHostStorageCreateVol(host *candidate.HostDesc, reqSize int64) (bool, error) {
|
||||
freeSize := host.GetFreeStorageSizeOfType("local", false)
|
||||
log.Debugf("[host %s] PVC request %dMB, free %dMB", host.Name, reqSize, freeSize)
|
||||
if freeSize > reqSize {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("Out of local storage for volume: %d/%d (request/free)MB", reqSize, freeSize)
|
||||
}
|
||||
Reference in New Issue
Block a user