rebase master

This commit is contained in:
boenn
2021-11-25 10:34:43 +08:00
parent aff056d8a1
commit cec2aae1e5
8 changed files with 294 additions and 188 deletions

View File

@@ -21,16 +21,10 @@ import (
"runtime"
v1 "k8s.io/api/core/v1"
"k8s.io/apiserver/pkg/util/feature"
v1affinityhelper "k8s.io/component-helpers/scheduling/corev1/nodeaffinity"
"k8s.io/klog/v2"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler"
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
)
type getNodeAnyWayFuncType func() (*v1.Node, error)
@@ -96,17 +90,8 @@ func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult
// the Resource Class API in the future.
podWithoutMissingExtendedResources := removeMissingExtendedResources(admitPod, nodeInfo)
reasons, err := GeneralPredicates(podWithoutMissingExtendedResources, nodeInfo)
fit := len(reasons) == 0 && err == nil
if err != nil {
message := fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", err)
klog.InfoS("Failed to admit pod, GeneralPredicates failed", "pod", klog.KObj(admitPod), "err", err)
return PodAdmitResult{
Admit: fit,
Reason: "UnexpectedAdmissionError",
Message: message,
}
}
reasons := generalFilter(podWithoutMissingExtendedResources, nodeInfo)
fit := len(reasons) == 0
if !fit {
reasons, err = w.admissionFailureHandler.HandleAdmissionFailure(admitPod, reasons)
fit = len(reasons) == 0 && err == nil
@@ -269,33 +254,21 @@ func (e *PredicateFailureError) GetReason() string {
return e.PredicateDesc
}
// GeneralPredicates checks a group of predicates that the kubelet cares about.
func GeneralPredicates(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) ([]PredicateFailureReason, error) {
if nodeInfo.Node() == nil {
return nil, fmt.Errorf("node not found")
}
// generalFilter checks a group of filterings that the kubelet cares about.
func generalFilter(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) []PredicateFailureReason {
admissionResults := scheduler.AdmissionCheck(pod, nodeInfo, true)
var reasons []PredicateFailureReason
for _, r := range noderesources.Fits(pod, nodeInfo, feature.DefaultFeatureGate.Enabled(features.PodOverhead)) {
reasons = append(reasons, &InsufficientResourceError{
ResourceName: r.ResourceName,
Requested: r.Requested,
Used: r.Used,
Capacity: r.Capacity,
})
for _, r := range admissionResults {
if r.InsufficientResource != nil {
reasons = append(reasons, &InsufficientResourceError{
ResourceName: r.InsufficientResource.ResourceName,
Requested: r.InsufficientResource.Requested,
Used: r.InsufficientResource.Used,
Capacity: r.InsufficientResource.Capacity,
})
} else {
reasons = append(reasons, &PredicateFailureError{r.Name, r.Reason})
}
}
// Ignore parsing errors for backwards compatibility.
match, _ := v1affinityhelper.GetRequiredNodeAffinity(pod).Match(nodeInfo.Node())
if !match {
reasons = append(reasons, &PredicateFailureError{nodeaffinity.Name, nodeaffinity.ErrReasonPod})
}
if !nodename.Fits(pod, nodeInfo) {
reasons = append(reasons, &PredicateFailureError{nodename.Name, nodename.ErrReason})
}
if !nodeports.Fits(pod, nodeInfo) {
reasons = append(reasons, &PredicateFailureError{nodeports.Name, nodeports.ErrReason})
}
return reasons, nil
return reasons
}

View File

@@ -17,10 +17,10 @@ limitations under the License.
package lifecycle
import (
"reflect"
goruntime "runtime"
"testing"
"github.com/google/go-cmp/cmp"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -87,8 +87,8 @@ func TestRemoveMissingExtendedResources(t *testing.T) {
nodeInfo := schedulerframework.NewNodeInfo()
nodeInfo.SetNode(test.node)
pod := removeMissingExtendedResources(test.pod, nodeInfo)
if !reflect.DeepEqual(pod, test.expectedPod) {
t.Errorf("%s: Expected pod\n%v\ngot\n%v\n", test.desc, test.expectedPod, pod)
if diff := cmp.Diff(test.expectedPod, pod); diff != "" {
t.Errorf("unexpected pod (-want, +got):\n%s", diff)
}
}
}
@@ -180,9 +180,7 @@ func TestGeneralPredicates(t *testing.T) {
pod *v1.Pod
nodeInfo *schedulerframework.NodeInfo
node *v1.Node
fits bool
name string
wErr error
reasons []PredicateFailureReason
}{
{
@@ -196,8 +194,6 @@ func TestGeneralPredicates(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
fits: true,
wErr: nil,
name: "no resources/port/host requested always fits",
},
{
@@ -214,8 +210,6 @@ func TestGeneralPredicates(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
fits: false,
wErr: nil,
reasons: []PredicateFailureReason{
&InsufficientResourceError{ResourceName: v1.ResourceCPU, Requested: 8, Used: 5, Capacity: 10},
&InsufficientResourceError{ResourceName: v1.ResourceMemory, Requested: 10, Used: 19, Capacity: 20},
@@ -233,8 +227,6 @@ func TestGeneralPredicates(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
fits: false,
wErr: nil,
reasons: []PredicateFailureReason{&PredicateFailureError{nodename.Name, nodename.ErrReason}},
name: "host not match",
},
@@ -245,8 +237,6 @@ func TestGeneralPredicates(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
fits: false,
wErr: nil,
reasons: []PredicateFailureReason{&PredicateFailureError{nodeports.Name, nodeports.ErrReason}},
name: "hostport conflict",
},
@@ -254,16 +244,9 @@ func TestGeneralPredicates(t *testing.T) {
for _, test := range resourceTests {
t.Run(test.name, func(t *testing.T) {
test.nodeInfo.SetNode(test.node)
reasons, err := GeneralPredicates(test.pod, test.nodeInfo)
fits := len(reasons) == 0 && err == nil
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !fits && !reflect.DeepEqual(reasons, test.reasons) {
t.Errorf("unexpected failure reasons: %v, want: %v", reasons, test.reasons)
}
if fits != test.fits {
t.Errorf("expected: %v got %v", test.fits, fits)
reasons := generalFilter(test.pod, test.nodeInfo)
if diff := cmp.Diff(test.reasons, reasons); diff != "" {
t.Errorf("unexpected failure reasons (-want, +got):\n%s", diff)
}
})
}