Exemplo n.º 1
0
func (e *NetworkController) updateLoadBalancer(service *api.Service, lb *networkprovider.LoadBalancer) (*api.LoadBalancerStatus, error) {
	loadBalancerFullName := networkprovider.BuildLoadBalancerName(service.Name, service.Namespace)

	newHosts, _ := e.getEndpointHosts(service)
	if len(newHosts) == 0 {
		glog.V(4).Infof("NetworkController: no endpoints on service %s", service.Name)
		return nil, nil
	}

	if e.hostPortsEqual(lb.Hosts, newHosts) {
		return nil, nil
	}

	vip, err := e.netProvider.LoadBalancers().UpdateLoadBalancer(loadBalancerFullName, newHosts, service.Spec.ExternalIPs)
	if err != nil {
		glog.Errorf("NetworkController: couldn't update loadlbalancer %s:%v", loadBalancerFullName, err)
		return nil, err
	}

	glog.V(4).Infof("NetworkController: loadbalancer %s (vip: %s) updated", loadBalancerFullName, vip)

	status := &api.LoadBalancerStatus{}
	status.Ingress = []api.LoadBalancerIngress{{IP: vip}}
	return status, nil
}
Exemplo n.º 2
0
func (e *NetworkController) createLoadBalancer(service *api.Service) (*api.LoadBalancerStatus, error) {
	newHosts, _ := e.getEndpointHosts(service)
	if len(newHosts) == 0 {
		glog.V(4).Infof("NetworkController: no endpoints on service %s", service.Name)
		return nil, nil
	}

	// get namespace of svc
	namespace, err := e.client.Namespaces().Get(service.Namespace)
	if err != nil {
		glog.Errorf("NetworkController: couldn't get namespace for service %s: %v", service.Name, err)
		return nil, err
	}
	if namespace.Spec.Network == "" {
		glog.Warningf("NetworkController: there is no network associated with namespace %s", namespace.Name)
		return nil, nil
	}

	// get network of namespace
	network, err := e.client.Networks().Get(namespace.Spec.Network)
	if err != nil {
		glog.Errorf("NetworkController: couldn't get network for namespace %s: %v", namespace.Name, err)
		return nil, err
	}

	var networkInfo *networkprovider.Network
	if network.Spec.ProviderNetworkID != "" {
		networkInfo, err = e.netProvider.Networks().GetNetworkByID(network.Spec.ProviderNetworkID)
	} else {
		networkName := networkprovider.BuildNetworkName(network.Name, network.Tenant)
		networkInfo, err = e.netProvider.Networks().GetNetwork(networkName)
	}
	if err != nil {
		glog.Errorf("NetworkController: couldn't get network from networkprovider: %v", err)
		return nil, err
	}

	// create loadbalancer for service
	loadBalancerFullName := networkprovider.BuildLoadBalancerName(service.Name, service.Namespace)
	providerLoadBalancer := networkprovider.LoadBalancer{
		Name: loadBalancerFullName,
		// TODO: support more loadbalancer type
		Type:        networkprovider.LoadBalancerTypeTCP,
		TenantID:    networkInfo.TenantID,
		Subnets:     networkInfo.Subnets,
		Hosts:       newHosts,
		ExternalIPs: service.Spec.ExternalIPs,
	}

	vip, err := e.netProvider.LoadBalancers().CreateLoadBalancer(&providerLoadBalancer, service.Spec.SessionAffinity)
	if err != nil {
		glog.Errorf("NetworkController: create load balancer %s failed: %v", loadBalancerFullName, err)
		return nil, err
	}

	glog.V(4).Infof("NetworkController: load balancer for service %s created", service.Name)

	status := &api.LoadBalancerStatus{}
	status.Ingress = []api.LoadBalancerIngress{{IP: vip}}
	return status, nil
}
Exemplo n.º 3
0
func (e *NetworkController) syncService(key string) {
	glog.V(4).Infof("NetworkController: processing service %v", key)

	obj, exists, err := e.serviceStore.Store.GetByKey(key)
	if err != nil || !exists {
		// Delete the corresponding loadbalancer, as the service has been deleted.
		namespace, name, err := cache.SplitMetaNamespaceKey(key)
		if err != nil {
			glog.Errorf("NetworkController: couldn't understand the key %s: %v", key, err)
			return
		}

		loadBalancerFullName := networkprovider.BuildLoadBalancerName(name, namespace)
		deleteError := e.netProvider.LoadBalancers().DeleteLoadBalancer(loadBalancerFullName)
		if deleteError != nil {
			glog.Errorf("NetworkController: delete loadbalancer %s failed: %v", loadBalancerFullName, err)
		}

		return
	}

	service := obj.(*api.Service)
	if service.Spec.Selector == nil {
		// services without a selector receive no endpoints from this controller;
		// these services will receive the endpoints that are created out-of-band via the REST API.
		return
	}

	// check if loadbalancer already created
	loadBalanerShouldExist := !(len(service.Spec.ExternalIPs) == 0)
	var status *api.LoadBalancerStatus
	loadBalancerFullName := networkprovider.BuildLoadBalancerName(service.Name, service.Namespace)
	loadBalancer, err := e.netProvider.LoadBalancers().GetLoadBalancer(loadBalancerFullName)
	if err != nil && err.Error() == networkprovider.ErrNotFound.Error() {
		if loadBalanerShouldExist {
			// create new loadbalancer
			status, _ = e.createLoadBalancer(service)
		}
	} else if err != nil {
		glog.Errorf("NetworkController: couldn't get loadbalancer from networkprovider: %v", err)
		return
	} else {
		if loadBalanerShouldExist {
			// update loadbalancer
			status, _ = e.updateLoadBalancer(service, loadBalancer)
		} else {
			// delete loadbalancer
			deleteError := e.netProvider.LoadBalancers().DeleteLoadBalancer(loadBalancerFullName)
			if deleteError != nil {
				glog.Errorf("NetworkController: delete loadbalancer %s failed: %v", loadBalancerFullName, err)
			}
		}

	}

	if status != nil {
		service.Status.LoadBalancer = *status
		err := e.updateService(service)
		if err != nil {
			e.eventRecorder.Event(service, "created loadbalancer", "created loadbalancer")
		}
	}
}