runtime_conformance_test.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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_node
  14. import (
  15. "fmt"
  16. "io/ioutil"
  17. "os"
  18. "path/filepath"
  19. "time"
  20. "k8s.io/api/core/v1"
  21. "k8s.io/kubernetes/pkg/kubelet/images"
  22. "k8s.io/kubernetes/test/e2e/common"
  23. "k8s.io/kubernetes/test/e2e/framework"
  24. e2elog "k8s.io/kubernetes/test/e2e/framework/log"
  25. "k8s.io/kubernetes/test/e2e_node/services"
  26. . "github.com/onsi/ginkgo"
  27. . "github.com/onsi/gomega"
  28. )
  29. var _ = framework.KubeDescribe("Container Runtime Conformance Test", func() {
  30. f := framework.NewDefaultFramework("runtime-conformance")
  31. Describe("container runtime conformance blackbox test", func() {
  32. Context("when running a container with a new image", func() {
  33. // The service account only has pull permission
  34. auth := `
  35. {
  36. "auths": {
  37. "https://gcr.io": {
  38. "auth": "X2pzb25fa2V5OnsKICAidHlwZSI6ICJzZXJ2aWNlX2FjY291bnQiLAogICJwcm9qZWN0X2lkIjogImF1dGhlbnRpY2F0ZWQtaW1hZ2UtcHVsbGluZyIsCiAgInByaXZhdGVfa2V5X2lkIjogImI5ZjJhNjY0YWE5YjIwNDg0Y2MxNTg2MDYzZmVmZGExOTIyNGFjM2IiLAogICJwcml2YXRlX2tleSI6ICItLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS1cbk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzdTSG5LVEVFaVlMamZcbkpmQVBHbUozd3JCY2VJNTBKS0xxS21GWE5RL3REWGJRK2g5YVl4aldJTDhEeDBKZTc0bVovS01uV2dYRjVLWlNcbm9BNktuSU85Yi9SY1NlV2VpSXRSekkzL1lYVitPNkNjcmpKSXl4anFWam5mVzJpM3NhMzd0OUE5VEZkbGZycm5cbjR6UkpiOWl4eU1YNGJMdHFGR3ZCMDNOSWl0QTNzVlo1ODhrb1FBZmgzSmhhQmVnTWorWjRSYko0aGVpQlFUMDNcbnZVbzViRWFQZVQ5RE16bHdzZWFQV2dydDZOME9VRGNBRTl4bGNJek11MjUzUG4vSzgySFpydEx4akd2UkhNVXhcbng0ZjhwSnhmQ3h4QlN3Z1NORit3OWpkbXR2b0wwRmE3ZGducFJlODZWRDY2ejNZenJqNHlLRXRqc2hLZHl5VWRcbkl5cVhoN1JSQWdNQkFBRUNnZ0VBT3pzZHdaeENVVlFUeEFka2wvSTVTRFVidi9NazRwaWZxYjJEa2FnbmhFcG9cbjFJajJsNGlWMTByOS9uenJnY2p5VlBBd3pZWk1JeDFBZVF0RDdoUzRHWmFweXZKWUc3NkZpWFpQUm9DVlB6b3VcbmZyOGRDaWFwbDV0enJDOWx2QXNHd29DTTdJWVRjZmNWdDdjRTEyRDNRS3NGNlo3QjJ6ZmdLS251WVBmK0NFNlRcbmNNMHkwaCtYRS9kMERvSERoVy96YU1yWEhqOFRvd2V1eXRrYmJzNGYvOUZqOVBuU2dET1lQd2xhbFZUcitGUWFcbkpSd1ZqVmxYcEZBUW14M0Jyd25rWnQzQ2lXV2lGM2QrSGk5RXRVYnRWclcxYjZnK1JRT0licWFtcis4YlJuZFhcbjZWZ3FCQWtKWjhSVnlkeFVQMGQxMUdqdU9QRHhCbkhCbmM0UW9rSXJFUUtCZ1FEMUNlaWN1ZGhXdGc0K2dTeGJcbnplanh0VjFONDFtZHVjQnpvMmp5b1dHbzNQVDh3ckJPL3lRRTM0cU9WSi9pZCs4SThoWjRvSWh1K0pBMDBzNmdcblRuSXErdi9kL1RFalk4MW5rWmlDa21SUFdiWHhhWXR4UjIxS1BYckxOTlFKS2ttOHRkeVh5UHFsOE1veUdmQ1dcbjJ2aVBKS05iNkhabnY5Q3lqZEo5ZzJMRG5RS0JnUUREcVN2eURtaGViOTIzSW96NGxlZ01SK205Z2xYVWdTS2dcbkVzZlllbVJmbU5XQitDN3ZhSXlVUm1ZNU55TXhmQlZXc3dXRldLYXhjK0krYnFzZmx6elZZdFpwMThNR2pzTURcbmZlZWZBWDZCWk1zVXQ3Qmw3WjlWSjg1bnRFZHFBQ0xwWitaLzN0SVJWdWdDV1pRMWhrbmxHa0dUMDI0SkVFKytcbk55SDFnM2QzUlFLQmdRQ1J2MXdKWkkwbVBsRklva0tGTkh1YTBUcDNLb1JTU1hzTURTVk9NK2xIckcxWHJtRjZcbkMwNGNTKzQ0N0dMUkxHOFVUaEpKbTRxckh0Ti9aK2dZOTYvMm1xYjRIakpORDM3TVhKQnZFYTN5ZUxTOHEvK1JcbjJGOU1LamRRaU5LWnhQcG84VzhOSlREWTVOa1BaZGh4a2pzSHdVNGRTNjZwMVRESUU0MGd0TFpaRFFLQmdGaldcbktyblFpTnEzOS9iNm5QOFJNVGJDUUFKbmR3anhTUU5kQTVmcW1rQTlhRk9HbCtqamsxQ1BWa0tNSWxLSmdEYkpcbk9heDl2OUc2Ui9NSTFIR1hmV3QxWU56VnRocjRIdHNyQTB0U3BsbWhwZ05XRTZWejZuQURqdGZQSnMyZUdqdlhcbmpQUnArdjhjY21MK3dTZzhQTGprM3ZsN2VlNXJsWWxNQndNdUdjUHhBb0dBZWRueGJXMVJMbVZubEFpSEx1L0xcbmxtZkF3RFdtRWlJMFVnK1BMbm9Pdk81dFE1ZDRXMS94RU44bFA0cWtzcGtmZk1Rbk5oNFNZR0VlQlQzMlpxQ1RcbkpSZ2YwWGpveXZ2dXA5eFhqTWtYcnBZL3ljMXpmcVRaQzBNTzkvMVVjMWJSR2RaMmR5M2xSNU5XYXA3T1h5Zk9cblBQcE5Gb1BUWGd2M3FDcW5sTEhyR3pNPVxuLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLVxuIiwKICAiY2xpZW50X2VtYWlsIjogImltYWdlLXB1bGxpbmdAYXV0aGVudGljYXRlZC1pbWFnZS1wdWxsaW5nLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwKICAiY2xpZW50X2lkIjogIjExMzc5NzkxNDUzMDA3MzI3ODcxMiIsCiAgImF1dGhfdXJpIjogImh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi9hdXRoIiwKICAidG9rZW5fdXJpIjogImh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsCiAgImF1dGhfcHJvdmlkZXJfeDUwOV9jZXJ0X3VybCI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9vYXV0aDIvdjEvY2VydHMiLAogICJjbGllbnRfeDUwOV9jZXJ0X3VybCI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9yb2JvdC92MS9tZXRhZGF0YS94NTA5L2ltYWdlLXB1bGxpbmclNDBhdXRoZW50aWNhdGVkLWltYWdlLXB1bGxpbmcuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iCn0=",
  39. "email": "image-pulling@authenticated-image-pulling.iam.gserviceaccount.com"
  40. }
  41. }
  42. }`
  43. // The following images are not added into NodeImageWhiteList, because this test is
  44. // testing image pulling, these images don't need to be prepulled. The ImagePullPolicy
  45. // is v1.PullAlways, so it won't be blocked by framework image white list check.
  46. for _, testCase := range []struct {
  47. description string
  48. image string
  49. phase v1.PodPhase
  50. waiting bool
  51. }{
  52. {
  53. description: "should be able to pull from private registry with credential provider",
  54. image: "gcr.io/authenticated-image-pulling/alpine:3.7",
  55. phase: v1.PodRunning,
  56. waiting: false,
  57. },
  58. } {
  59. testCase := testCase
  60. It(testCase.description+" [NodeConformance]", func() {
  61. name := "image-pull-test"
  62. command := []string{"/bin/sh", "-c", "while true; do sleep 1; done"}
  63. container := common.ConformanceContainer{
  64. PodClient: f.PodClient(),
  65. Container: v1.Container{
  66. Name: name,
  67. Image: testCase.image,
  68. Command: command,
  69. // PullAlways makes sure that the image will always be pulled even if it is present before the test.
  70. ImagePullPolicy: v1.PullAlways,
  71. },
  72. RestartPolicy: v1.RestartPolicyNever,
  73. }
  74. configFile := filepath.Join(services.KubeletRootDirectory, "config.json")
  75. err := ioutil.WriteFile(configFile, []byte(auth), 0644)
  76. Expect(err).NotTo(HaveOccurred())
  77. defer os.Remove(configFile)
  78. // checkContainerStatus checks whether the container status matches expectation.
  79. checkContainerStatus := func() error {
  80. status, err := container.GetStatus()
  81. if err != nil {
  82. return fmt.Errorf("failed to get container status: %v", err)
  83. }
  84. // We need to check container state first. The default pod status is pending, If we check
  85. // pod phase first, and the expected pod phase is Pending, the container status may not
  86. // even show up when we check it.
  87. // Check container state
  88. if !testCase.waiting {
  89. if status.State.Running == nil {
  90. return fmt.Errorf("expected container state: Running, got: %q",
  91. common.GetContainerState(status.State))
  92. }
  93. }
  94. if testCase.waiting {
  95. if status.State.Waiting == nil {
  96. return fmt.Errorf("expected container state: Waiting, got: %q",
  97. common.GetContainerState(status.State))
  98. }
  99. reason := status.State.Waiting.Reason
  100. if reason != images.ErrImagePull.Error() &&
  101. reason != images.ErrImagePullBackOff.Error() {
  102. return fmt.Errorf("unexpected waiting reason: %q", reason)
  103. }
  104. }
  105. // Check pod phase
  106. phase, err := container.GetPhase()
  107. if err != nil {
  108. return fmt.Errorf("failed to get pod phase: %v", err)
  109. }
  110. if phase != testCase.phase {
  111. return fmt.Errorf("expected pod phase: %q, got: %q", testCase.phase, phase)
  112. }
  113. return nil
  114. }
  115. // The image registry is not stable, which sometimes causes the test to fail. Add retry mechanism to make this
  116. // less flaky.
  117. const flakeRetry = 3
  118. for i := 1; i <= flakeRetry; i++ {
  119. var err error
  120. By("create the container")
  121. container.Create()
  122. By("check the container status")
  123. for start := time.Now(); time.Since(start) < common.ContainerStatusRetryTimeout; time.Sleep(common.ContainerStatusPollInterval) {
  124. if err = checkContainerStatus(); err == nil {
  125. break
  126. }
  127. }
  128. By("delete the container")
  129. container.Delete()
  130. if err == nil {
  131. break
  132. }
  133. if i < flakeRetry {
  134. e2elog.Logf("No.%d attempt failed: %v, retrying...", i, err)
  135. } else {
  136. framework.Failf("All %d attempts failed: %v", flakeRetry, err)
  137. }
  138. }
  139. })
  140. }
  141. })
  142. })
  143. })