Merge pull request #72087 from pontiyaraja/pod_termination

graceful pod termination with preStop container life cycle hook
pull/564/head
Kubernetes Prow Robot 2019-01-24 21:17:44 -08:00 committed by GitHub
commit 402263fd4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 0 deletions

View File

@ -24,6 +24,7 @@ go_library(
"//pkg/kubelet/apis/stats/v1alpha1:go_default_library",
"//pkg/kubelet/events:go_default_library",
"//pkg/kubelet/runtimeclass/testing:go_default_library",
"//pkg/master/ports:go_default_library",
"//pkg/util/slice:go_default_library",
"//staging/src/k8s.io/api/batch/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",

View File

@ -24,12 +24,15 @@ import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/master/ports"
"k8s.io/kubernetes/test/e2e/framework"
imageutils "k8s.io/kubernetes/test/utils/image"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
// partially cloned from webserver.go
@ -160,6 +163,10 @@ func testPreStop(c clientset.Interface, ns string) {
var _ = SIGDescribe("PreStop", func() {
f := framework.NewDefaultFramework("prestop")
var podClient *framework.PodClient
BeforeEach(func() {
podClient = f.PodClient()
})
/*
Release : v1.9
@ -169,4 +176,70 @@ var _ = SIGDescribe("PreStop", func() {
framework.ConformanceIt("should call prestop when killing a pod ", func() {
testPreStop(f.ClientSet, f.Namespace.Name)
})
It("graceful pod terminated should wait until preStop hook completes the process", func() {
gracefulTerminationPeriodSeconds := int64(30)
By("creating the pod")
name := "pod-prestop-hook-" + string(uuid.NewUUID())
pod := getPodWithpreStopLifeCycle(name)
By("submitting the pod to kubernetes")
podClient.Create(pod)
By("waiting for pod running")
framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
var err error
pod, err = podClient.Get(pod.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to GET scheduled pod")
By("deleting the pod gracefully")
err = podClient.Delete(pod.Name, metav1.NewDeleteOptions(gracefulTerminationPeriodSeconds))
Expect(err).NotTo(HaveOccurred(), "failed to delete pod")
//wait up to graceful termination period seconds
time.Sleep(30 * time.Second)
By("verifying the pod running state after graceful termination")
result := &v1.PodList{}
err = wait.Poll(time.Second*5, time.Second*60, func() (bool, error) {
client, err := framework.NodeProxyRequest(f.ClientSet, pod.Spec.NodeName, "pods", ports.KubeletPort)
Expect(err).NotTo(HaveOccurred(), "failed to get the pods of the node")
err = client.Into(result)
Expect(err).NotTo(HaveOccurred(), "failed to parse the pods of the node")
for _, kubeletPod := range result.Items {
if pod.Name != kubeletPod.Name {
continue
} else if kubeletPod.Status.Phase == v1.PodRunning {
framework.Logf("pod is running")
return true, err
}
}
return false, err
})
})
})
func getPodWithpreStopLifeCycle(name string) *v1.Pod {
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "nginx",
Image: imageutils.GetE2EImage(imageutils.Nginx),
Lifecycle: &v1.Lifecycle{
PreStop: &v1.Handler{
Exec: &v1.ExecAction{
Command: []string{"sh", "-c", "while true; do echo preStop; sleep 1; done"},
},
},
},
},
},
},
}
}