Weisen Pan a877aed45f AI-based CFN Traffic Control and Computer Force Scheduling
Change-Id: I16cd7730c1e0732253ac52f51010f6b813295aa7
2023-11-03 00:09:19 -07:00

84 lines
2.2 KiB
Go

package scheduling
// Author: Weisen Pan
// Date: 2023-10-24
import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/knets_pkg/api/resource"
resourcehelper "k8s.io/kubectl/knets_pkg/util/resource"
)
// GreedQueue is used to sort pods using the Greed algorithm
type GreedQueue struct {
pods []*v1.Pod
totalResource v1.ResourceList
}
// NewGreedQueue creates a new GreedQueue instance
func NewGreedQueue(nodes []v1.Node, pods []*v1.Pod) *GreedQueue {
totalResource := make(v1.ResourceList)
for _, node := range nodes {
cpu := totalResource[v1.ResourceCPU]
memory := totalResource[v1.ResourceMemory]
cpu.Add(*node.Status.Allocatable.Cpu())
memory.Add(*node.Status.Allocatable.Memory())
totalResource[v1.ResourceCPU] = cpu
totalResource[v1.ResourceMemory] = memory
}
return &GreedQueue{
totalResource: totalResource,
pods: pods,
}
}
// Len returns the number of pods in the queue
func (greed *GreedQueue) Len() int { return len(greed.pods) }
// Swap swaps two pods in the queue
func (greed *GreedQueue) Swap(i, j int) { greed.pods[i], greed.pods[j] = greed.pods[j], greed.pods[i] }
// Less compares two pods based on priority for scheduling
func (greed *GreedQueue) Less(i, j int) bool {
// DRF algorithm: Prioritize pods with assigned nodes
if len(greed.pods[i].Spec.NodeName) != 0 {
return true
} else if len(greed.pods[j].Spec.NodeName) != 0 {
return false
} else {
return greed.calculatePodShare(greed.pods[i]) > greed.calculatePodShare(greed.pods[j])
}
}
// calculatePodShare calculates the resource share of a pod
func (greed *GreedQueue) calculatePodShare(pod *v1.Pod) float64 {
podReq, _ := resourcehelper.PodRequestsAndLimits(pod)
if len(podReq) == 0 {
return 0
}
var res float64
for resourceName := range greed.totalResource {
allocatedRes := podReq[resourceName]
totalRes := greed.totalResource[resourceName]
share := Share(allocatedRes.AsApproximateFloat64(), totalRes.AsApproximateFloat64())
if share > res {
res = share
}
}
return res
}
// Share calculates the resource share
func Share(alloc, total float64) float64 {
if total == 0 {
if alloc == 0 {
return 0
}
return 1
}
return alloc / total
}