mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 18:00:08 +00:00
using set instead of lists for topologyPairsMaps attributes
This commit is contained in:
parent
0f4c3064fd
commit
b4c7d190cd
@ -51,11 +51,15 @@ type matchingPodAntiAffinityTerm struct {
|
|||||||
node *v1.Node
|
node *v1.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type podSet map[*v1.Pod]struct{}
|
||||||
|
|
||||||
|
type topologyPairSet map[topologyPair]struct{}
|
||||||
|
|
||||||
// topologyPairsMaps keeps topologyPairToAntiAffinityPods and antiAffinityPodToTopologyPairs in sync
|
// topologyPairsMaps keeps topologyPairToAntiAffinityPods and antiAffinityPodToTopologyPairs in sync
|
||||||
// as they are the inverse of each others.
|
// as they are the inverse of each others.
|
||||||
type topologyPairsMaps struct {
|
type topologyPairsMaps struct {
|
||||||
topologyPairToPods map[topologyPair][]*v1.Pod
|
topologyPairToPods map[topologyPair]podSet
|
||||||
podToTopologyPairs map[string][]topologyPair
|
podToTopologyPairs map[string]topologyPairSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: When new fields are added/removed or logic is changed, please make sure that
|
// NOTE: When new fields are added/removed or logic is changed, please make sure that
|
||||||
@ -151,44 +155,40 @@ func (pfactory *PredicateMetadataFactory) GetMetadata(pod *v1.Pod, nodeNameToInf
|
|||||||
return predicateMetadata
|
return predicateMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topologyPairsMaps *topologyPairsMaps) AddTopologyPair(pair topologyPair, pod *v1.Pod) {
|
// returns a pointer to a new topologyPairsMaps
|
||||||
found := false
|
func newTopologyPairsMaps() *topologyPairsMaps {
|
||||||
for _, existingPod := range topologyPairsMaps.topologyPairToPods[pair] {
|
return &topologyPairsMaps{topologyPairToPods: make(map[topologyPair]podSet),
|
||||||
if existingPod == pod {
|
podToTopologyPairs: make(map[string]topologyPairSet)}
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
topologyPairsMaps.topologyPairToPods[pair] = append(topologyPairsMaps.topologyPairToPods[pair], pod)
|
|
||||||
topologyPairsMaps.podToTopologyPairs[schedutil.GetPodFullName(pod)] = append(topologyPairsMaps.podToTopologyPairs[schedutil.GetPodFullName(pod)], pair)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topologyPairsMaps *topologyPairsMaps) RemovePod(podName string) {
|
func (topologyPairsMaps *topologyPairsMaps) addTopologyPair(pair topologyPair, pod *v1.Pod) {
|
||||||
for _, pair := range topologyPairsMaps.podToTopologyPairs[podName] {
|
podFullName := schedutil.GetPodFullName(pod)
|
||||||
for index, pod := range topologyPairsMaps.topologyPairToPods[pair] {
|
if topologyPairsMaps.topologyPairToPods[pair] == nil {
|
||||||
if schedutil.GetPodFullName(pod) == podName {
|
topologyPairsMaps.topologyPairToPods[pair] = make(map[*v1.Pod]struct{})
|
||||||
podsList := topologyPairsMaps.topologyPairToPods[pair]
|
}
|
||||||
podsList[index] = podsList[len(podsList)-1]
|
topologyPairsMaps.topologyPairToPods[pair][pod] = struct{}{}
|
||||||
if len(podsList) <= 1 {
|
if topologyPairsMaps.podToTopologyPairs[podFullName] == nil {
|
||||||
delete(topologyPairsMaps.topologyPairToPods, pair)
|
topologyPairsMaps.podToTopologyPairs[podFullName] = make(map[topologyPair]struct{})
|
||||||
} else {
|
}
|
||||||
topologyPairsMaps.topologyPairToPods[pair] = podsList[:len(podsList)-1]
|
topologyPairsMaps.podToTopologyPairs[podFullName][pair] = struct{}{}
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
func (topologyPairsMaps *topologyPairsMaps) removePod(deletedPod *v1.Pod) {
|
||||||
|
deletedPodFullName := schedutil.GetPodFullName(deletedPod)
|
||||||
|
for pair := range topologyPairsMaps.podToTopologyPairs[deletedPodFullName] {
|
||||||
|
delete(topologyPairsMaps.topologyPairToPods[pair], deletedPod)
|
||||||
|
if len(topologyPairsMaps.topologyPairToPods[pair]) == 0 {
|
||||||
|
delete(topologyPairsMaps.topologyPairToPods, pair)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete(topologyPairsMaps.podToTopologyPairs, podName)
|
delete(topologyPairsMaps.podToTopologyPairs, deletedPodFullName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (topologyPairsMaps *topologyPairsMaps) appendMaps(toAppend *topologyPairsMaps) {
|
func (topologyPairsMaps *topologyPairsMaps) appendMaps(toAppend *topologyPairsMaps) {
|
||||||
for pod, pairs := range toAppend.podToTopologyPairs {
|
for pair := range toAppend.topologyPairToPods {
|
||||||
topologyPairsMaps.podToTopologyPairs[pod] = append(topologyPairsMaps.podToTopologyPairs[pod], pairs...)
|
for pod := range toAppend.topologyPairToPods[pair] {
|
||||||
}
|
topologyPairsMaps.addTopologyPair(pair, pod)
|
||||||
for pair, pods := range toAppend.topologyPairToPods {
|
}
|
||||||
topologyPairsMaps.topologyPairToPods[pair] = append(topologyPairsMaps.topologyPairToPods[pair], pods...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ func (meta *predicateMetadata) RemovePod(deletedPod *v1.Pod) error {
|
|||||||
if deletedPodFullName == schedutil.GetPodFullName(meta.pod) {
|
if deletedPodFullName == schedutil.GetPodFullName(meta.pod) {
|
||||||
return fmt.Errorf("deletedPod and meta.pod must not be the same")
|
return fmt.Errorf("deletedPod and meta.pod must not be the same")
|
||||||
}
|
}
|
||||||
meta.topologyPairsAntiAffinityPodsMap.RemovePod(deletedPodFullName)
|
meta.topologyPairsAntiAffinityPodsMap.removePod(deletedPod)
|
||||||
// Delete pod from the matching affinity or anti-affinity pods if exists.
|
// Delete pod from the matching affinity or anti-affinity pods if exists.
|
||||||
affinity := meta.pod.Spec.Affinity
|
affinity := meta.pod.Spec.Affinity
|
||||||
podNodeName := deletedPod.Spec.NodeName
|
podNodeName := deletedPod.Spec.NodeName
|
||||||
@ -324,8 +324,7 @@ func (meta *predicateMetadata) ShallowCopy() algorithm.PredicateMetadata {
|
|||||||
for k, v := range meta.nodeNameToMatchingAntiAffinityPods {
|
for k, v := range meta.nodeNameToMatchingAntiAffinityPods {
|
||||||
newPredMeta.nodeNameToMatchingAntiAffinityPods[k] = append([]*v1.Pod(nil), v...)
|
newPredMeta.nodeNameToMatchingAntiAffinityPods[k] = append([]*v1.Pod(nil), v...)
|
||||||
}
|
}
|
||||||
newPredMeta.topologyPairsAntiAffinityPodsMap = &topologyPairsMaps{topologyPairToPods: make(map[topologyPair][]*v1.Pod),
|
newPredMeta.topologyPairsAntiAffinityPodsMap = newTopologyPairsMaps()
|
||||||
podToTopologyPairs: make(map[string][]topologyPair)}
|
|
||||||
newPredMeta.topologyPairsAntiAffinityPodsMap.appendMaps(meta.topologyPairsAntiAffinityPodsMap)
|
newPredMeta.topologyPairsAntiAffinityPodsMap.appendMaps(meta.topologyPairsAntiAffinityPodsMap)
|
||||||
newPredMeta.serviceAffinityMatchingPodServices = append([]*v1.Service(nil),
|
newPredMeta.serviceAffinityMatchingPodServices = append([]*v1.Service(nil),
|
||||||
meta.serviceAffinityMatchingPodServices...)
|
meta.serviceAffinityMatchingPodServices...)
|
||||||
|
@ -28,33 +28,6 @@ import (
|
|||||||
schedulertesting "k8s.io/kubernetes/pkg/scheduler/testing"
|
schedulertesting "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sortableTopologyPairs lets us sort topology pairs
|
|
||||||
type sortableTopologyPairs []topologyPair
|
|
||||||
|
|
||||||
// Less establishes some ordering between two topologyPairs for sorting.
|
|
||||||
func (s sortableTopologyPairs) Less(i, j int) bool {
|
|
||||||
t1, t2 := s[i], s[j]
|
|
||||||
return t1.key < t2.key || (t1.key == t2.key && t1.value < t2.value)
|
|
||||||
}
|
|
||||||
func (s sortableTopologyPairs) Len() int { return len(s) }
|
|
||||||
func (s sortableTopologyPairs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
|
|
||||||
var _ = sort.Interface(sortableTopologyPairs{})
|
|
||||||
|
|
||||||
func sortTopologyPairs(pairs map[string][]topologyPair) {
|
|
||||||
for k, v := range pairs {
|
|
||||||
sortableTerms := sortableTopologyPairs(v)
|
|
||||||
sort.Sort(sortableTerms)
|
|
||||||
pairs[k] = sortableTerms
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func sortTopologyPairPods(np map[topologyPair][]*v1.Pod) {
|
|
||||||
for _, pl := range np {
|
|
||||||
sortablePods := sortablePods(pl)
|
|
||||||
sort.Sort(sortablePods)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sortablePods lets us to sort pods.
|
// sortablePods lets us to sort pods.
|
||||||
type sortablePods []*v1.Pod
|
type sortablePods []*v1.Pod
|
||||||
|
|
||||||
@ -114,17 +87,13 @@ func predicateMetadataEquivalent(meta1, meta2 *predicateMetadata) error {
|
|||||||
if !reflect.DeepEqual(meta1.nodeNameToMatchingAntiAffinityPods, meta2.nodeNameToMatchingAntiAffinityPods) {
|
if !reflect.DeepEqual(meta1.nodeNameToMatchingAntiAffinityPods, meta2.nodeNameToMatchingAntiAffinityPods) {
|
||||||
return fmt.Errorf("nodeNameToMatchingAntiAffinityPods are not euqal")
|
return fmt.Errorf("nodeNameToMatchingAntiAffinityPods are not euqal")
|
||||||
}
|
}
|
||||||
sortTopologyPairs(meta1.topologyPairsAntiAffinityPodsMap.podToTopologyPairs)
|
|
||||||
sortTopologyPairs(meta2.topologyPairsAntiAffinityPodsMap.podToTopologyPairs)
|
|
||||||
if !reflect.DeepEqual(meta1.topologyPairsAntiAffinityPodsMap.podToTopologyPairs,
|
if !reflect.DeepEqual(meta1.topologyPairsAntiAffinityPodsMap.podToTopologyPairs,
|
||||||
meta2.topologyPairsAntiAffinityPodsMap.podToTopologyPairs) {
|
meta2.topologyPairsAntiAffinityPodsMap.podToTopologyPairs) {
|
||||||
return fmt.Errorf("topologyPairsAntiAffinityPodsMap.antiAffinityPodToTopologyPairs are not equal")
|
return fmt.Errorf("topologyPairsAntiAffinityPodsMap.podToTopologyPairs are not equal")
|
||||||
}
|
}
|
||||||
sortTopologyPairPods(meta1.topologyPairsAntiAffinityPodsMap.topologyPairToPods)
|
|
||||||
sortTopologyPairPods(meta2.topologyPairsAntiAffinityPodsMap.topologyPairToPods)
|
|
||||||
if !reflect.DeepEqual(meta1.topologyPairsAntiAffinityPodsMap.topologyPairToPods,
|
if !reflect.DeepEqual(meta1.topologyPairsAntiAffinityPodsMap.topologyPairToPods,
|
||||||
meta2.topologyPairsAntiAffinityPodsMap.topologyPairToPods) {
|
meta2.topologyPairsAntiAffinityPodsMap.topologyPairToPods) {
|
||||||
return fmt.Errorf("topologyPairsAntiAffinityPodsMap.topologyPairToAntiAffinityPods are not equal")
|
return fmt.Errorf("topologyPairsAntiAffinityPodsMap.topologyPairToPods are not equal")
|
||||||
}
|
}
|
||||||
if meta1.serviceAffinityInUse {
|
if meta1.serviceAffinityInUse {
|
||||||
sortablePods1 := sortablePods(meta1.serviceAffinityMatchingPodList)
|
sortablePods1 := sortablePods(meta1.serviceAffinityMatchingPodList)
|
||||||
@ -464,24 +433,24 @@ func TestPredicateMetadata_ShallowCopy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
topologyPairsAntiAffinityPodsMap: &topologyPairsMaps{
|
topologyPairsAntiAffinityPodsMap: &topologyPairsMaps{
|
||||||
topologyPairToPods: map[topologyPair][]*v1.Pod{
|
topologyPairToPods: map[topologyPair]podSet{
|
||||||
{key: "name", value: "machine1"}: {
|
{key: "name", value: "machine1"}: {
|
||||||
&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p2", Labels: selector1},
|
&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p2", Labels: selector1},
|
||||||
Spec: v1.PodSpec{NodeName: "nodeC"},
|
Spec: v1.PodSpec{NodeName: "nodeC"},
|
||||||
},
|
}: struct{}{},
|
||||||
},
|
},
|
||||||
{key: "name", value: "machine2"}: {
|
{key: "name", value: "machine2"}: {
|
||||||
&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: selector1},
|
&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: selector1},
|
||||||
Spec: v1.PodSpec{NodeName: "nodeA"},
|
Spec: v1.PodSpec{NodeName: "nodeA"},
|
||||||
},
|
}: struct{}{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
podToTopologyPairs: map[string][]topologyPair{
|
podToTopologyPairs: map[string]topologyPairSet{
|
||||||
"p2": {
|
"p2_": {
|
||||||
topologyPair{key: "name", value: "machine1"},
|
topologyPair{key: "name", value: "machine1"}: struct{}{},
|
||||||
},
|
},
|
||||||
"p1": {
|
"p1_": {
|
||||||
topologyPair{key: "name", value: "machine2"},
|
topologyPair{key: "name", value: "machine2"}: struct{}{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1255,8 +1255,7 @@ func getMatchingTopologyPairs(pod *v1.Pod, nodeInfoMap map[string]*schedulercach
|
|||||||
var lock sync.Mutex
|
var lock sync.Mutex
|
||||||
var firstError error
|
var firstError error
|
||||||
|
|
||||||
topologyMaps := &topologyPairsMaps{topologyPairToPods: make(map[topologyPair][]*v1.Pod),
|
topologyMaps := newTopologyPairsMaps()
|
||||||
podToTopologyPairs: make(map[string][]topologyPair)}
|
|
||||||
|
|
||||||
appendTopologyPairsMaps := func(toAppend *topologyPairsMaps) {
|
appendTopologyPairsMaps := func(toAppend *topologyPairsMaps) {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
@ -1278,8 +1277,7 @@ func getMatchingTopologyPairs(pod *v1.Pod, nodeInfoMap map[string]*schedulercach
|
|||||||
catchError(fmt.Errorf("node not found"))
|
catchError(fmt.Errorf("node not found"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nodeTopologyMaps := &topologyPairsMaps{topologyPairToPods: make(map[topologyPair][]*v1.Pod),
|
nodeTopologyMaps := newTopologyPairsMaps()
|
||||||
podToTopologyPairs: make(map[string][]topologyPair)}
|
|
||||||
for _, existingPod := range nodeInfo.PodsWithAffinity() {
|
for _, existingPod := range nodeInfo.PodsWithAffinity() {
|
||||||
affinity := existingPod.Spec.Affinity
|
affinity := existingPod.Spec.Affinity
|
||||||
if affinity == nil {
|
if affinity == nil {
|
||||||
@ -1295,7 +1293,7 @@ func getMatchingTopologyPairs(pod *v1.Pod, nodeInfoMap map[string]*schedulercach
|
|||||||
if priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) {
|
if priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) {
|
||||||
if topologyValue, ok := node.Labels[term.TopologyKey]; ok {
|
if topologyValue, ok := node.Labels[term.TopologyKey]; ok {
|
||||||
pair := topologyPair{key: term.TopologyKey, value: topologyValue}
|
pair := topologyPair{key: term.TopologyKey, value: topologyValue}
|
||||||
nodeTopologyMaps.AddTopologyPair(pair, existingPod)
|
nodeTopologyMaps.addTopologyPair(pair, existingPod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1309,8 +1307,7 @@ func getMatchingTopologyPairs(pod *v1.Pod, nodeInfoMap map[string]*schedulercach
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getMatchingTopologyPairsOfExistingPod(newPod *v1.Pod, existingPod *v1.Pod, node *v1.Node) (*topologyPairsMaps, error) {
|
func getMatchingTopologyPairsOfExistingPod(newPod *v1.Pod, existingPod *v1.Pod, node *v1.Node) (*topologyPairsMaps, error) {
|
||||||
topologyMaps := &topologyPairsMaps{topologyPairToPods: make(map[topologyPair][]*v1.Pod),
|
topologyMaps := newTopologyPairsMaps()
|
||||||
podToTopologyPairs: make(map[string][]topologyPair)}
|
|
||||||
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) {
|
||||||
@ -1322,7 +1319,7 @@ func getMatchingTopologyPairsOfExistingPod(newPod *v1.Pod, existingPod *v1.Pod,
|
|||||||
if priorityutil.PodMatchesTermsNamespaceAndSelector(newPod, namespaces, selector) {
|
if priorityutil.PodMatchesTermsNamespaceAndSelector(newPod, namespaces, selector) {
|
||||||
if topologyValue, ok := node.Labels[term.TopologyKey]; ok {
|
if topologyValue, ok := node.Labels[term.TopologyKey]; ok {
|
||||||
pair := topologyPair{key: term.TopologyKey, value: topologyValue}
|
pair := topologyPair{key: term.TopologyKey, value: topologyValue}
|
||||||
topologyMaps.AddTopologyPair(pair, existingPod)
|
topologyMaps.addTopologyPair(pair, existingPod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1330,8 +1327,7 @@ func getMatchingTopologyPairsOfExistingPod(newPod *v1.Pod, existingPod *v1.Pod,
|
|||||||
return topologyMaps, nil
|
return topologyMaps, nil
|
||||||
}
|
}
|
||||||
func (c *PodAffinityChecker) getMatchingAntiAffinityTopologyPairs(pod *v1.Pod, allPods []*v1.Pod) (*topologyPairsMaps, error) {
|
func (c *PodAffinityChecker) getMatchingAntiAffinityTopologyPairs(pod *v1.Pod, allPods []*v1.Pod) (*topologyPairsMaps, error) {
|
||||||
topologyMaps := &topologyPairsMaps{topologyPairToPods: make(map[topologyPair][]*v1.Pod),
|
topologyMaps := newTopologyPairsMaps()
|
||||||
podToTopologyPairs: make(map[string][]topologyPair)}
|
|
||||||
|
|
||||||
for _, existingPod := range allPods {
|
for _, existingPod := range allPods {
|
||||||
affinity := existingPod.Spec.Affinity
|
affinity := existingPod.Spec.Affinity
|
||||||
@ -1383,7 +1379,7 @@ func (c *PodAffinityChecker) satisfiesExistingPodsAntiAffinity(pod *v1.Pod, meta
|
|||||||
// Iterate over topology pairs to get any of the pods being affected by
|
// Iterate over topology pairs to get any of the pods being affected by
|
||||||
// the scheduled pod anti-affinity rules
|
// the scheduled pod anti-affinity rules
|
||||||
for topologyKey, topologyValue := range node.Labels {
|
for topologyKey, topologyValue := range node.Labels {
|
||||||
if _, ok := topologyMaps.topologyPairToPods[topologyPair{key: topologyKey, value: topologyValue}]; ok {
|
if topologyMaps.topologyPairToPods[topologyPair{key: topologyKey, value: topologyValue}] != nil {
|
||||||
glog.V(10).Infof("Cannot schedule pod %+v onto node %v", podName(pod), node.Name)
|
glog.V(10).Infof("Cannot schedule pod %+v onto node %v", podName(pod), node.Name)
|
||||||
return ErrExistingPodsAntiAffinityRulesNotMatch, nil
|
return ErrExistingPodsAntiAffinityRulesNotMatch, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user