84 lines
2.2 KiB
Go
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
|
|
}
|