Commit 5ab47145 authored by Jonathan Basseri's avatar Jonathan Basseri

Change equivalence hash function.

This changes the equivalence class hashing function to use as inputs all the Pod fields which are read by FitPredicates. Before we used a combination of OwnerReference and PersistentVolumeClaim info, which was a close approximation. The new method ensures that hashing remains correct regardless of controller behavior. The PVCSet field can be removed from equivalencePod because it is implicitly included in the Volume list. Tests are now broken.
parent 4ae7075e
...@@ -17,11 +17,8 @@ limitations under the License. ...@@ -17,11 +17,8 @@ limitations under the License.
package predicates package predicates
import ( import (
"github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/scheduler/algorithm" "k8s.io/kubernetes/pkg/scheduler/algorithm"
schedutil "k8s.io/kubernetes/pkg/scheduler/util" schedutil "k8s.io/kubernetes/pkg/scheduler/util"
) )
...@@ -83,53 +80,35 @@ func NewEquivalencePodGenerator(pvcInfo PersistentVolumeClaimInfo) algorithm.Get ...@@ -83,53 +80,35 @@ func NewEquivalencePodGenerator(pvcInfo PersistentVolumeClaimInfo) algorithm.Get
return g.getEquivalencePod return g.getEquivalencePod
} }
// GetEquivalencePod returns a EquivalencePod which contains a group of pod attributes which can be reused. // GetEquivalencePod returns a equivalencePod which contains a group of pod attributes which can be reused.
func (e *EquivalencePodGenerator) getEquivalencePod(pod *v1.Pod) interface{} { func (e *EquivalencePodGenerator) getEquivalencePod(pod *v1.Pod) interface{} {
// For now we only consider pods: // For equivalence hash to be formally correct, lists and maps
// 1. OwnerReferences is Controller // in the equivalencePod should be normalized. (e.g. by sorting
// 2. with same OwnerReferences // them) However, the vast majority of equivalent pod classes
// 3. with same PVC claim // are expected to be created from a single pod template, so
// to be equivalent // they will all have the same ordering.
for _, ref := range pod.OwnerReferences { return &equivalencePod{
if ref.Controller != nil && *ref.Controller { Labels: pod.Labels,
if pvcSet, err := e.getPVCSet(pod); err == nil { Affinity: pod.Spec.Affinity,
// A pod can only belongs to one controller, so let's return. Containers: pod.Spec.Containers,
return &EquivalencePod{ InitContainers: pod.Spec.InitContainers,
ControllerRef: ref, NodeName: &pod.Spec.NodeName,
PVCSet: pvcSet, NodeSelector: pod.Spec.NodeSelector,
} Tolerations: pod.Spec.Tolerations,
} else { Volumes: pod.Spec.Volumes,
// If error encountered, log warning and return nil (i.e. no equivalent pod found)
glog.Warningf("[EquivalencePodGenerator] for pod: %v failed due to: %v", pod.GetName(), err)
return nil
}
}
}
return nil
}
// getPVCSet returns a set of PVC UIDs of given pod.
func (e *EquivalencePodGenerator) getPVCSet(pod *v1.Pod) (sets.String, error) {
result := sets.NewString()
for _, volume := range pod.Spec.Volumes {
if volume.PersistentVolumeClaim == nil {
continue
}
pvcName := volume.PersistentVolumeClaim.ClaimName
pvc, err := e.pvcInfo.GetPersistentVolumeClaimInfo(pod.GetNamespace(), pvcName)
if err != nil {
return nil, err
}
result.Insert(string(pvc.UID))
} }
return result, nil
} }
// EquivalencePod is a group of pod attributes which can be reused as equivalence to schedule other pods. // equivalencePod is a group of pod attributes which can be reused as equivalence to schedule other pods.
type EquivalencePod struct { type equivalencePod struct {
ControllerRef metav1.OwnerReference Labels map[string]string
PVCSet sets.String Affinity *v1.Affinity
Containers []v1.Container // note about ordering
InitContainers []v1.Container // note about ordering
NodeName *string
NodeSelector map[string]string
Tolerations []v1.Toleration
Volumes []v1.Volume // note about ordering
} }
// portsConflict check whether existingPorts and wantPorts conflict with each other // portsConflict check whether existingPorts and wantPorts conflict with each other
......
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