k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/scheduler/framework/plugins/helper/spread.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package helper 18 19 import ( 20 appsv1 "k8s.io/api/apps/v1" 21 v1 "k8s.io/api/core/v1" 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/apimachinery/pkg/labels" 24 "k8s.io/apimachinery/pkg/runtime/schema" 25 appslisters "k8s.io/client-go/listers/apps/v1" 26 corelisters "k8s.io/client-go/listers/core/v1" 27 ) 28 29 var ( 30 rcKind = v1.SchemeGroupVersion.WithKind("ReplicationController") 31 rsKind = appsv1.SchemeGroupVersion.WithKind("ReplicaSet") 32 ssKind = appsv1.SchemeGroupVersion.WithKind("StatefulSet") 33 ) 34 35 // DefaultSelector returns a selector deduced from the Services, Replication 36 // Controllers, Replica Sets, and Stateful Sets matching the given pod. 37 func DefaultSelector( 38 pod *v1.Pod, 39 sl corelisters.ServiceLister, 40 cl corelisters.ReplicationControllerLister, 41 rsl appslisters.ReplicaSetLister, 42 ssl appslisters.StatefulSetLister, 43 ) labels.Selector { 44 labelSet := make(labels.Set) 45 // Since services, RCs, RSs and SSs match the pod, they won't have conflicting 46 // labels. Merging is safe. 47 48 if services, err := GetPodServices(sl, pod); err == nil { 49 for _, service := range services { 50 labelSet = labels.Merge(labelSet, service.Spec.Selector) 51 } 52 } 53 selector := labelSet.AsSelector() 54 55 owner := metav1.GetControllerOfNoCopy(pod) 56 if owner == nil { 57 return selector 58 } 59 60 gv, err := schema.ParseGroupVersion(owner.APIVersion) 61 if err != nil { 62 return selector 63 } 64 65 gvk := gv.WithKind(owner.Kind) 66 switch gvk { 67 case rcKind: 68 if rc, err := cl.ReplicationControllers(pod.Namespace).Get(owner.Name); err == nil { 69 labelSet = labels.Merge(labelSet, rc.Spec.Selector) 70 selector = labelSet.AsSelector() 71 } 72 case rsKind: 73 if rs, err := rsl.ReplicaSets(pod.Namespace).Get(owner.Name); err == nil { 74 if other, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector); err == nil { 75 if r, ok := other.Requirements(); ok { 76 selector = selector.Add(r...) 77 } 78 } 79 } 80 case ssKind: 81 if ss, err := ssl.StatefulSets(pod.Namespace).Get(owner.Name); err == nil { 82 if other, err := metav1.LabelSelectorAsSelector(ss.Spec.Selector); err == nil { 83 if r, ok := other.Requirements(); ok { 84 selector = selector.Add(r...) 85 } 86 } 87 } 88 default: 89 // Not owned by a supported controller. 90 } 91 92 return selector 93 } 94 95 // GetPodServices gets the services that have the selector that match the labels on the given pod. 96 func GetPodServices(sl corelisters.ServiceLister, pod *v1.Pod) ([]*v1.Service, error) { 97 allServices, err := sl.Services(pod.Namespace).List(labels.Everything()) 98 if err != nil { 99 return nil, err 100 } 101 102 var services []*v1.Service 103 for i := range allServices { 104 service := allServices[i] 105 if service.Spec.Selector == nil { 106 // services with nil selectors match nothing, not everything. 107 continue 108 } 109 selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated() 110 if selector.Matches(labels.Set(pod.Labels)) { 111 services = append(services, service) 112 } 113 } 114 115 return services, nil 116 }