// reconcileExternalServices updates balancers for external services, so that they will match the nodes given. // Returns true if something went wrong and we should call reconcile again. func (nc *NodeController) reconcileExternalServices(nodes *api.NodeList) (shouldRetry bool) { balancer, ok := nc.cloud.TCPLoadBalancer() if !ok { glog.Error("The cloud provider does not support external TCP load balancers.") return false } zones, ok := nc.cloud.Zones() if !ok { glog.Error("The cloud provider does not support zone enumeration.") return false } zone, err := zones.GetZone() if err != nil { glog.Errorf("Error while getting zone: %v", err) return false } hosts := []string{} for _, node := range nodes.Items { hosts = append(hosts, node.Name) } services, err := nc.kubeClient.Services(api.NamespaceAll).List(labels.Everything()) if err != nil { glog.Errorf("Error while listing services: %v", err) return true } shouldRetry = false for _, service := range services.Items { if service.Spec.CreateExternalLoadBalancer { nonTCPPort := false for i := range service.Spec.Ports { if service.Spec.Ports[i].Protocol != api.ProtocolTCP { nonTCPPort = true break } } if nonTCPPort { // TODO: Support UDP here. glog.Errorf("External load balancers for non TCP services are not currently supported: %v.", service) continue } name := cloudprovider.GetLoadBalancerName(&service) err := balancer.UpdateTCPLoadBalancer(name, zone.Region, hosts) if err != nil { glog.Errorf("External error while updating TCP load balancer: %v.", err) shouldRetry = true } } } return shouldRetry }
// Updates the external load balancer of a service, assuming we hold the mutex // associated with the service. func (s *ServiceController) lockedUpdateLoadBalancerHosts(service *api.Service, hosts []string) error { if !wantsExternalLoadBalancer(service) { return nil } name := cloudprovider.GetLoadBalancerName(service) err := s.balancer.UpdateTCPLoadBalancer(name, s.zone.Region, hosts) if err == nil { return nil } // It's only an actual error if the load balancer still exists. if _, exists, err := s.balancer.GetTCPLoadBalancer(name, s.zone.Region); err != nil { glog.Errorf("External error while checking if TCP load balancer %q exists: name, %v") } else if !exists { return nil } return err }
func (s *ServiceController) loadBalancerName(service *api.Service) string { return cloudprovider.GetLoadBalancerName(service) }