implement taints and tolerations

This commit is contained in:
Kevin
2016-03-31 11:42:57 +08:00
parent 952e8302fb
commit 52fb89ff73
34 changed files with 4623 additions and 69 deletions

View File

@@ -19,6 +19,7 @@ package e2e
import (
"fmt"
"path/filepath"
"strings"
"time"
"k8s.io/kubernetes/pkg/api"
@@ -1280,4 +1281,250 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() {
framework.ExpectNoError(err)
Expect(labelPod.Spec.NodeName).To(Equal(nodeName))
})
// 1. Run a pod to get an available node, then delete the pod
// 2. Taint the node with a random taint
// 3. Try to relaunch the pod with tolerations tolerate the taints on node,
// and the pod's nodeName specified to the name of node found in step 1
It("validates that taints-tolerations is respected if matching", func() {
// launch a pod to find a node which can launch a pod. We intentionally do
// not just take the node list and choose the first of them. Depending on the
// cluster and the scheduler it might be that a "normal" pod cannot be
// scheduled onto it.
By("Trying to launch a pod without a toleration to get a node which can launch it.")
podName := "without-toleration"
_, err := c.Pods(ns).Create(&api.Pod{
TypeMeta: unversioned.TypeMeta{
Kind: "Pod",
},
ObjectMeta: api.ObjectMeta{
Name: podName,
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: podName,
Image: "gcr.io/google_containers/pause-amd64:3.0",
},
},
},
})
framework.ExpectNoError(err)
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(c, podName, ns))
pod, err := c.Pods(ns).Get(podName)
framework.ExpectNoError(err)
nodeName := pod.Spec.NodeName
err = c.Pods(ns).Delete(podName, api.NewDeleteOptions(0))
framework.ExpectNoError(err)
By("Trying to apply a random taint on the found node.")
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(util.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := string(api.TaintEffectNoSchedule)
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"="+taintValue+":"+taintEffect)
By("verifying the node has the taint " + taintName + " with the value " + taintValue)
output := framework.RunKubectlOrDie("describe", "node", nodeName)
requiredStrings := [][]string{
{"Name:", nodeName},
{"Taints:"},
{taintName, taintValue, taintEffect},
}
checkOutput(output, requiredStrings)
By("Trying to apply a random label on the found node.")
labelKey := fmt.Sprintf("kubernetes.io/e2e-label-key-%s", string(util.NewUUID()))
labelValue := "testing-label-value"
framework.RunKubectlOrDie("label", "nodes", nodeName, labelKey+"="+labelValue)
By("verifying the node has the label " + labelKey + " with the value " + labelValue)
labelOutput := framework.RunKubectlOrDie("describe", "node", nodeName)
labelOutputRequiredStrings := [][]string{
{"Name:", nodeName},
{"Labels:"},
{labelKey + "=" + labelValue},
}
checkOutput(labelOutput, labelOutputRequiredStrings)
By("Trying to relaunch the pod, now with tolerations.")
tolerationPodName := "with-tolerations"
_, err = c.Pods(ns).Create(&api.Pod{
TypeMeta: unversioned.TypeMeta{
Kind: "Pod",
},
ObjectMeta: api.ObjectMeta{
Name: tolerationPodName,
Annotations: map[string]string{
"scheduler.alpha.kubernetes.io/tolerations": `
[
{
"key": "` + taintName + `",
"value": "` + taintValue + `",
"effect": "` + taintEffect + `"
}
]`,
},
},
Spec: api.PodSpec{
NodeSelector: map[string]string{labelKey: labelValue},
Containers: []api.Container{
{
Name: tolerationPodName,
Image: "gcr.io/google_containers/pause-amd64:3.0",
},
},
},
})
framework.ExpectNoError(err)
defer c.Pods(ns).Delete(tolerationPodName, api.NewDeleteOptions(0))
// check that pod got scheduled. We intentionally DO NOT check that the
// pod is running because this will create a race condition with the
// kubelet and the scheduler: the scheduler might have scheduled a pod
// already when the kubelet does not know about its new taint yet. The
// kubelet will then refuse to launch the pod.
framework.ExpectNoError(framework.WaitForPodNotPending(c, ns, tolerationPodName))
deployedPod, err := c.Pods(ns).Get(tolerationPodName)
framework.ExpectNoError(err)
Expect(deployedPod.Spec.NodeName).To(Equal(nodeName))
By("removing the taint " + taintName + " off the node " + nodeName)
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"-")
By("verifying the node doesn't have the taint " + taintName)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, taintName) {
framework.Failf("Failed removing taint " + taintName + " of the node " + nodeName)
}
By("removing the label " + labelKey + " off the node " + nodeName)
framework.RunKubectlOrDie("label", "nodes", nodeName, labelKey+"-")
By("verifying the node doesn't have the label " + labelKey)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, labelKey) {
framework.Failf("Failed removing label " + labelKey + " of the node " + nodeName)
}
})
// 1. Run a pod to get an available node, then delete the pod
// 2. Taint the node with a random taint
// 3. Try to relaunch the pod still no tolerations,
// and the pod's nodeName specified to the name of node found in step 1
It("validates that taints-tolerations is respected if not matching", func() {
// launch a pod to find a node which can launch a pod. We intentionally do
// not just take the node list and choose the first of them. Depending on the
// cluster and the scheduler it might be that a "normal" pod cannot be
// scheduled onto it.
By("Trying to launch a pod without a toleration to get a node which can launch it.")
podName := "without-toleration"
_, err := c.Pods(ns).Create(&api.Pod{
TypeMeta: unversioned.TypeMeta{
Kind: "Pod",
},
ObjectMeta: api.ObjectMeta{
Name: podName,
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: podName,
Image: "gcr.io/google_containers/pause-amd64:3.0",
},
},
},
})
framework.ExpectNoError(err)
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(c, podName, ns))
pod, err := c.Pods(ns).Get(podName)
framework.ExpectNoError(err)
nodeName := pod.Spec.NodeName
err = c.Pods(ns).Delete(podName, api.NewDeleteOptions(0))
framework.ExpectNoError(err)
By("Trying to apply a random taint on the found node.")
taintName := fmt.Sprintf("kubernetes.io/e2e-taint-key-%s", string(util.NewUUID()))
taintValue := "testing-taint-value"
taintEffect := string(api.TaintEffectNoSchedule)
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"="+taintValue+":"+taintEffect)
By("verifying the node has the taint " + taintName + " with the value " + taintValue)
output := framework.RunKubectlOrDie("describe", "node", nodeName)
requiredStrings := [][]string{
{"Name:", nodeName},
{"Taints:"},
{taintName, taintValue, taintEffect},
}
checkOutput(output, requiredStrings)
By("Trying to apply a random label on the found node.")
labelKey := fmt.Sprintf("kubernetes.io/e2e-label-key-%s", string(util.NewUUID()))
labelValue := "testing-label-value"
framework.RunKubectlOrDie("label", "nodes", nodeName, labelKey+"="+labelValue)
By("verifying the node has the label " + labelKey + " with the value " + labelValue)
labelOutput := framework.RunKubectlOrDie("describe", "node", nodeName)
labelOutputRequiredStrings := [][]string{
{"Name:", nodeName},
{"Labels:"},
{labelKey + "=" + labelValue},
}
checkOutput(labelOutput, labelOutputRequiredStrings)
By("Trying to relaunch the pod, still no tolerations.")
podNameNoTolerations := "still-no-tolerations"
podNoTolerations := api.Pod{
TypeMeta: unversioned.TypeMeta{
Kind: "Pod",
},
ObjectMeta: api.ObjectMeta{
Name: podNameNoTolerations,
},
Spec: api.PodSpec{
NodeSelector: map[string]string{labelKey: labelValue},
Containers: []api.Container{
{
Name: podNameNoTolerations,
Image: "gcr.io/google_containers/pause-amd64:3.0",
},
},
},
}
_, err = c.Pods(ns).Create(&podNoTolerations)
framework.ExpectNoError(err)
// Wait a bit to allow scheduler to do its thing
// TODO: this is brittle; there's no guarantee the scheduler will have run in 10 seconds.
framework.Logf("Sleeping 10 seconds and crossing our fingers that scheduler will run in that time.")
time.Sleep(10 * time.Second)
verifyResult(c, podNameNoTolerations, ns)
cleanupPods(c, ns)
By("removing the taint " + taintName + " off the node " + nodeName)
framework.RunKubectlOrDie("taint", "nodes", nodeName, taintName+"-")
By("verifying the node doesn't have the taint " + taintName)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, taintName) {
framework.Failf("Failed removing taint " + taintName + " of the node " + nodeName)
}
By("Trying to relaunch the same.")
_, err = c.Pods(ns).Create(&podNoTolerations)
framework.ExpectNoError(err)
defer c.Pods(ns).Delete(podNameNoTolerations, api.NewDeleteOptions(0))
// check that pod got scheduled. We intentionally DO NOT check that the
// pod is running because this will create a race condition with the
// kubelet and the scheduler: the scheduler might have scheduled a pod
// already when the kubelet does not know about its new taint yet. The
// kubelet will then refuse to launch the pod.
framework.ExpectNoError(framework.WaitForPodNotPending(c, ns, podNameNoTolerations))
deployedPod, err := c.Pods(ns).Get(podNameNoTolerations)
framework.ExpectNoError(err)
Expect(deployedPod.Spec.NodeName).To(Equal(nodeName))
By("removing the label " + labelKey + " off the node " + nodeName)
framework.RunKubectlOrDie("label", "nodes", nodeName, labelKey+"-")
By("verifying the node doesn't have the label " + labelKey)
output = framework.RunKubectlOrDie("describe", "node", nodeName)
if strings.Contains(output, labelKey) {
framework.Failf("Failed removing label " + labelKey + " of the node " + nodeName)
}
})
})