garbage_collector.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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 e2e
  14. import (
  15. "fmt"
  16. "time"
  17. "k8s.io/kubernetes/pkg/api"
  18. "k8s.io/kubernetes/pkg/api/unversioned"
  19. "k8s.io/kubernetes/pkg/api/v1"
  20. clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3"
  21. "k8s.io/kubernetes/pkg/metrics"
  22. "k8s.io/kubernetes/pkg/util/wait"
  23. "k8s.io/kubernetes/test/e2e/framework"
  24. . "github.com/onsi/ginkgo"
  25. )
  26. func getOrphanOptions() *api.DeleteOptions {
  27. var trueVar = true
  28. return &api.DeleteOptions{OrphanDependents: &trueVar}
  29. }
  30. func getNonOrphanOptions() *api.DeleteOptions {
  31. var falseVar = false
  32. return &api.DeleteOptions{OrphanDependents: &falseVar}
  33. }
  34. func newOwnerRC(f *framework.Framework, name string) *v1.ReplicationController {
  35. var replicas int32
  36. replicas = 2
  37. return &v1.ReplicationController{
  38. TypeMeta: unversioned.TypeMeta{
  39. Kind: "ReplicationController",
  40. APIVersion: "v1",
  41. },
  42. ObjectMeta: v1.ObjectMeta{
  43. Namespace: f.Namespace.Name,
  44. Name: name,
  45. },
  46. Spec: v1.ReplicationControllerSpec{
  47. Replicas: &replicas,
  48. Selector: map[string]string{"app": "gc-test"},
  49. Template: &v1.PodTemplateSpec{
  50. ObjectMeta: v1.ObjectMeta{
  51. Labels: map[string]string{"app": "gc-test"},
  52. },
  53. Spec: v1.PodSpec{
  54. Containers: []v1.Container{
  55. {
  56. Name: "nginx",
  57. Image: "gcr.io/google_containers/nginx:1.7.9",
  58. },
  59. },
  60. },
  61. },
  62. },
  63. }
  64. }
  65. // verifyRemainingObjects verifies if the number of the remaining replication
  66. // controllers and pods are rcNum and podNum. It returns error if the
  67. // communication with the API server fails.
  68. func verifyRemainingObjects(f *framework.Framework, clientSet clientset.Interface, rcNum, podNum int) (bool, error) {
  69. rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
  70. pods, err := clientSet.Core().Pods(f.Namespace.Name).List(api.ListOptions{})
  71. if err != nil {
  72. return false, fmt.Errorf("Failed to list pods: %v", err)
  73. }
  74. var ret = true
  75. if len(pods.Items) != podNum {
  76. ret = false
  77. By(fmt.Sprintf("expected %d pods, got %d pods", podNum, len(pods.Items)))
  78. }
  79. rcs, err := rcClient.List(api.ListOptions{})
  80. if err != nil {
  81. return false, fmt.Errorf("Failed to list replication controllers: %v", err)
  82. }
  83. if len(rcs.Items) != rcNum {
  84. ret = false
  85. By(fmt.Sprintf("expected %d RCs, got %d RCs", rcNum, len(rcs.Items)))
  86. }
  87. return ret, nil
  88. }
  89. func gatherMetrics(f *framework.Framework) {
  90. By("Gathering metrics")
  91. var summary framework.TestDataSummary
  92. grabber, err := metrics.NewMetricsGrabber(f.Client, false, false, true, false)
  93. if err != nil {
  94. framework.Logf("Failed to create MetricsGrabber. Skipping metrics gathering.")
  95. } else {
  96. received, err := grabber.Grab()
  97. if err != nil {
  98. framework.Logf("MetricsGrabber failed grab metrics. Skipping metrics gathering.")
  99. } else {
  100. summary = (*framework.MetricsForE2E)(&received)
  101. framework.Logf(summary.PrintHumanReadable())
  102. }
  103. }
  104. }
  105. var _ = framework.KubeDescribe("Garbage collector", func() {
  106. f := framework.NewDefaultFramework("gc")
  107. It("[Feature:GarbageCollector] should delete pods created by rc when not orphaning", func() {
  108. clientSet := f.Clientset_1_3
  109. rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
  110. podClient := clientSet.Core().Pods(f.Namespace.Name)
  111. rcName := "simpletest.rc"
  112. rc := newOwnerRC(f, rcName)
  113. By("create the rc")
  114. rc, err := rcClient.Create(rc)
  115. if err != nil {
  116. framework.Failf("Failed to create replication controller: %v", err)
  117. }
  118. // wait for rc to create some pods
  119. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  120. pods, err := podClient.List(api.ListOptions{})
  121. if err != nil {
  122. return false, fmt.Errorf("Failed to list pods: %v", err)
  123. }
  124. // We intentionally don't wait the number of pods to reach
  125. // rc.Spec.Replicas. We want to see if the garbage collector and the
  126. // rc manager work properly if the rc is deleted before it reaches
  127. // stasis.
  128. if len(pods.Items) > 0 {
  129. return true, nil
  130. } else {
  131. return false, nil
  132. }
  133. }); err != nil {
  134. framework.Failf("failed to wait for the rc to create some pods: %v", err)
  135. }
  136. By("delete the rc")
  137. deleteOptions := getNonOrphanOptions()
  138. deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
  139. if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
  140. framework.Failf("failed to delete the rc: %v", err)
  141. }
  142. By("wait for all pods to be garbage collected")
  143. // wait for the RCs and Pods to reach the expected numbers.
  144. if err := wait.Poll(5*time.Second, 60*time.Second, func() (bool, error) {
  145. return verifyRemainingObjects(f, clientSet, 0, 0)
  146. }); err != nil {
  147. framework.Failf("failed to wait for all pods to be deleted: %v", err)
  148. remainingPods, err := podClient.List(api.ListOptions{})
  149. if err != nil {
  150. framework.Failf("failed to list pods post mortem: %v", err)
  151. } else {
  152. framework.Failf("remaining pods are: %#v", remainingPods)
  153. }
  154. }
  155. gatherMetrics(f)
  156. })
  157. It("[Feature:GarbageCollector] should orphan pods created by rc if delete options say so", func() {
  158. clientSet := f.Clientset_1_3
  159. rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
  160. podClient := clientSet.Core().Pods(f.Namespace.Name)
  161. rcName := "simpletest.rc"
  162. rc := newOwnerRC(f, rcName)
  163. replicas := int32(100)
  164. rc.Spec.Replicas = &replicas
  165. By("create the rc")
  166. rc, err := rcClient.Create(rc)
  167. if err != nil {
  168. framework.Failf("Failed to create replication controller: %v", err)
  169. }
  170. // wait for rc to create pods
  171. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  172. rc, err := rcClient.Get(rc.Name)
  173. if err != nil {
  174. return false, fmt.Errorf("Failed to get rc: %v", err)
  175. }
  176. if rc.Status.Replicas == *rc.Spec.Replicas {
  177. return true, nil
  178. } else {
  179. return false, nil
  180. }
  181. }); err != nil {
  182. framework.Failf("failed to wait for the rc.Status.Replicas to reach rc.Spec.Replicas: %v", err)
  183. }
  184. By("delete the rc")
  185. deleteOptions := getOrphanOptions()
  186. deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
  187. if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
  188. framework.Failf("failed to delete the rc: %v", err)
  189. }
  190. By("wait for the rc to be deleted")
  191. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  192. rcs, err := rcClient.List(api.ListOptions{})
  193. if err != nil {
  194. return false, fmt.Errorf("Failed to list rcs: %v", err)
  195. }
  196. if len(rcs.Items) != 0 {
  197. return false, nil
  198. }
  199. return true, nil
  200. }); err != nil && err != wait.ErrWaitTimeout {
  201. framework.Failf("%v", err)
  202. }
  203. By("wait for 30 seconds to see if the garbage collector mistakenly deletes the pods")
  204. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  205. pods, err := podClient.List(api.ListOptions{})
  206. if err != nil {
  207. return false, fmt.Errorf("Failed to list pods: %v", err)
  208. }
  209. if e, a := int(*(rc.Spec.Replicas)), len(pods.Items); e != a {
  210. return false, fmt.Errorf("expect %d pods, got %d pods", e, a)
  211. }
  212. return false, nil
  213. }); err != nil && err != wait.ErrWaitTimeout {
  214. framework.Failf("%v", err)
  215. }
  216. gatherMetrics(f)
  217. })
  218. It("[Feature:GarbageCollector] should orphan pods created by rc if deleteOptions.OrphanDependents is nil", func() {
  219. clientSet := f.Clientset_1_3
  220. rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
  221. podClient := clientSet.Core().Pods(f.Namespace.Name)
  222. rcName := "simpletest.rc"
  223. rc := newOwnerRC(f, rcName)
  224. By("create the rc")
  225. rc, err := rcClient.Create(rc)
  226. if err != nil {
  227. framework.Failf("Failed to create replication controller: %v", err)
  228. }
  229. // wait for rc to create some pods
  230. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  231. rc, err := rcClient.Get(rc.Name)
  232. if err != nil {
  233. return false, fmt.Errorf("Failed to get rc: %v", err)
  234. }
  235. if rc.Status.Replicas == *rc.Spec.Replicas {
  236. return true, nil
  237. } else {
  238. return false, nil
  239. }
  240. }); err != nil {
  241. framework.Failf("failed to wait for the rc.Status.Replicas to reach rc.Spec.Replicas: %v", err)
  242. }
  243. By("delete the rc")
  244. deleteOptions := &api.DeleteOptions{}
  245. deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
  246. if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
  247. framework.Failf("failed to delete the rc: %v", err)
  248. }
  249. By("wait for 30 seconds to see if the garbage collector mistakenly deletes the pods")
  250. if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
  251. pods, err := podClient.List(api.ListOptions{})
  252. if err != nil {
  253. return false, fmt.Errorf("Failed to list pods: %v", err)
  254. }
  255. if e, a := int(*(rc.Spec.Replicas)), len(pods.Items); e != a {
  256. return false, fmt.Errorf("expect %d pods, got %d pods", e, a)
  257. }
  258. return false, nil
  259. }); err != nil && err != wait.ErrWaitTimeout {
  260. framework.Failf("%v", err)
  261. }
  262. gatherMetrics(f)
  263. })
  264. })