Unverified Commit 6b97376a authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #55109 from bsalamat/starvation2

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add a new scheduling queue based on priority queue. **What this PR does / why we need it**: This PR is a part of solution to fix potential starvation of pods in pod preemption. It adds a different scheduling queue to the scheduler that allows highest priority pods to be scheduled before other pods. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: I tried enabling this queue and made sure that our existing tests pass with this queue enabled. **Release note**: ```release-note Add a new scheduling queue that helps schedule the highest priority pending pod first. ``` /sig scheduling ref/ #54501 ref/ #47604
parents ff0d72a3 79ac37d8
...@@ -38,7 +38,6 @@ go_library( ...@@ -38,7 +38,6 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/plugin/pkg/scheduler", importpath = "k8s.io/kubernetes/plugin/pkg/scheduler",
deps = [ deps = [
"//pkg/features:go_default_library",
"//plugin/pkg/scheduler/algorithm:go_default_library", "//plugin/pkg/scheduler/algorithm:go_default_library",
"//plugin/pkg/scheduler/api:go_default_library", "//plugin/pkg/scheduler/api:go_default_library",
"//plugin/pkg/scheduler/core:go_default_library", "//plugin/pkg/scheduler/core:go_default_library",
...@@ -50,7 +49,6 @@ go_library( ...@@ -50,7 +49,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/listers/core/v1:go_default_library", "//vendor/k8s.io/client-go/listers/core/v1:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/record:go_default_library",
......
...@@ -1070,7 +1070,7 @@ func (c *PodAffinityChecker) anyPodMatchesPodAffinityTerm(pod *v1.Pod, allPods [ ...@@ -1070,7 +1070,7 @@ func (c *PodAffinityChecker) anyPodMatchesPodAffinityTerm(pod *v1.Pod, allPods [
return false, matchingPodExists, nil return false, matchingPodExists, nil
} }
func getPodAffinityTerms(podAffinity *v1.PodAffinity) (terms []v1.PodAffinityTerm) { func GetPodAffinityTerms(podAffinity *v1.PodAffinity) (terms []v1.PodAffinityTerm) {
if podAffinity != nil { if podAffinity != nil {
if len(podAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 { if len(podAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
terms = podAffinity.RequiredDuringSchedulingIgnoredDuringExecution terms = podAffinity.RequiredDuringSchedulingIgnoredDuringExecution
...@@ -1083,7 +1083,7 @@ func getPodAffinityTerms(podAffinity *v1.PodAffinity) (terms []v1.PodAffinityTer ...@@ -1083,7 +1083,7 @@ func getPodAffinityTerms(podAffinity *v1.PodAffinity) (terms []v1.PodAffinityTer
return terms return terms
} }
func getPodAntiAffinityTerms(podAntiAffinity *v1.PodAntiAffinity) (terms []v1.PodAffinityTerm) { func GetPodAntiAffinityTerms(podAntiAffinity *v1.PodAntiAffinity) (terms []v1.PodAffinityTerm) {
if podAntiAffinity != nil { if podAntiAffinity != nil {
if len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 { if len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
terms = podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution terms = podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution
...@@ -1133,7 +1133,7 @@ func getMatchingAntiAffinityTerms(pod *v1.Pod, nodeInfoMap map[string]*scheduler ...@@ -1133,7 +1133,7 @@ func getMatchingAntiAffinityTerms(pod *v1.Pod, nodeInfoMap map[string]*scheduler
if affinity == nil { if affinity == nil {
continue continue
} }
for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { for _, term := range GetPodAntiAffinityTerms(affinity.PodAntiAffinity) {
namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term) namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term)
selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector)
if err != nil { if err != nil {
...@@ -1160,7 +1160,7 @@ func getMatchingAntiAffinityTermsOfExistingPod(newPod *v1.Pod, existingPod *v1.P ...@@ -1160,7 +1160,7 @@ func getMatchingAntiAffinityTermsOfExistingPod(newPod *v1.Pod, existingPod *v1.P
var result []matchingPodAntiAffinityTerm var result []matchingPodAntiAffinityTerm
affinity := existingPod.Spec.Affinity affinity := existingPod.Spec.Affinity
if affinity != nil && affinity.PodAntiAffinity != nil { if affinity != nil && affinity.PodAntiAffinity != nil {
for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { for _, term := range GetPodAntiAffinityTerms(affinity.PodAntiAffinity) {
namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term) namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term)
selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector)
if err != nil { if err != nil {
...@@ -1257,7 +1257,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node ...@@ -1257,7 +1257,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node
} }
// Check all affinity terms. // Check all affinity terms.
for _, term := range getPodAffinityTerms(affinity.PodAffinity) { for _, term := range GetPodAffinityTerms(affinity.PodAffinity) {
termMatches, matchingPodExists, err := c.anyPodMatchesPodAffinityTerm(pod, filteredPods, node, &term) termMatches, matchingPodExists, err := c.anyPodMatchesPodAffinityTerm(pod, filteredPods, node, &term)
if err != nil { if err != nil {
errMessage := fmt.Sprintf("Cannot schedule pod %+v onto node %v, because of PodAffinityTerm %v, err: %v", podName(pod), node.Name, term, err) errMessage := fmt.Sprintf("Cannot schedule pod %+v onto node %v, because of PodAffinityTerm %v, err: %v", podName(pod), node.Name, term, err)
...@@ -1290,7 +1290,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node ...@@ -1290,7 +1290,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node
} }
// Check all anti-affinity terms. // Check all anti-affinity terms.
for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { for _, term := range GetPodAntiAffinityTerms(affinity.PodAntiAffinity) {
termMatches, _, err := c.anyPodMatchesPodAffinityTerm(pod, filteredPods, node, &term) termMatches, _, err := c.anyPodMatchesPodAffinityTerm(pod, filteredPods, node, &term)
if err != nil || termMatches { if err != nil || termMatches {
glog.V(10).Infof("Cannot schedule pod %+v onto node %v, because of PodAntiAffinityTerm %v, err: %v", glog.V(10).Infof("Cannot schedule pod %+v onto node %v, because of PodAntiAffinityTerm %v, err: %v",
......
...@@ -12,6 +12,7 @@ go_test( ...@@ -12,6 +12,7 @@ go_test(
"equivalence_cache_test.go", "equivalence_cache_test.go",
"extender_test.go", "extender_test.go",
"generic_scheduler_test.go", "generic_scheduler_test.go",
"scheduling_queue_test.go",
], ],
importpath = "k8s.io/kubernetes/plugin/pkg/scheduler/core", importpath = "k8s.io/kubernetes/plugin/pkg/scheduler/core",
library = ":go_default_library", library = ":go_default_library",
...@@ -23,6 +24,7 @@ go_test( ...@@ -23,6 +24,7 @@ go_test(
"//plugin/pkg/scheduler/api:go_default_library", "//plugin/pkg/scheduler/api:go_default_library",
"//plugin/pkg/scheduler/schedulercache:go_default_library", "//plugin/pkg/scheduler/schedulercache:go_default_library",
"//plugin/pkg/scheduler/testing:go_default_library", "//plugin/pkg/scheduler/testing:go_default_library",
"//plugin/pkg/scheduler/util:go_default_library",
"//vendor/k8s.io/api/apps/v1beta1:go_default_library", "//vendor/k8s.io/api/apps/v1beta1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
...@@ -46,12 +48,14 @@ go_library( ...@@ -46,12 +48,14 @@ go_library(
"//pkg/util/hash:go_default_library", "//pkg/util/hash:go_default_library",
"//plugin/pkg/scheduler/algorithm:go_default_library", "//plugin/pkg/scheduler/algorithm:go_default_library",
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library", "//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
"//plugin/pkg/scheduler/algorithm/priorities/util:go_default_library",
"//plugin/pkg/scheduler/api:go_default_library", "//plugin/pkg/scheduler/api:go_default_library",
"//plugin/pkg/scheduler/schedulercache:go_default_library", "//plugin/pkg/scheduler/schedulercache:go_default_library",
"//plugin/pkg/scheduler/util:go_default_library", "//plugin/pkg/scheduler/util:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/golang/groupcache/lru:go_default_library", "//vendor/github.com/golang/groupcache/lru:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
......
...@@ -142,11 +142,10 @@ func NewConfigFactory( ...@@ -142,11 +142,10 @@ func NewConfigFactory(
stopEverything := make(chan struct{}) stopEverything := make(chan struct{})
schedulerCache := schedulercache.New(30*time.Second, stopEverything) schedulerCache := schedulercache.New(30*time.Second, stopEverything)
schedulingQueue := &core.FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)}
c := &configFactory{ c := &configFactory{
client: client, client: client,
podLister: schedulerCache, podLister: schedulerCache,
podQueue: schedulingQueue, podQueue: core.NewSchedulingQueue(),
pVLister: pvInformer.Lister(), pVLister: pvInformer.Lister(),
pVCLister: pvcInformer.Lister(), pVCLister: pvcInformer.Lister(),
serviceLister: serviceInformer.Lister(), serviceLister: serviceInformer.Lister(),
...@@ -195,20 +194,21 @@ func NewConfigFactory( ...@@ -195,20 +194,21 @@ func NewConfigFactory(
}, },
Handler: cache.ResourceEventHandlerFuncs{ Handler: cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { AddFunc: func(obj interface{}) {
if err := c.podQueue.Add(obj); err != nil { if err := c.podQueue.Add(obj.(*v1.Pod)); err != nil {
runtime.HandleError(fmt.Errorf("unable to queue %T: %v", obj, err)) runtime.HandleError(fmt.Errorf("unable to queue %T: %v", obj, err))
} }
}, },
UpdateFunc: func(oldObj, newObj interface{}) { UpdateFunc: func(oldObj, newObj interface{}) {
if c.skipPodUpdate(newObj.(*v1.Pod)) { pod := newObj.(*v1.Pod)
if c.skipPodUpdate(pod) {
return return
} }
if err := c.podQueue.Update(newObj); err != nil { if err := c.podQueue.Update(pod); err != nil {
runtime.HandleError(fmt.Errorf("unable to update %T: %v", newObj, err)) runtime.HandleError(fmt.Errorf("unable to update %T: %v", newObj, err))
} }
}, },
DeleteFunc: func(obj interface{}) { DeleteFunc: func(obj interface{}) {
if err := c.podQueue.Delete(obj); err != nil { if err := c.podQueue.Delete(obj.(*v1.Pod)); err != nil {
runtime.HandleError(fmt.Errorf("unable to dequeue %T: %v", obj, err)) runtime.HandleError(fmt.Errorf("unable to dequeue %T: %v", obj, err))
} }
}, },
...@@ -377,6 +377,7 @@ func (c *configFactory) onPvcAdd(obj interface{}) { ...@@ -377,6 +377,7 @@ func (c *configFactory) onPvcAdd(obj interface{}) {
} }
c.invalidatePredicatesForPvc(pvc) c.invalidatePredicatesForPvc(pvc)
} }
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) onPvcDelete(obj interface{}) { func (c *configFactory) onPvcDelete(obj interface{}) {
...@@ -398,6 +399,7 @@ func (c *configFactory) onPvcDelete(obj interface{}) { ...@@ -398,6 +399,7 @@ func (c *configFactory) onPvcDelete(obj interface{}) {
} }
c.invalidatePredicatesForPvc(pvc) c.invalidatePredicatesForPvc(pvc)
} }
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) invalidatePredicatesForPvc(pvc *v1.PersistentVolumeClaim) { func (c *configFactory) invalidatePredicatesForPvc(pvc *v1.PersistentVolumeClaim) {
...@@ -410,6 +412,7 @@ func (c *configFactory) onServiceAdd(obj interface{}) { ...@@ -410,6 +412,7 @@ func (c *configFactory) onServiceAdd(obj interface{}) {
if c.enableEquivalenceClassCache { if c.enableEquivalenceClassCache {
c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet) c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet)
} }
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) onServiceUpdate(oldObj interface{}, newObj interface{}) { func (c *configFactory) onServiceUpdate(oldObj interface{}, newObj interface{}) {
...@@ -421,12 +424,14 @@ func (c *configFactory) onServiceUpdate(oldObj interface{}, newObj interface{}) ...@@ -421,12 +424,14 @@ func (c *configFactory) onServiceUpdate(oldObj interface{}, newObj interface{})
c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet) c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet)
} }
} }
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) onServiceDelete(obj interface{}) { func (c *configFactory) onServiceDelete(obj interface{}) {
if c.enableEquivalenceClassCache { if c.enableEquivalenceClassCache {
c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet) c.equivalencePodCache.InvalidateCachedPredicateItemOfAllNodes(serviceAffinitySet)
} }
c.podQueue.MoveAllToActiveQueue()
} }
// GetNodeStore provides the cache to the nodes, mostly internal use, but may also be called by mock-tests. // GetNodeStore provides the cache to the nodes, mostly internal use, but may also be called by mock-tests.
...@@ -462,6 +467,8 @@ func (c *configFactory) addPodToCache(obj interface{}) { ...@@ -462,6 +467,8 @@ func (c *configFactory) addPodToCache(obj interface{}) {
if err := c.schedulerCache.AddPod(pod); err != nil { if err := c.schedulerCache.AddPod(pod); err != nil {
glog.Errorf("scheduler cache AddPod failed: %v", err) glog.Errorf("scheduler cache AddPod failed: %v", err)
} }
c.podQueue.AssignedPodAdded(pod)
// NOTE: Updating equivalence cache of addPodToCache has been // NOTE: Updating equivalence cache of addPodToCache has been
// handled optimistically in InvalidateCachedPredicateItemForPodAdd. // handled optimistically in InvalidateCachedPredicateItemForPodAdd.
} }
...@@ -483,6 +490,7 @@ func (c *configFactory) updatePodInCache(oldObj, newObj interface{}) { ...@@ -483,6 +490,7 @@ func (c *configFactory) updatePodInCache(oldObj, newObj interface{}) {
} }
c.invalidateCachedPredicatesOnUpdatePod(newPod, oldPod) c.invalidateCachedPredicatesOnUpdatePod(newPod, oldPod)
c.podQueue.AssignedPodUpdated(newPod)
} }
func (c *configFactory) invalidateCachedPredicatesOnUpdatePod(newPod *v1.Pod, oldPod *v1.Pod) { func (c *configFactory) invalidateCachedPredicatesOnUpdatePod(newPod *v1.Pod, oldPod *v1.Pod) {
...@@ -527,6 +535,7 @@ func (c *configFactory) deletePodFromCache(obj interface{}) { ...@@ -527,6 +535,7 @@ func (c *configFactory) deletePodFromCache(obj interface{}) {
} }
c.invalidateCachedPredicatesOnDeletePod(pod) c.invalidateCachedPredicatesOnDeletePod(pod)
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) invalidateCachedPredicatesOnDeletePod(pod *v1.Pod) { func (c *configFactory) invalidateCachedPredicatesOnDeletePod(pod *v1.Pod) {
...@@ -561,6 +570,7 @@ func (c *configFactory) addNodeToCache(obj interface{}) { ...@@ -561,6 +570,7 @@ func (c *configFactory) addNodeToCache(obj interface{}) {
glog.Errorf("scheduler cache AddNode failed: %v", err) glog.Errorf("scheduler cache AddNode failed: %v", err)
} }
c.podQueue.MoveAllToActiveQueue()
// NOTE: add a new node does not affect existing predicates in equivalence cache // NOTE: add a new node does not affect existing predicates in equivalence cache
} }
...@@ -581,6 +591,7 @@ func (c *configFactory) updateNodeInCache(oldObj, newObj interface{}) { ...@@ -581,6 +591,7 @@ func (c *configFactory) updateNodeInCache(oldObj, newObj interface{}) {
} }
c.invalidateCachedPredicatesOnNodeUpdate(newNode, oldNode) c.invalidateCachedPredicatesOnNodeUpdate(newNode, oldNode)
c.podQueue.MoveAllToActiveQueue()
} }
func (c *configFactory) invalidateCachedPredicatesOnNodeUpdate(newNode *v1.Node, oldNode *v1.Node) { func (c *configFactory) invalidateCachedPredicatesOnNodeUpdate(newNode *v1.Node, oldNode *v1.Node) {
...@@ -902,8 +913,7 @@ func (f *configFactory) getPluginArgs() (*PluginFactoryArgs, error) { ...@@ -902,8 +913,7 @@ func (f *configFactory) getPluginArgs() (*PluginFactoryArgs, error) {
} }
func (f *configFactory) getNextPod() *v1.Pod { func (f *configFactory) getNextPod() *v1.Pod {
if obj, err := f.podQueue.Pop(); err == nil { if pod, err := f.podQueue.Pop(); err == nil {
pod := obj.(*v1.Pod)
glog.V(4).Infof("About to try and schedule pod %v", pod.Name) glog.V(4).Infof("About to try and schedule pod %v", pod.Name)
return pod return pod
} else { } else {
......
...@@ -23,11 +23,9 @@ import ( ...@@ -23,11 +23,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
corelisters "k8s.io/client-go/listers/core/v1" corelisters "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api"
"k8s.io/kubernetes/plugin/pkg/scheduler/core" "k8s.io/kubernetes/plugin/pkg/scheduler/core"
...@@ -196,7 +194,7 @@ func (sched *Scheduler) schedule(pod *v1.Pod) (string, error) { ...@@ -196,7 +194,7 @@ func (sched *Scheduler) schedule(pod *v1.Pod) (string, error) {
// If it succeeds, it adds the name of the node where preemption has happened to the pod annotations. // If it succeeds, it adds the name of the node where preemption has happened to the pod annotations.
// It returns the node name and an error if any. // It returns the node name and an error if any.
func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, error) { func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, error) {
if !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) { if !util.PodPriorityEnabled() {
glog.V(3).Infof("Pod priority feature is not enabled. No preemption is performed.") glog.V(3).Infof("Pod priority feature is not enabled. No preemption is performed.")
return "", nil return "", nil
} }
......
...@@ -37,11 +37,13 @@ go_library( ...@@ -37,11 +37,13 @@ go_library(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/install:go_default_library", "//pkg/apis/core/install:go_default_library",
"//pkg/apis/scheduling:go_default_library", "//pkg/apis/scheduling:go_default_library",
"//pkg/features:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
], ],
) )
......
...@@ -21,7 +21,9 @@ import ( ...@@ -21,7 +21,9 @@ import (
"sort" "sort"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
"k8s.io/kubernetes/pkg/features"
) )
const DefaultBindAllHostIP = "0.0.0.0" const DefaultBindAllHostIP = "0.0.0.0"
...@@ -59,6 +61,11 @@ func GetUsedPorts(pods ...*v1.Pod) map[string]bool { ...@@ -59,6 +61,11 @@ func GetUsedPorts(pods ...*v1.Pod) map[string]bool {
return ports return ports
} }
// PodPriorityEnabled indicates whether pod priority feature is enabled.
func PodPriorityEnabled() bool {
return feature.DefaultFeatureGate.Enabled(features.PodPriority)
}
// GetPodFullName returns a name that uniquely identifies a pod. // GetPodFullName returns a name that uniquely identifies a pod.
func GetPodFullName(pod *v1.Pod) string { func GetPodFullName(pod *v1.Pod) string {
// Use underscore as the delimiter because it is not allowed in pod name // Use underscore as the delimiter because it is not allowed in pod name
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment