pods.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package node
  14. import (
  15. "context"
  16. "encoding/json"
  17. "net/http"
  18. "strconv"
  19. "time"
  20. v1 "k8s.io/api/core/v1"
  21. "k8s.io/apimachinery/pkg/api/resource"
  22. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  23. "k8s.io/apimachinery/pkg/labels"
  24. "k8s.io/apimachinery/pkg/util/uuid"
  25. "k8s.io/apimachinery/pkg/util/wait"
  26. "k8s.io/kubernetes/test/e2e/framework"
  27. e2ekubelet "k8s.io/kubernetes/test/e2e/framework/kubelet"
  28. imageutils "k8s.io/kubernetes/test/utils/image"
  29. "github.com/onsi/ginkgo"
  30. )
  31. var _ = SIGDescribe("Pods Extended", func() {
  32. f := framework.NewDefaultFramework("pods")
  33. framework.KubeDescribe("Delete Grace Period", func() {
  34. var podClient *framework.PodClient
  35. ginkgo.BeforeEach(func() {
  36. podClient = f.PodClient()
  37. })
  38. /*
  39. Release : v1.15
  40. Testname: Pods, delete grace period
  41. Description: Create a pod, make sure it is running. Using the http client send a 'delete' with gracePeriodSeconds=30. Pod SHOULD get deleted within 30 seconds.
  42. */
  43. ginkgo.It("should be submitted and removed [Flaky]", func() {
  44. ginkgo.By("creating the pod")
  45. name := "pod-submit-remove-" + string(uuid.NewUUID())
  46. value := strconv.Itoa(time.Now().Nanosecond())
  47. pod := &v1.Pod{
  48. ObjectMeta: metav1.ObjectMeta{
  49. Name: name,
  50. Labels: map[string]string{
  51. "name": "foo",
  52. "time": value,
  53. },
  54. },
  55. Spec: v1.PodSpec{
  56. Containers: []v1.Container{
  57. {
  58. Name: "agnhost",
  59. Image: imageutils.GetE2EImage(imageutils.Agnhost),
  60. Args: []string{"pause"},
  61. },
  62. },
  63. },
  64. }
  65. ginkgo.By("setting up selector")
  66. selector := labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
  67. options := metav1.ListOptions{LabelSelector: selector.String()}
  68. pods, err := podClient.List(context.TODO(), options)
  69. framework.ExpectNoError(err, "failed to query for pod")
  70. framework.ExpectEqual(len(pods.Items), 0)
  71. options = metav1.ListOptions{
  72. LabelSelector: selector.String(),
  73. ResourceVersion: pods.ListMeta.ResourceVersion,
  74. }
  75. ginkgo.By("submitting the pod to kubernetes")
  76. podClient.Create(pod)
  77. ginkgo.By("verifying the pod is in kubernetes")
  78. selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
  79. options = metav1.ListOptions{LabelSelector: selector.String()}
  80. pods, err = podClient.List(context.TODO(), options)
  81. framework.ExpectNoError(err, "failed to query for pod")
  82. framework.ExpectEqual(len(pods.Items), 1)
  83. // We need to wait for the pod to be running, otherwise the deletion
  84. // may be carried out immediately rather than gracefully.
  85. framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
  86. // save the running pod
  87. pod, err = podClient.Get(context.TODO(), pod.Name, metav1.GetOptions{})
  88. framework.ExpectNoError(err, "failed to GET scheduled pod")
  89. ginkgo.By("deleting the pod gracefully")
  90. var lastPod v1.Pod
  91. var statusCode int
  92. err = f.ClientSet.CoreV1().RESTClient().Delete().AbsPath("/api/v1/namespaces", pod.Namespace, "pods", pod.Name).Param("gracePeriodSeconds", "30").Do(context.TODO()).StatusCode(&statusCode).Into(&lastPod)
  93. framework.ExpectNoError(err, "failed to use http client to send delete")
  94. framework.ExpectEqual(statusCode, http.StatusOK, "failed to delete gracefully by client request")
  95. ginkgo.By("verifying the kubelet observed the termination notice")
  96. start := time.Now()
  97. err = wait.Poll(time.Second*5, time.Second*30, func() (bool, error) {
  98. podList, err := e2ekubelet.GetKubeletPods(f.ClientSet, pod.Spec.NodeName)
  99. if err != nil {
  100. framework.Logf("Unable to retrieve kubelet pods for node %v: %v", pod.Spec.NodeName, err)
  101. return false, nil
  102. }
  103. for _, kubeletPod := range podList.Items {
  104. if pod.Name != kubeletPod.Name || pod.Namespace != kubeletPod.Namespace {
  105. continue
  106. }
  107. if kubeletPod.ObjectMeta.DeletionTimestamp == nil {
  108. framework.Logf("deletion has not yet been observed")
  109. return false, nil
  110. }
  111. data, _ := json.Marshal(kubeletPod)
  112. framework.Logf("start=%s, now=%s, kubelet pod: %s", start, time.Now(), string(data))
  113. return false, nil
  114. }
  115. framework.Logf("no pod exists with the name we were looking for, assuming the termination request was observed and completed")
  116. return true, nil
  117. })
  118. framework.ExpectNoError(err, "kubelet never observed the termination notice")
  119. framework.ExpectNotEqual(lastPod.DeletionTimestamp, nil)
  120. framework.ExpectNotEqual(lastPod.Spec.TerminationGracePeriodSeconds, 0)
  121. selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
  122. options = metav1.ListOptions{LabelSelector: selector.String()}
  123. pods, err = podClient.List(context.TODO(), options)
  124. framework.ExpectNoError(err, "failed to query for pods")
  125. framework.ExpectEqual(len(pods.Items), 0)
  126. })
  127. })
  128. framework.KubeDescribe("Pods Set QOS Class", func() {
  129. var podClient *framework.PodClient
  130. ginkgo.BeforeEach(func() {
  131. podClient = f.PodClient()
  132. })
  133. /*
  134. Release : v1.9
  135. Testname: Pods, QOS
  136. Description: Create a Pod with CPU and Memory request and limits. Pod status MUST have QOSClass set to PodQOSGuaranteed.
  137. */
  138. framework.ConformanceIt("should be set on Pods with matching resource requests and limits for memory and cpu", func() {
  139. ginkgo.By("creating the pod")
  140. name := "pod-qos-class-" + string(uuid.NewUUID())
  141. pod := &v1.Pod{
  142. ObjectMeta: metav1.ObjectMeta{
  143. Name: name,
  144. Labels: map[string]string{
  145. "name": name,
  146. },
  147. },
  148. Spec: v1.PodSpec{
  149. Containers: []v1.Container{
  150. {
  151. Name: "agnhost",
  152. Image: imageutils.GetE2EImage(imageutils.Agnhost),
  153. Args: []string{"pause"},
  154. Resources: v1.ResourceRequirements{
  155. Limits: v1.ResourceList{
  156. v1.ResourceCPU: resource.MustParse("100m"),
  157. v1.ResourceMemory: resource.MustParse("100Mi"),
  158. },
  159. Requests: v1.ResourceList{
  160. v1.ResourceCPU: resource.MustParse("100m"),
  161. v1.ResourceMemory: resource.MustParse("100Mi"),
  162. },
  163. },
  164. },
  165. },
  166. },
  167. }
  168. ginkgo.By("submitting the pod to kubernetes")
  169. podClient.Create(pod)
  170. ginkgo.By("verifying QOS class is set on the pod")
  171. pod, err := podClient.Get(context.TODO(), name, metav1.GetOptions{})
  172. framework.ExpectNoError(err, "failed to query for pod")
  173. framework.ExpectEqual(pod.Status.QOSClass, v1.PodQOSGuaranteed)
  174. })
  175. })
  176. })