Merge pull request #101218 from gjkim42/add-taint-toleration-check

kubelet: check taint/toleration before accepting pods
This commit is contained in:
Kubernetes Prow Robot 2022-03-29 09:16:56 -07:00 committed by GitHub
commit 6c96ac04ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 0 deletions

View File

@ -21,10 +21,13 @@ import (
"runtime" "runtime"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/component-helpers/scheduling/corev1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/scheduler" "k8s.io/kubernetes/pkg/scheduler"
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration"
) )
type getNodeAnyWayFuncType func() (*v1.Node, error) type getNodeAnyWayFuncType func() (*v1.Node, error)
@ -270,5 +273,17 @@ func generalFilter(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) []Predica
reasons = append(reasons, &PredicateFailureError{r.Name, r.Reason}) reasons = append(reasons, &PredicateFailureError{r.Name, r.Reason})
} }
} }
// Check taint/toleration except for static pods
if !types.IsStaticPod(pod) {
_, isUntolerated := corev1.FindMatchingUntoleratedTaint(nodeInfo.Node().Spec.Taints, pod.Spec.Tolerations, func(t *v1.Taint) bool {
// Kubelet is only interested in the NoExecute taint.
return t.Effect == v1.TaintEffectNoExecute
})
if isUntolerated {
reasons = append(reasons, &PredicateFailureError{tainttoleration.Name, tainttoleration.ErrReasonNotMatch})
}
}
return reasons return reasons
} }

View File

@ -25,9 +25,11 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/kubelet/types"
schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration"
) )
var ( var (
@ -240,6 +242,92 @@ func TestGeneralPredicates(t *testing.T) {
reasons: []PredicateFailureReason{&PredicateFailureError{nodeports.Name, nodeports.ErrReason}}, reasons: []PredicateFailureReason{&PredicateFailureError{nodeports.Name, nodeports.ErrReason}},
name: "hostport conflict", name: "hostport conflict",
}, },
{
pod: &v1.Pod{
Spec: v1.PodSpec{
Tolerations: []v1.Toleration{
{Key: "foo"},
{Key: "bar"},
},
},
},
nodeInfo: schedulerframework.NewNodeInfo(),
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Spec: v1.NodeSpec{
Taints: []v1.Taint{
{Key: "foo", Effect: v1.TaintEffectNoSchedule},
{Key: "bar", Effect: v1.TaintEffectNoExecute},
},
},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
name: "taint/toleration match",
},
{
pod: &v1.Pod{},
nodeInfo: schedulerframework.NewNodeInfo(),
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Spec: v1.NodeSpec{
Taints: []v1.Taint{
{Key: "foo", Effect: v1.TaintEffectNoSchedule},
},
},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
name: "NoSchedule taint/toleration not match",
},
{
pod: &v1.Pod{},
nodeInfo: schedulerframework.NewNodeInfo(),
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Spec: v1.NodeSpec{
Taints: []v1.Taint{
{Key: "bar", Effect: v1.TaintEffectNoExecute},
},
},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
reasons: []PredicateFailureReason{&PredicateFailureError{tainttoleration.Name, tainttoleration.ErrReasonNotMatch}},
name: "NoExecute taint/toleration not match",
},
{
pod: &v1.Pod{},
nodeInfo: schedulerframework.NewNodeInfo(),
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Spec: v1.NodeSpec{
Taints: []v1.Taint{
{Key: "baz", Effect: v1.TaintEffectPreferNoSchedule},
},
},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
name: "PreferNoSchedule taint/toleration not match",
},
{
pod: &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
types.ConfigSourceAnnotationKey: types.FileSource,
},
},
},
nodeInfo: schedulerframework.NewNodeInfo(),
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "machine1"},
Spec: v1.NodeSpec{
Taints: []v1.Taint{
{Key: "foo", Effect: v1.TaintEffectNoSchedule},
{Key: "bar", Effect: v1.TaintEffectNoExecute},
},
},
Status: v1.NodeStatus{Capacity: makeResources(10, 20, 32, 0, 0, 0).Capacity, Allocatable: makeAllocatableResources(10, 20, 32, 0, 0, 0)},
},
name: "static pods ignore taints",
},
} }
for _, test := range resourceTests { for _, test := range resourceTests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {