services.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. Copyright 2017 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 upgrades
  14. import (
  15. v1 "k8s.io/api/core/v1"
  16. "k8s.io/apimachinery/pkg/util/wait"
  17. "k8s.io/kubernetes/test/e2e/framework"
  18. "github.com/onsi/ginkgo"
  19. )
  20. // ServiceUpgradeTest tests that a service is available before and
  21. // after a cluster upgrade. During a master-only upgrade, it will test
  22. // that a service remains available during the upgrade.
  23. type ServiceUpgradeTest struct {
  24. jig *framework.ServiceTestJig
  25. tcpService *v1.Service
  26. tcpIngressIP string
  27. svcPort int
  28. }
  29. // Name returns the tracking name of the test.
  30. func (ServiceUpgradeTest) Name() string { return "service-upgrade" }
  31. func shouldTestPDBs() bool { return framework.ProviderIs("gce", "gke") }
  32. // Setup creates a service with a load balancer and makes sure it's reachable.
  33. func (t *ServiceUpgradeTest) Setup(f *framework.Framework) {
  34. serviceName := "service-test"
  35. jig := framework.NewServiceTestJig(f.ClientSet, serviceName)
  36. ns := f.Namespace
  37. ginkgo.By("creating a TCP service " + serviceName + " with type=LoadBalancer in namespace " + ns.Name)
  38. tcpService := jig.CreateTCPServiceOrFail(ns.Name, func(s *v1.Service) {
  39. s.Spec.Type = v1.ServiceTypeLoadBalancer
  40. })
  41. tcpService = jig.WaitForLoadBalancerOrFail(ns.Name, tcpService.Name, framework.LoadBalancerCreateTimeoutDefault)
  42. jig.SanityCheckService(tcpService, v1.ServiceTypeLoadBalancer)
  43. // Get info to hit it with
  44. tcpIngressIP := framework.GetIngressPoint(&tcpService.Status.LoadBalancer.Ingress[0])
  45. svcPort := int(tcpService.Spec.Ports[0].Port)
  46. ginkgo.By("creating pod to be part of service " + serviceName)
  47. rc := jig.RunOrFail(ns.Name, jig.AddRCAntiAffinity)
  48. if shouldTestPDBs() {
  49. ginkgo.By("creating a PodDisruptionBudget to cover the ReplicationController")
  50. jig.CreatePDBOrFail(ns.Name, rc)
  51. }
  52. // Hit it once before considering ourselves ready
  53. ginkgo.By("hitting the pod through the service's LoadBalancer")
  54. jig.TestReachableHTTP(tcpIngressIP, svcPort, framework.LoadBalancerLagTimeoutDefault)
  55. t.jig = jig
  56. t.tcpService = tcpService
  57. t.tcpIngressIP = tcpIngressIP
  58. t.svcPort = svcPort
  59. }
  60. // Test runs a connectivity check to the service.
  61. func (t *ServiceUpgradeTest) Test(f *framework.Framework, done <-chan struct{}, upgrade UpgradeType) {
  62. switch upgrade {
  63. case MasterUpgrade, ClusterUpgrade:
  64. t.test(f, done, true)
  65. case NodeUpgrade:
  66. // Node upgrades should test during disruption only on GCE/GKE for now.
  67. t.test(f, done, shouldTestPDBs())
  68. default:
  69. t.test(f, done, false)
  70. }
  71. }
  72. // Teardown cleans up any remaining resources.
  73. func (t *ServiceUpgradeTest) Teardown(f *framework.Framework) {
  74. // rely on the namespace deletion to clean up everything
  75. }
  76. func (t *ServiceUpgradeTest) test(f *framework.Framework, done <-chan struct{}, testDuringDisruption bool) {
  77. if testDuringDisruption {
  78. // Continuous validation
  79. ginkgo.By("continuously hitting the pod through the service's LoadBalancer")
  80. wait.Until(func() {
  81. t.jig.TestReachableHTTP(t.tcpIngressIP, t.svcPort, framework.LoadBalancerLagTimeoutDefault)
  82. }, framework.Poll, done)
  83. } else {
  84. // Block until upgrade is done
  85. ginkgo.By("waiting for upgrade to finish without checking if service remains up")
  86. <-done
  87. }
  88. // Sanity check and hit it once more
  89. ginkgo.By("hitting the pod through the service's LoadBalancer")
  90. t.jig.TestReachableHTTP(t.tcpIngressIP, t.svcPort, framework.LoadBalancerLagTimeoutDefault)
  91. t.jig.SanityCheckService(t.tcpService, v1.ServiceTypeLoadBalancer)
  92. }