From a71abdc36df866557d14ce083766d85e7a1d84bf Mon Sep 17 00:00:00 2001 From: bprashanth Date: Wed, 9 Nov 2016 11:55:15 -0800 Subject: [PATCH] Ensure health check exists before creating target pool --- pkg/cloudprovider/providers/gce/gce.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/cloudprovider/providers/gce/gce.go b/pkg/cloudprovider/providers/gce/gce.go index 126feec37d9..c56dd43b6b0 100644 --- a/pkg/cloudprovider/providers/gce/gce.go +++ b/pkg/cloudprovider/providers/gce/gce.go @@ -608,6 +608,8 @@ func (gce *GCECloud) EnsureLoadBalancer(clusterName string, apiService *api.Serv // an IP, we assume they are managing it themselves. Otherwise, we will // release the IP in case of early-terminating failure or upon successful // creating of the LB. + // TODO(#36535): boil this logic down into a set of component functions + // and key the flag values off of errors returned. isUserOwnedIP := false // if this is set, we never release the IP isSafeToReleaseIP := false defer func() { @@ -735,7 +737,7 @@ func (gce *GCECloud) EnsureLoadBalancer(clusterName string, apiService *api.Serv return nil, fmt.Errorf("Error checking HTTP health check %s: %v", loadBalancerName, err) } if path, healthCheckNodePort := apiservice.GetServiceHealthCheckPathPort(apiService); path != "" { - glog.V(4).Infof("service %v needs health checks on :%d/%s)", apiService.Name, healthCheckNodePort, path) + glog.V(4).Infof("service %v (%v) needs health checks on :%d%s)", apiService.Name, loadBalancerName, healthCheckNodePort, path) if err != nil { // This logic exists to detect a transition for a pre-existing service and turn on // the tpNeedsUpdate flag to delete/recreate fwdrule/tpool adding the health check @@ -1080,13 +1082,18 @@ func (gce *GCECloud) createTargetPool(name, serviceName, region string, hosts [] for _, host := range hosts { instances = append(instances, makeHostURL(gce.projectID, host.Zone, host.Name)) } + // health check management is coupled with targetPools to prevent leaks. A + // target pool is the only thing that requires a health check, so we delete + // associated checks on teardown, and ensure checks on setup. hcLinks := []string{} if hc != nil { + var err error + if hc, err = gce.ensureHttpHealthCheck(name, hc.RequestPath, int32(hc.Port)); err != nil || hc == nil { + return fmt.Errorf("Failed to ensure health check for %v port %d path %v: %v", name, hc.Port, hc.RequestPath, err) + } hcLinks = append(hcLinks, hc.SelfLink) } - if len(hcLinks) > 0 { - glog.Infof("Creating targetpool %v with healthchecking", name) - } + glog.Infof("Creating targetpool %v with %d healthchecks", name, len(hcLinks)) pool := &compute.TargetPool{ Name: name, Description: fmt.Sprintf(`{"kubernetes.io/service-name":"%s"}`, serviceName),