Change:
/kind bug What happened: Services of type LoadBalancer (GCE) with IP addresses promoted to static (by user or by orphan) cause the service controller to panic. The constant panicking will cause a reboot loop of the pod. How to reproduce it (as minimally and precisely as possible): a service on GCP it the GCP Console, promote the IP address of the LB to static and set the name to the loadBalancerName which is the same name as the forwarding rule. Environment: Kubernetes version: 1.7.0 AND 1.7.1 Cloud provider or hardware configuration: GCE Symptoms -controller-manager crash loops on the master. Mitigation** Option 1: Build your own version of branch for the master. Only the kube-controller-manager image needs to be updated. Option 2: For all affected services, set the field to the known external IP address. Steps: list of reserved IPs gcloud compute addresses list NAME REGION ADDRESS STATUS us-central1 35.35.35.35 INUSE list of all Services of type LoadBalancer kubectl get svc --all-namespaces | grep "LoadBalancer" default my-service LoadBalancer 10.0.99.201 35.35.35.35 80:/TCP,443:/TCP 58m each service of type LoadBalancer with an IP that's reserved (in the list above), continue to next step. the service's field equal to the known IP. Example_ apiVersion: v1 kind: Service metadata: creationTimestamp: 2017-07-13T00:09:31Z labels: app: echo name: my-service namespace: default resourceVersion: "" selfLink: /api/v1/namespaces/default/services/my-service uid: -675f-11e7-bee2- spec: clusterIP: 10.0.99.201 externalTrafficPolicy: Cluster loadBalancerIP: 35.35.35.35 <------- Field set to below. ports: name: port-1 nodePort: port: 80 protocol: TCP targetPort: 80 name: port-2 nodePort: port: 443 protocol: TCP targetPort: 443 selector: app: echo sessionAffinity: ClientIP type: LoadBalancer status: loadBalancer: ingress: ip: 35.35.35.35
/sig network /assign /area platform/gce
cc

Discussion:
// Caller is allocated a random IP if they do not specify an ipAddress. If an // ipAddress is specified, it must belong to the current project, eg: an // ephemeral IP associated with a global forwarding rule. <del> func (gce *GCECloud) ReserveGlobalAddress(addr *compute.Address) (*compute.Address, error) { </del> <ins> func (gce *GCECloud) ReserveGlobalAddress(addr *compute.Address) error { </ins> mc := newAddressMetricContext("reserve", "") op, err := gce.service.GlobalAddresses.Insert(gce.projectID, addr).Do() if err != nil { <del> return nil, mc.Observe(err) } if err := gce.waitForGlobalOp(op, mc); err != nil { return nil, err </del> <ins> return mc.Observe(err) </ins> } <del> return gce.GetGlobalAddress(addr.Name) </del> <ins> return gce.waitForGlobalOp(op, mc) </ins> } // DeleteGlobalAddress deletes a global address by name.

} // ReserveRegionAddress creates a region address <del> func (gce *GCECloud) ReserveRegionAddress(addr *compute.Address, region string) (*compute.Address, error) { </del> <ins> func (gce *GCECloud) ReserveRegionAddress(addr *compute.Address, region string) error { </ins> mc := newAddressMetricContext("reserve", region) op, err := gce.service.Addresses.Insert(gce.projectID, region, addr).Do() if err != nil { <del> return nil, mc.Observe(err) } if err := gce.waitForRegionOp(op, region, mc); err != nil { return nil, err </del> <ins> return mc.Observe(err) </ins> } <del> return gce.GetRegionAddress(addr.Name, region) </del> <ins> return gce.waitForRegionOp(op, region, mc) </ins> } // DeleteRegionAddress deletes a region address by name.

addressObj.Address = existingIP } <del> address, err := gce.ReserveRegionAddress(addressObj, region) if err != nil { </del> <ins> if err = gce.ReserveRegionAddress(addressObj, region); err != nil { </ins> if !isHTTPErrorCode(err, http.StatusConflict) { return "", false, fmt.Errorf("error creating gce static IP address: %v", err) }

existed = true } <del> return address.Address, existed, nil </del> <ins> addr, err := gce.GetRegionAddress(name, region) if err != nil { return "", false, fmt.Errorf("error getting static IP address: %v", err) } return addr.Address, existed, nil </ins> }

func (cont *GCEIngressController) CreateStaticIP(name string) string { gceCloud := cont.Cloud.Provider.(*gcecloud.GCECloud) addr := &compute.Address{Name: name} <del> ip, err := gceCloud.ReserveGlobalAddress(addr) if err != nil { </del> <ins> if err := gceCloud.ReserveGlobalAddress(addr); err != nil { </ins> if delErr := gceCloud.DeleteGlobalAddress(name); delErr != nil { if cont.isHTTPErrorCode(delErr, http.StatusNotFound) { Logf("Static ip with name %v was not allocated, nothing to delete", name)

Logf("Failed to delete static ip %v: %v", name, delErr) } } <del> Failf("Failed to allocated static ip %v: %v", name, err) </del> <ins> Failf("Failed to allocate static ip %v: %v", name, err) </ins> } <ins> ip, err := gceCloud.GetGlobalAddress(name) if err != nil { Failf("Failed to get newly created static ip %v: %v", name, err) } </ins> cont.staticIPName = ip.Name Logf("Reserved static ip %v: %v", cont.staticIPName, ip.Address) return ip.Address