Skip to content

Commit d13339c

Browse files
authored
IPVS sync services performnce improvement (#253)
During periodic sync of IPVS services there is a check if the required service already existing in IPVS. For the check the list of currnet IPVS services are read from IPVS. This is causing performance hit as number of services increases. With this fix, Kube-router reads once from ipvs and use for further during service sync
1 parent 38e3082 commit d13339c

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

app/controllers/network_services_controller.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ type externalIPService struct {
238238
// as learned from services and endpoints information from the api server
239239
func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInfoMap, endpointsInfoMap endpointsInfoMap) error {
240240

241+
var ipvsSvcs []*ipvs.Service
241242
start := time.Now()
242243
defer func() {
243244
glog.Infof("sync ipvs servers took %v", time.Since(start))
@@ -266,6 +267,11 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
266267
// map of active services and service endpoints
267268
activeServiceEndpointMap := make(map[string][]string)
268269

270+
ipvsSvcs, err = h.GetServices()
271+
if err != nil {
272+
return errors.New("Failed get list of IPVS services due to: " + err.Error())
273+
}
274+
269275
for k, svc := range serviceInfoMap {
270276
var protocol uint16
271277
if svc.protocol == "tcp" {
@@ -283,7 +289,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
283289
}
284290

285291
// create IPVS service for the service to be exposed through the cluster ip
286-
ipvsClusterVipSvc, err := ipvsAddService(svc.clusterIP, protocol, uint16(svc.port), svc.sessionAffinity, svc.scheduler)
292+
ipvsClusterVipSvc, err := ipvsAddService(ipvsSvcs, svc.clusterIP, protocol, uint16(svc.port), svc.sessionAffinity, svc.scheduler)
287293
if err != nil {
288294
glog.Errorf("Failed to create ipvs service for cluster ip: %s", err.Error())
289295
continue
@@ -315,7 +321,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
315321
nodeServiceIds = make([]string, len(addrs))
316322

317323
for i, addr := range addrs {
318-
ipvsNodeportSvcs[i], err = ipvsAddService(addr.IP, protocol, uint16(svc.nodePort), svc.sessionAffinity, svc.scheduler)
324+
ipvsNodeportSvcs[i], err = ipvsAddService(ipvsSvcs, addr.IP, protocol, uint16(svc.nodePort), svc.sessionAffinity, svc.scheduler)
319325
if err != nil {
320326
glog.Errorf("Failed to create ipvs service for node port due to: %s", err.Error())
321327
continue
@@ -326,7 +332,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
326332
}
327333
} else {
328334
ipvsNodeportSvcs = make([]*ipvs.Service, 1)
329-
ipvsNodeportSvcs[0], err = ipvsAddService(nsc.nodeIP, protocol, uint16(svc.nodePort), svc.sessionAffinity, svc.scheduler)
335+
ipvsNodeportSvcs[0], err = ipvsAddService(ipvsSvcs, nsc.nodeIP, protocol, uint16(svc.nodePort), svc.sessionAffinity, svc.scheduler)
330336
if err != nil {
331337
glog.Errorf("Failed to create ipvs service for node port due to: %s", err.Error())
332338
continue
@@ -388,7 +394,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
388394
}
389395

390396
// create IPVS service for the service to be exposed through the external ip
391-
ipvsExternalIPSvc, err := ipvsAddService(net.ParseIP(externalIP), protocol, uint16(svc.port), svc.sessionAffinity, svc.scheduler)
397+
ipvsExternalIPSvc, err := ipvsAddService(ipvsSvcs, net.ParseIP(externalIP), protocol, uint16(svc.port), svc.sessionAffinity, svc.scheduler)
392398
if err != nil {
393399
glog.Errorf("Failed to create ipvs service for external ip: %s due to %s", externalIP, err.Error())
394400
continue
@@ -484,7 +490,8 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
484490

485491
// cleanup stale ipvs service and servers
486492
glog.Infof("Cleaning up if any, old ipvs service and servers which are no longer needed")
487-
ipvsSvcs, err := h.GetServices()
493+
ipvsSvcs, err = h.GetServices()
494+
488495
if err != nil {
489496
return errors.New("Failed to list IPVS services: " + err.Error())
490497
}
@@ -1081,12 +1088,9 @@ func ipvsSetPersistence(svc *ipvs.Service, p bool) {
10811088
}
10821089
}
10831090

1084-
func ipvsAddService(vip net.IP, protocol, port uint16, persistent bool, scheduler string) (*ipvs.Service, error) {
1085-
svcs, err := h.GetServices()
1086-
if err != nil {
1087-
return nil, err
1088-
}
1091+
func ipvsAddService(svcs []*ipvs.Service, vip net.IP, protocol, port uint16, persistent bool, scheduler string) (*ipvs.Service, error) {
10891092

1093+
var err error
10901094
for _, svc := range svcs {
10911095
if vip.Equal(svc.Address) && protocol == svc.Protocol && port == svc.Port {
10921096
if (persistent && (svc.Flags&0x0001) == 0) || (!persistent && (svc.Flags&0x0001) != 0) {

0 commit comments

Comments
 (0)