mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #101218 from gjkim42/add-taint-toleration-check
kubelet: check taint/toleration before accepting pods
This commit is contained in:
commit
6c96ac04ff
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user