mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Merge pull request #86764 from haosdent/migrate-servie-affinity
Break serviceaffinity Filter plugins dependency on predicates package
This commit is contained in:
commit
b34c96b62c
@ -17,7 +17,6 @@ go_library(
|
|||||||
"//pkg/scheduler/nodeinfo:go_default_library",
|
"//pkg/scheduler/nodeinfo:go_default_library",
|
||||||
"//pkg/scheduler/util:go_default_library",
|
"//pkg/scheduler/util:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
@ -39,7 +38,6 @@ go_test(
|
|||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
||||||
|
@ -18,54 +18,9 @@ package predicates
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FindLabelsInSet gets as many key/value pairs as possible out of a label set.
|
|
||||||
func FindLabelsInSet(labelsToKeep []string, selector labels.Set) map[string]string {
|
|
||||||
aL := make(map[string]string)
|
|
||||||
for _, l := range labelsToKeep {
|
|
||||||
if selector.Has(l) {
|
|
||||||
aL[l] = selector.Get(l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aL
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddUnsetLabelsToMap backfills missing values with values we find in a map.
|
|
||||||
func AddUnsetLabelsToMap(aL map[string]string, labelsToAdd []string, labelSet labels.Set) {
|
|
||||||
for _, l := range labelsToAdd {
|
|
||||||
// if the label is already there, dont overwrite it.
|
|
||||||
if _, exists := aL[l]; exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// otherwise, backfill this label.
|
|
||||||
if labelSet.Has(l) {
|
|
||||||
aL[l] = labelSet.Get(l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterPodsByNamespace filters pods outside a namespace from the given list.
|
|
||||||
func FilterPodsByNamespace(pods []*v1.Pod, ns string) []*v1.Pod {
|
|
||||||
filtered := []*v1.Pod{}
|
|
||||||
for _, nsPod := range pods {
|
|
||||||
if nsPod.Namespace == ns {
|
|
||||||
filtered = append(filtered, nsPod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filtered
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSelectorFromLabels is used to define a selector that corresponds to the keys in a map.
|
|
||||||
func CreateSelectorFromLabels(aL map[string]string) labels.Selector {
|
|
||||||
if len(aL) == 0 {
|
|
||||||
return labels.Everything()
|
|
||||||
}
|
|
||||||
return labels.Set(aL).AsSelector()
|
|
||||||
}
|
|
||||||
|
|
||||||
// portsConflict check whether existingPorts and wantPorts conflict with each other
|
// portsConflict check whether existingPorts and wantPorts conflict with each other
|
||||||
// return true if we have a conflict
|
// return true if we have a conflict
|
||||||
func portsConflict(existingPorts schedulernodeinfo.HostPortInfo, wantPorts []*v1.ContainerPort) bool {
|
func portsConflict(existingPorts schedulernodeinfo.HostPortInfo, wantPorts []*v1.ContainerPort) bool {
|
||||||
|
@ -15,56 +15,3 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
package predicates
|
package predicates
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ExampleUtils is a https://blog.golang.org/examples styled unit test.
|
|
||||||
func ExampleFindLabelsInSet() {
|
|
||||||
labelSubset := labels.Set{}
|
|
||||||
labelSubset["label1"] = "value1"
|
|
||||||
labelSubset["label2"] = "value2"
|
|
||||||
// Lets make believe that these pods are on the cluster.
|
|
||||||
// Utility functions will inspect their labels, filter them, and so on.
|
|
||||||
nsPods := []*v1.Pod{
|
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pod1",
|
|
||||||
Namespace: "ns1",
|
|
||||||
Labels: map[string]string{
|
|
||||||
"label1": "wontSeeThis",
|
|
||||||
"label2": "wontSeeThis",
|
|
||||||
"label3": "will_see_this",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, // first pod which will be used via the utilities
|
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pod2",
|
|
||||||
Namespace: "ns1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pod3ThatWeWontSee",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
fmt.Println(FindLabelsInSet([]string{"label1", "label2", "label3"}, nsPods[0].ObjectMeta.Labels)["label3"])
|
|
||||||
AddUnsetLabelsToMap(labelSubset, []string{"label1", "label2", "label3"}, nsPods[0].ObjectMeta.Labels)
|
|
||||||
fmt.Println(labelSubset)
|
|
||||||
|
|
||||||
for _, pod := range FilterPodsByNamespace(nsPods, "ns1") {
|
|
||||||
fmt.Print(pod.Name, ",")
|
|
||||||
}
|
|
||||||
// Output:
|
|
||||||
// will_see_this
|
|
||||||
// label1=value1,label2=value2,label3=will_see_this
|
|
||||||
// pod1,pod2,
|
|
||||||
}
|
|
||||||
|
@ -113,14 +113,14 @@ func (pl *ServiceAffinity) createPreFilterState(pod *v1.Pod) (*preFilterState, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("listing pod services: %v", err.Error())
|
return nil, fmt.Errorf("listing pod services: %v", err.Error())
|
||||||
}
|
}
|
||||||
selector := predicates.CreateSelectorFromLabels(pod.Labels)
|
selector := createSelectorFromLabels(pod.Labels)
|
||||||
allMatches, err := pl.sharedLister.Pods().List(selector)
|
allMatches, err := pl.sharedLister.Pods().List(selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("listing pods: %v", err.Error())
|
return nil, fmt.Errorf("listing pods: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// consider only the pods that belong to the same namespace
|
// consider only the pods that belong to the same namespace
|
||||||
matchingPodList := predicates.FilterPodsByNamespace(allMatches, pod.Namespace)
|
matchingPodList := filterPodsByNamespace(allMatches, pod.Namespace)
|
||||||
|
|
||||||
return &preFilterState{
|
return &preFilterState{
|
||||||
matchingPodList: matchingPodList,
|
matchingPodList: matchingPodList,
|
||||||
@ -157,7 +157,7 @@ func (pl *ServiceAffinity) AddPod(ctx context.Context, cycleState *framework.Cyc
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
selector := predicates.CreateSelectorFromLabels(podToSchedule.Labels)
|
selector := createSelectorFromLabels(podToSchedule.Labels)
|
||||||
if selector.Matches(labels.Set(podToAdd.Labels)) {
|
if selector.Matches(labels.Set(podToAdd.Labels)) {
|
||||||
s.matchingPodList = append(s.matchingPodList, podToAdd)
|
s.matchingPodList = append(s.matchingPodList, podToAdd)
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ func (pl *ServiceAffinity) Filter(ctx context.Context, cycleState *framework.Cyc
|
|||||||
pods, services := s.matchingPodList, s.matchingPodServices
|
pods, services := s.matchingPodList, s.matchingPodServices
|
||||||
filteredPods := nodeInfo.FilterOutPods(pods)
|
filteredPods := nodeInfo.FilterOutPods(pods)
|
||||||
// check if the pod being scheduled has the affinity labels specified in its NodeSelector
|
// check if the pod being scheduled has the affinity labels specified in its NodeSelector
|
||||||
affinityLabels := predicates.FindLabelsInSet(pl.args.AffinityLabels, labels.Set(pod.Spec.NodeSelector))
|
affinityLabels := findLabelsInSet(pl.args.AffinityLabels, labels.Set(pod.Spec.NodeSelector))
|
||||||
// Step 1: If we don't have all constraints, introspect nodes to find the missing constraints.
|
// Step 1: If we don't have all constraints, introspect nodes to find the missing constraints.
|
||||||
if len(pl.args.AffinityLabels) > len(affinityLabels) {
|
if len(pl.args.AffinityLabels) > len(affinityLabels) {
|
||||||
if len(services) > 0 {
|
if len(services) > 0 {
|
||||||
@ -267,12 +267,12 @@ func (pl *ServiceAffinity) Filter(ctx context.Context, cycleState *framework.Cyc
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return framework.NewStatus(framework.Error, "node not found")
|
return framework.NewStatus(framework.Error, "node not found")
|
||||||
}
|
}
|
||||||
predicates.AddUnsetLabelsToMap(affinityLabels, pl.args.AffinityLabels, labels.Set(nodeWithAffinityLabels.Node().Labels))
|
addUnsetLabelsToMap(affinityLabels, pl.args.AffinityLabels, labels.Set(nodeWithAffinityLabels.Node().Labels))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Step 2: Finally complete the affinity predicate based on whatever set of predicates we were able to find.
|
// Step 2: Finally complete the affinity predicate based on whatever set of predicates we were able to find.
|
||||||
if predicates.CreateSelectorFromLabels(affinityLabels).Matches(labels.Set(node.Labels)) {
|
if createSelectorFromLabels(affinityLabels).Matches(labels.Set(node.Labels)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,3 +390,47 @@ func (pl *ServiceAffinity) updateNodeScoresForLabel(sharedLister schedulerlister
|
|||||||
func (pl *ServiceAffinity) ScoreExtensions() framework.ScoreExtensions {
|
func (pl *ServiceAffinity) ScoreExtensions() framework.ScoreExtensions {
|
||||||
return pl
|
return pl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addUnsetLabelsToMap backfills missing values with values we find in a map.
|
||||||
|
func addUnsetLabelsToMap(aL map[string]string, labelsToAdd []string, labelSet labels.Set) {
|
||||||
|
for _, l := range labelsToAdd {
|
||||||
|
// if the label is already there, dont overwrite it.
|
||||||
|
if _, exists := aL[l]; exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// otherwise, backfill this label.
|
||||||
|
if labelSet.Has(l) {
|
||||||
|
aL[l] = labelSet.Get(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// createSelectorFromLabels is used to define a selector that corresponds to the keys in a map.
|
||||||
|
func createSelectorFromLabels(aL map[string]string) labels.Selector {
|
||||||
|
if len(aL) == 0 {
|
||||||
|
return labels.Everything()
|
||||||
|
}
|
||||||
|
return labels.Set(aL).AsSelector()
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterPodsByNamespace filters pods outside a namespace from the given list.
|
||||||
|
func filterPodsByNamespace(pods []*v1.Pod, ns string) []*v1.Pod {
|
||||||
|
filtered := []*v1.Pod{}
|
||||||
|
for _, nsPod := range pods {
|
||||||
|
if nsPod.Namespace == ns {
|
||||||
|
filtered = append(filtered, nsPod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
// findLabelsInSet gets as many key/value pairs as possible out of a label set.
|
||||||
|
func findLabelsInSet(labelsToKeep []string, selector labels.Set) map[string]string {
|
||||||
|
aL := make(map[string]string)
|
||||||
|
for _, l := range labelsToKeep {
|
||||||
|
if selector.Has(l) {
|
||||||
|
aL[l] = selector.Get(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aL
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user