mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 15:25:57 +00:00
Merge pull request #11077 from krousey/service_flake
Adding retry logic around service updates
This commit is contained in:
commit
3452748de9
@ -26,6 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
@ -370,8 +371,9 @@ var _ = Describe("Services", func() {
|
|||||||
t.CreateWebserverRC(1)
|
t.CreateWebserverRC(1)
|
||||||
|
|
||||||
By("changing service " + serviceName + " to type=NodePort")
|
By("changing service " + serviceName + " to type=NodePort")
|
||||||
service.Spec.Type = api.ServiceTypeNodePort
|
service, err = updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
service, err = c.Services(ns).Update(service)
|
s.Spec.Type = api.ServiceTypeNodePort
|
||||||
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
if service.Spec.Type != api.ServiceTypeNodePort {
|
if service.Spec.Type != api.ServiceTypeNodePort {
|
||||||
@ -398,7 +400,9 @@ var _ = Describe("Services", func() {
|
|||||||
|
|
||||||
By("changing service " + serviceName + " to type=LoadBalancer")
|
By("changing service " + serviceName + " to type=LoadBalancer")
|
||||||
service.Spec.Type = api.ServiceTypeLoadBalancer
|
service.Spec.Type = api.ServiceTypeLoadBalancer
|
||||||
service, err = c.Services(ns).Update(service)
|
service, err = updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
|
s.Spec.Type = api.ServiceTypeLoadBalancer
|
||||||
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// Wait for the load balancer to be created asynchronously
|
// Wait for the load balancer to be created asynchronously
|
||||||
@ -434,8 +438,9 @@ var _ = Describe("Services", func() {
|
|||||||
//Check for (unlikely) assignment at bottom of range
|
//Check for (unlikely) assignment at bottom of range
|
||||||
nodePort2 = nodePort1 + 1
|
nodePort2 = nodePort1 + 1
|
||||||
}
|
}
|
||||||
service.Spec.Ports[0].NodePort = nodePort2
|
service, err = updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
service, err = c.Services(ns).Update(service)
|
s.Spec.Ports[0].NodePort = nodePort2
|
||||||
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
if service.Spec.Type != api.ServiceTypeLoadBalancer {
|
if service.Spec.Type != api.ServiceTypeLoadBalancer {
|
||||||
@ -463,9 +468,10 @@ var _ = Describe("Services", func() {
|
|||||||
testNotReachable(ip, nodePort1)
|
testNotReachable(ip, nodePort1)
|
||||||
|
|
||||||
By("changing service " + serviceName + " back to type=ClusterIP")
|
By("changing service " + serviceName + " back to type=ClusterIP")
|
||||||
service.Spec.Type = api.ServiceTypeClusterIP
|
service, err = updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
service.Spec.Ports[0].NodePort = 0
|
s.Spec.Type = api.ServiceTypeClusterIP
|
||||||
service, err = c.Services(ns).Update(service)
|
s.Spec.Ports[0].NodePort = 0
|
||||||
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
if service.Spec.Type != api.ServiceTypeClusterIP {
|
if service.Spec.Type != api.ServiceTypeClusterIP {
|
||||||
@ -552,8 +558,9 @@ var _ = Describe("Services", func() {
|
|||||||
testLoadBalancerReachable(ingress, 80)
|
testLoadBalancerReachable(ingress, 80)
|
||||||
|
|
||||||
By("changing service " + serviceName + " to type=NodePort")
|
By("changing service " + serviceName + " to type=NodePort")
|
||||||
service.Spec.Type = api.ServiceTypeNodePort
|
service, err = updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
service, err = c.Services(ns).Update(service)
|
s.Spec.Type = api.ServiceTypeNodePort
|
||||||
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
if service.Spec.Type != api.ServiceTypeNodePort {
|
if service.Spec.Type != api.ServiceTypeNodePort {
|
||||||
@ -678,8 +685,9 @@ var _ = Describe("Services", func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
By(fmt.Sprintf("changing service "+serviceName+" to out-of-range NodePort %d", outOfRangeNodePort))
|
By(fmt.Sprintf("changing service "+serviceName+" to out-of-range NodePort %d", outOfRangeNodePort))
|
||||||
service.Spec.Ports[0].NodePort = outOfRangeNodePort
|
result, err := updateService(c, ns, serviceName, func(s *api.Service) {
|
||||||
result, err := t.Client.Services(t.Namespace).Update(service)
|
s.Spec.Ports[0].NodePort = outOfRangeNodePort
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
Failf("failed to prevent update of service with out-of-range NodePort: %v", result)
|
Failf("failed to prevent update of service with out-of-range NodePort: %v", result)
|
||||||
}
|
}
|
||||||
@ -801,6 +809,29 @@ var _ = Describe("Services", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// updateService fetches a service, calls the update function on it,
|
||||||
|
// and then attempts to send the updated service. It retries up to 2
|
||||||
|
// times in the face of timeouts and conflicts.
|
||||||
|
func updateService(c *client.Client, namespace, serviceName string, update func(*api.Service)) (*api.Service, error) {
|
||||||
|
var service *api.Service
|
||||||
|
var err error
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
service, err = c.Services(namespace).Get(serviceName)
|
||||||
|
if err != nil {
|
||||||
|
return service, err
|
||||||
|
}
|
||||||
|
|
||||||
|
update(service)
|
||||||
|
|
||||||
|
service, err = c.Services(namespace).Update(service)
|
||||||
|
|
||||||
|
if !errors.IsConflict(err) && !errors.IsServerTimeout(err) {
|
||||||
|
return service, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return service, err
|
||||||
|
}
|
||||||
|
|
||||||
func waitForLoadBalancerIngress(c *client.Client, serviceName, namespace string) (*api.Service, error) {
|
func waitForLoadBalancerIngress(c *client.Client, serviceName, namespace string) (*api.Service, error) {
|
||||||
// TODO: once support ticket 21807001 is resolved, reduce this timeout back to something reasonable
|
// TODO: once support ticket 21807001 is resolved, reduce this timeout back to something reasonable
|
||||||
const timeout = 20 * time.Minute
|
const timeout = 20 * time.Minute
|
||||||
|
Loading…
Reference in New Issue
Block a user