Add weighted round robin load balancer on TCP
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
8e18d37b3d
commit
685c6dc00c
33 changed files with 787 additions and 239 deletions
|
@ -49,9 +49,16 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client
|
|||
continue
|
||||
}
|
||||
|
||||
var allServers []dynamic.TCPServer
|
||||
key, err := makeServiceKey(route.Match, ingressName)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
serviceName := makeID(ingressRouteTCP.Namespace, key)
|
||||
|
||||
for _, service := range route.Services {
|
||||
servers, err := loadTCPServers(client, ingressRouteTCP.Namespace, service)
|
||||
balancerServerTCP, err := createLoadBalancerServerTCP(client, ingressRouteTCP.Namespace, service)
|
||||
if err != nil {
|
||||
logger.
|
||||
WithField("serviceName", service.Name).
|
||||
|
@ -60,16 +67,28 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client
|
|||
continue
|
||||
}
|
||||
|
||||
allServers = append(allServers, servers...)
|
||||
// If there is only one service defined, we skip the creation of the load balancer of services,
|
||||
// i.e. the service on top is directly a load balancer of servers.
|
||||
if len(route.Services) == 1 {
|
||||
conf.Services[serviceName] = balancerServerTCP
|
||||
break
|
||||
}
|
||||
|
||||
serviceKey := fmt.Sprintf("%s-%s-%d", serviceName, service.Name, service.Port)
|
||||
conf.Services[serviceKey] = balancerServerTCP
|
||||
|
||||
srv := dynamic.TCPWRRService{Name: serviceKey}
|
||||
srv.SetDefaults()
|
||||
if service.Weight != nil {
|
||||
srv.Weight = service.Weight
|
||||
}
|
||||
|
||||
if conf.Services[serviceName] == nil {
|
||||
conf.Services[serviceName] = &dynamic.TCPService{Weighted: &dynamic.TCPWeightedRoundRobin{}}
|
||||
}
|
||||
conf.Services[serviceName].Weighted.Services = append(conf.Services[serviceName].Weighted.Services, srv)
|
||||
}
|
||||
|
||||
key, e := makeServiceKey(route.Match, ingressName)
|
||||
if e != nil {
|
||||
logger.Error(e)
|
||||
continue
|
||||
}
|
||||
|
||||
serviceName := makeID(ingressRouteTCP.Namespace, key)
|
||||
conf.Routers[serviceName] = &dynamic.TCPRouter{
|
||||
EntryPoints: ingressRouteTCP.Spec.EntryPoints,
|
||||
Rule: route.Match,
|
||||
|
@ -83,37 +102,53 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client
|
|||
Domains: ingressRouteTCP.Spec.TLS.Domains,
|
||||
}
|
||||
|
||||
if ingressRouteTCP.Spec.TLS.Options != nil && len(ingressRouteTCP.Spec.TLS.Options.Name) > 0 {
|
||||
tlsOptionsName := ingressRouteTCP.Spec.TLS.Options.Name
|
||||
// Is a Kubernetes CRD reference (i.e. not a cross-provider reference)
|
||||
ns := ingressRouteTCP.Spec.TLS.Options.Namespace
|
||||
if !strings.Contains(tlsOptionsName, "@") {
|
||||
if len(ns) == 0 {
|
||||
ns = ingressRouteTCP.Namespace
|
||||
}
|
||||
tlsOptionsName = makeID(ns, tlsOptionsName)
|
||||
} else if len(ns) > 0 {
|
||||
logger.
|
||||
WithField("TLSoptions", ingressRouteTCP.Spec.TLS.Options.Name).
|
||||
Warnf("namespace %q is ignored in cross-provider context", ns)
|
||||
}
|
||||
|
||||
conf.Routers[serviceName].TLS.Options = tlsOptionsName
|
||||
|
||||
if ingressRouteTCP.Spec.TLS.Options == nil || len(ingressRouteTCP.Spec.TLS.Options.Name) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
tlsOptionsName := ingressRouteTCP.Spec.TLS.Options.Name
|
||||
// Is a Kubernetes CRD reference (i.e. not a cross-provider reference)
|
||||
ns := ingressRouteTCP.Spec.TLS.Options.Namespace
|
||||
if !strings.Contains(tlsOptionsName, "@") {
|
||||
if len(ns) == 0 {
|
||||
ns = ingressRouteTCP.Namespace
|
||||
}
|
||||
tlsOptionsName = makeID(ns, tlsOptionsName)
|
||||
} else if len(ns) > 0 {
|
||||
logger.
|
||||
WithField("TLSoptions", ingressRouteTCP.Spec.TLS.Options.Name).
|
||||
Warnf("namespace %q is ignored in cross-provider context", ns)
|
||||
}
|
||||
|
||||
conf.Routers[serviceName].TLS.Options = tlsOptionsName
|
||||
|
||||
}
|
||||
|
||||
conf.Services[serviceName] = &dynamic.TCPService{
|
||||
LoadBalancer: &dynamic.TCPLoadBalancerService{
|
||||
Servers: allServers,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conf
|
||||
}
|
||||
|
||||
func createLoadBalancerServerTCP(client Client, namespace string, service v1alpha1.ServiceTCP) (*dynamic.TCPService, error) {
|
||||
servers, err := loadTCPServers(client, namespace, service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tcpService := &dynamic.TCPService{
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
||||
Servers: servers,
|
||||
},
|
||||
}
|
||||
|
||||
if service.TerminationDelay != nil {
|
||||
tcpService.LoadBalancer.TerminationDelay = service.TerminationDelay
|
||||
}
|
||||
|
||||
return tcpService, nil
|
||||
}
|
||||
|
||||
func loadTCPServers(client Client, namespace string, svc v1alpha1.ServiceTCP) ([]dynamic.TCPServer, error) {
|
||||
service, exists, err := client.GetService(namespace, svc.Name)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue