Change:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: What happened: When discussing issue in , I noticed: although is using key , it has actually been changed to in for quite a while. I am thinking we may need to fix this inconsistency in 1.9, by moving out of alpha. Anything else we need to know?: Task tracker: [x] update [x] update kubernetes doc
/sig scheduling

Discussion:
for _, taint := range node.Spec.Taints { if taint.Key == algorithm.DeprecatedTaintNodeNotReady { <del> // delete old taint </del> tDel := taint taintsToDel = append(taintsToDel, &tDel) <del> // add right taint </del> tAdd := taint tAdd.Key = algorithm.TaintNodeNotReady taintsToAdd = append(taintsToAdd, &tAdd) <ins> } </ins> <del> glog.Warningf("Detected deprecated taint key: %v on node: %v, will substitute it with %v", algorithm.DeprecatedTaintNodeNotReady, node.GetName(), algorithm.TaintNodeNotReady) </del> <ins> if taint.Key == algorithm.DeprecatedTaintNodeUnreachable { tDel := taint taintsToDel = append(taintsToDel, &tDel) </ins> <del> break </del> <ins> tAdd := taint tAdd.Key = algorithm.TaintNodeUnreachable taintsToAdd = append(taintsToAdd, &tAdd) </ins> } } if len(taintsToAdd) == 0 && len(taintsToDel) == 0 { return nil } <ins> glog.Warningf("Detected deprecated taint keys: %v on node: %v, will substitute them with %v", taintsToDel, node.GetName(), taintsToAdd) </ins> if !util.SwapNodeControllerTaint(nc.kubeClient, taintsToAdd, taintsToDel, node) { return fmt.Errorf("failed to swap taints of node %+v", node) }

} } } <ins> // TestFixDeprecatedTaintKey verifies we have backwards compatibility after upgraded alpha taint key to GA taint key. // TODO(resouer): this is introduced in 1.9 and should be removed in the future. func TestFixDeprecatedTaintKey(t *testing.T) { fakeNow := metav1.Date(2017, 1, 1, 12, 0, 0, 0, time.UTC) evictionTimeout := 10 * time.Minute fakeNodeHandler := &testutil.FakeNodeHandler{ Existing: []*v1.Node{ { ObjectMeta: metav1.ObjectMeta{ Name:              "node0", CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Labels: map[string]string{ kubeletapis.LabelZoneRegion:        "region1", kubeletapis.LabelZoneFailureDomain: "zone1", }, }, }, }, Clientset: fake.NewSimpleClientset(&v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}), } nodeController, _ := newNodeControllerFromClient(nil, fakeNodeHandler, evictionTimeout, testRateLimiterQPS, testRateLimiterQPS, testLargeClusterThreshold, testUnhealthyThreshold, testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, nil, 0, false, true) nodeController.now = func() metav1.Time { return fakeNow } nodeController.recorder = testutil.NewFakeRecorder() deprecatedNotReadyTaint := &v1.Taint{ Key:    algorithm.DeprecatedTaintNodeNotReady, Effect: v1.TaintEffectNoExecute, } nodeNotReadyTaint := &v1.Taint{ Key:    algorithm.TaintNodeNotReady, Effect: v1.TaintEffectNoExecute, } deprecatedUnreachableTaint := &v1.Taint{ Key:    algorithm.DeprecatedTaintNodeUnreachable, Effect: v1.TaintEffectNoExecute, } nodeUnreachableTaint := &v1.Taint{ Key:    algorithm.TaintNodeUnreachable, Effect: v1.TaintEffectNoExecute, } tests := []struct { Name           string Node           *v1.Node ExpectedTaints []*v1.Taint }{ { Name: "Node with deprecated not-ready taint key", Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name:              "node0", CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Labels: map[string]string{ kubeletapis.LabelZoneRegion:        "region1", kubeletapis.LabelZoneFailureDomain: "zone1", }, }, Spec: v1.NodeSpec{ Taints: []v1.Taint{ *deprecatedNotReadyTaint, }, }, }, ExpectedTaints: []*v1.Taint{nodeNotReadyTaint}, }, { Name: "Node with deprecated unreachable taint key", Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name:              "node0", CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Labels: map[string]string{ kubeletapis.LabelZoneRegion:        "region1", kubeletapis.LabelZoneFailureDomain: "zone1", }, }, Spec: v1.NodeSpec{ Taints: []v1.Taint{ *deprecatedUnreachableTaint, }, }, }, ExpectedTaints: []*v1.Taint{nodeUnreachableTaint}, }, { Name: "Node with not-ready taint key", Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name:              "node0", CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Labels: map[string]string{ kubeletapis.LabelZoneRegion:        "region1", kubeletapis.LabelZoneFailureDomain: "zone1", }, }, Spec: v1.NodeSpec{ Taints: []v1.Taint{ *nodeNotReadyTaint, }, }, }, ExpectedTaints: []*v1.Taint{nodeNotReadyTaint}, }, { Name: "Node with unreachable taint key", Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name:              "node0", CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), Labels: map[string]string{ kubeletapis.LabelZoneRegion:        "region1", kubeletapis.LabelZoneFailureDomain: "zone1", }, }, Spec: v1.NodeSpec{ Taints: []v1.Taint{ *nodeUnreachableTaint, }, }, }, ExpectedTaints: []*v1.Taint{nodeUnreachableTaint}, }, } for _, test := range tests { fakeNodeHandler.Update(test.Node) if err := syncNodeStore(nodeController, fakeNodeHandler); err != nil { t.Errorf("unexpected error: %v", err) } nodeController.doFixDeprecatedTaintKeyPass(test.Node) if err := syncNodeStore(nodeController, fakeNodeHandler); err != nil { t.Errorf("unexpected error: %v", err) } node, err := nodeController.nodeLister.Get(test.Node.GetName()) if err != nil { t.Errorf("Can't get current node...") return } if len(node.Spec.Taints) != len(test.ExpectedTaints) { t.Errorf("%s: Unexpected number of taints: expected %d, got %d", test.Name, len(test.ExpectedTaints), len(node.Spec.Taints)) } for _, taint := range test.ExpectedTaints { if !taintutils.TaintExists(node.Spec.Taints, taint) { t.Errorf("%s: Can't find taint %v in %v", test.Name, taint, node.Spec.Taints) } } } } </ins>

} handler := NewDefaultTolerationSeconds() <ins> // NOTE: for anyone who want to modify this test, the order of tolerations matters! </ins> tests := []struct { description  string requestedPod api.Pod expectedPod  api.Pod }{ { <del> description: "pod has no tolerations, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`", </del> <ins> description: "pod has no tolerations, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{}, },

}, }, { <del> description: "pod has tolerations, but none is for taint `notReady:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `notReady:NoExecute` and `unreachable:NoExecute`", </del> <ins> description: "pod has alpha tolerations, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`" + ", the alpha tolerations will not be touched", requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.DeprecatedTaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, expectedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.DeprecatedTaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, }, { description: "pod has alpha not-ready toleration, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`" + ", the alpha tolerations will not be touched", requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, expectedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, }, { description: "pod has alpha unreachable toleration, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`" + ", the alpha tolerations will not be touched", requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, expectedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{ { Key:               algorithm.DeprecatedTaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeNotReady, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, { Key:               algorithm.TaintNodeUnreachable, Operator:          api.TolerationOpExists, Effect:            api.TaintEffectNoExecute, TolerationSeconds: &defaultTolerationSeconds, }, }, }, }, }, { description: "pod has tolerations, but none is for taint `not-ready:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{

}, }, { <del> description: "pod specified a toleration for taint `notReady:NoExecute`, expect add toleration for `unreachable:NoExecute`", </del> <ins> description: "pod specified a toleration for taint `not-ready:NoExecute`, expect add toleration for `unreachable:NoExecute`", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{

}, }, { <del> description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `notReady:NoExecute`", </del> <ins> description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `not-ready:NoExecute`", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{

}, }, { <del> description: "pod specified tolerations for both `notReady:NoExecute` and `unreachable:NoExecute`, expect no change", </del> <ins> description: "pod specified tolerations for both `not-ready:NoExecute` and `unreachable:NoExecute`, expect no change", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{

}, }, { <del> description: "pod specified toleration for taint `unreachable`, expect add toleration for `notReady:NoExecute`", </del> <ins> description: "pod specified toleration for taint `unreachable`, expect add toleration for `not-ready:NoExecute`", </ins> requestedPod: api.Pod{ Spec: api.PodSpec{ Tolerations: []api.Toleration{

// TaintNodeUnreachable would be automatically added by node controller // when node becomes unreachable (corresponding to NodeReady status ConditionUnknown) // and removed when node becomes reachable (NodeReady status ConditionTrue). <del> TaintNodeUnreachable = "node.alpha.kubernetes.io/unreachable" </del> <ins> TaintNodeUnreachable = "node.kubernetes.io/unreachable" // DeprecatedTaintNodeUnreachable is the deprecated version of TaintNodeUnreachable. // It is deprecated since 1.9 DeprecatedTaintNodeUnreachable = "node.alpha.kubernetes.io/unreachable" </ins> // When feature-gate for TaintBasedEvictions=true flag is enabled, // TaintNodeOutOfDisk would be automatically added by node controller