@@ -11,6 +11,7 @@ import (
1111 "context"
1212 "fmt"
1313 "io"
14+ "strconv"
1415
1516 "github.com/davecgh/go-spew/spew"
1617 yaml "gopkg.in/yaml.v2"
@@ -27,8 +28,9 @@ import (
2728)
2829
2930const (
30- ProviderName = "qingcloud"
31- QYConfigPath = "/etc/qingcloud/config.yaml"
31+ ProviderName = "qingcloud"
32+ QYConfigPath = "/etc/qingcloud/config.yaml"
33+ DefaultBackendCount = 3
3234)
3335
3436type Config struct {
@@ -232,7 +234,7 @@ func (qc *QingCloud) EnsureLoadBalancer(ctx context.Context, _ string, service *
232234 klog .Infof ("The loadbalancer %s has the following listeners %s" , * lb .Status .LoadBalancerID , spew .Sdump (listenerIDs ))
233235 if len (listenerIDs ) <= 0 {
234236 klog .Infof ("creating listeners for loadbalancers %s, service ports %s" , * lb .Status .LoadBalancerID , spew .Sdump (service .Spec .Ports ))
235- if err = qc .createListenersAndBackends (conf , lb , service .Spec .Ports , nodes ); err != nil {
237+ if err = qc .createListenersAndBackends (conf , lb , service .Spec .Ports , nodes , service ); err != nil {
236238 klog .Errorf ("createListenersAndBackends for loadbalancer %s error: %v" , * lb .Status .LoadBalancerID , err )
237239 return nil , err
238240 }
@@ -244,7 +246,7 @@ func (qc *QingCloud) EnsureLoadBalancer(ctx context.Context, _ string, service *
244246 }
245247
246248 //update listerner
247- toDelete , toAdd := diffListeners (listeners , conf , service .Spec .Ports )
249+ toDelete , toAdd , toKeep := diffListeners (listeners , conf , service .Spec .Ports )
248250 if len (toDelete ) > 0 {
249251 klog .Infof ("listeners %s will be deleted for lb %s" , spew .Sdump (toDelete ), * lb .Status .LoadBalancerID )
250252 err = qc .Client .DeleteListener (toDelete )
@@ -256,38 +258,37 @@ func (qc *QingCloud) EnsureLoadBalancer(ctx context.Context, _ string, service *
256258
257259 if len (toAdd ) > 0 {
258260 klog .Infof ("listeners %s will be added for lb %s" , spew .Sdump (toAdd ), * lb .Status .LoadBalancerID )
259- err = qc .createListenersAndBackends (conf , lb , toAdd , nodes )
261+ err = qc .createListenersAndBackends (conf , lb , toAdd , nodes , service )
260262 if err != nil {
261263 return nil , err
262264 }
263265 modify = true
264266 }
265267
266268 //update backend; for example, service annotation for backend label changed
267- if len (toAdd ) == 0 && len (toDelete ) == 0 {
268- for _ , listener := range listeners {
269- toDelete , toAdd := diffBackend (listener , nodes )
270-
271- if len (toDelete ) > 0 {
272- klog .Infof ("backends %s will be deleted for listener %s(%s) of lb %s" ,
273- spew .Sdump (toDelete ), * listener .Spec .LoadBalancerListenerName , * listener .Spec .LoadBalancerListenerID , * lb .Status .LoadBalancerID )
274- err = qc .Client .DeleteBackends (toDelete )
275- if err != nil {
276- return nil , err
277- }
278- modify = true
269+ for _ , listener := range toKeep {
270+ // toDelete, toAdd := diffBackend(listener, nodes)
271+ toDelete , toAdd := qc .diffBackend (listener , nodes , conf , service )
272+
273+ if len (toDelete ) > 0 {
274+ klog .Infof ("backends %s will be deleted for listener %s(%s) of lb %s" ,
275+ spew .Sdump (toDelete ), * listener .Spec .LoadBalancerListenerName , * listener .Spec .LoadBalancerListenerID , * lb .Status .LoadBalancerID )
276+ err = qc .Client .DeleteBackends (toDelete )
277+ if err != nil {
278+ return nil , err
279279 }
280+ modify = true
281+ }
280282
281- toAddBackends := generateLoadBalancerBackends (toAdd , listener , service .Spec .Ports )
282- if len (toAddBackends ) > 0 {
283- klog .Infof ("backends %s will be added for listener %s(%s) of lb %s" ,
284- spew .Sdump (toAddBackends ), * listener .Spec .LoadBalancerListenerName , * listener .Spec .LoadBalancerListenerID , * lb .Status .LoadBalancerID )
285- _ , err = qc .Client .CreateBackends (toAddBackends )
286- if err != nil {
287- return nil , err
288- }
289- modify = true
283+ toAddBackends := generateLoadBalancerBackends (toAdd , listener , service .Spec .Ports )
284+ if len (toAddBackends ) > 0 {
285+ klog .Infof ("backends %s will be added for listener %s(%s) of lb %s" ,
286+ spew .Sdump (toAddBackends ), * listener .Spec .LoadBalancerListenerName , * listener .Spec .LoadBalancerListenerID , * lb .Status .LoadBalancerID )
287+ _ , err = qc .Client .CreateBackends (toAddBackends )
288+ if err != nil {
289+ return nil , err
290290 }
291+ modify = true
291292 }
292293 }
293294
@@ -316,6 +317,7 @@ func (qc *QingCloud) EnsureLoadBalancer(ctx context.Context, _ string, service *
316317 //1.2 prepare sg
317318 //default sg set by Client auto
318319 //1.3 create lb
320+ klog .Infof ("creating loadbalance for service %s/%s" , service .Namespace , service .Name )
319321 lb , err = qc .Client .CreateLB (& apis.LoadBalancer {
320322 Spec : apis.LoadBalancerSpec {
321323 LoadBalancerName : & conf .LoadBalancerName ,
@@ -331,7 +333,7 @@ func (qc *QingCloud) EnsureLoadBalancer(ctx context.Context, _ string, service *
331333 }
332334
333335 //create listener
334- if err = qc .createListenersAndBackends (conf , lb , service .Spec .Ports , nodes ); err != nil {
336+ if err = qc .createListenersAndBackends (conf , lb , service .Spec .Ports , nodes , service ); err != nil {
335337 return nil , err
336338 }
337339 } else {
@@ -382,7 +384,8 @@ func (qc *QingCloud) UpdateLoadBalancer(ctx context.Context, _ string, service *
382384 }
383385
384386 for _ , listener := range listeners {
385- toDelete , toAdd := diffBackend (listener , nodes )
387+ // toDelete, toAdd := diffBackend(listener, nodes)
388+ toDelete , toAdd := qc .diffBackend (listener , nodes , conf , service )
386389
387390 if len (toDelete ) > 0 {
388391 klog .Infof ("backends %s will be deleted for listener %s(%s) of lb %s" ,
@@ -414,7 +417,7 @@ func (qc *QingCloud) UpdateLoadBalancer(ctx context.Context, _ string, service *
414417 return qc .Client .UpdateLB (lb .Status .LoadBalancerID )
415418}
416419
417- func (qc * QingCloud ) createListenersAndBackends (conf * LoadBalancerConfig , status * apis.LoadBalancer , ports []v1.ServicePort , nodes []* v1.Node ) error {
420+ func (qc * QingCloud ) createListenersAndBackends (conf * LoadBalancerConfig , status * apis.LoadBalancer , ports []v1.ServicePort , nodes []* v1.Node , svc * v1. Service ) error {
418421 listeners , err := generateLoadBalancerListeners (conf , status , ports )
419422 if err != nil {
420423 klog .Errorf ("generateLoadBalancerListeners for loadbalancer %s error: %v" , * status .Status .LoadBalancerID , err )
@@ -426,7 +429,19 @@ func (qc *QingCloud) createListenersAndBackends(conf *LoadBalancerConfig, status
426429 return err
427430 }
428431
429- //create backend
432+ // filter backend nodes by count
433+ if svc .Spec .ExternalTrafficPolicy == v1 .ServiceExternalTrafficPolicyTypeCluster && conf .BackendCountConfig != "" {
434+ klog .Infof ("service %s/%s has lb backend count annotation, try to get %d random nodes as backend" , svc .Namespace , svc .Name , conf .BackendCountResult )
435+ nodes = getRandomNodes (nodes , conf .BackendCountResult )
436+
437+ var resultNames []string
438+ for _ , node := range nodes {
439+ resultNames = append (resultNames , node .Name )
440+ }
441+ klog .Infof ("get random nodes result for service %s/%s: %v" , svc .Namespace , svc .Name , resultNames )
442+ }
443+
444+ // create backend
430445 for _ , listener := range listeners {
431446 backends := generateLoadBalancerBackends (nodes , listener , ports )
432447 _ , err = qc .Client .CreateBackends (backends )
@@ -515,7 +530,7 @@ func (qc *QingCloud) filterNodes(ctx context.Context, svc *v1.Service, nodes []*
515530 }
516531 }
517532 } else {
518- if lbconfog .BackendLabel != "" {
533+ if lbconfog .BackendLabel != "" { // filter by node label
519534 klog .Infof ("filter nodes for service %s/%s by backend label: %s" , svc .Namespace , svc .Name , lbconfog .BackendLabel )
520535
521536 // filter by label
@@ -543,6 +558,28 @@ func (qc *QingCloud) filterNodes(ctx context.Context, svc *v1.Service, nodes []*
543558 klog .Infof ("there are no available nodes for service %s/%s, use all nodes!" , svc .Namespace , svc .Name )
544559 newNodes = nodes
545560 }
561+ // clear lb backend count config
562+ lbconfog .BackendCountConfig = ""
563+ } else if lbconfog .BackendCountConfig != "" { //filter by backend count config
564+ var backendCountResult int
565+
566+ backendCountConfig , _ := strconv .Atoi (lbconfog .BackendCountConfig )
567+ if backendCountConfig > 0 && backendCountConfig <= len (nodes ) {
568+ backendCountResult = backendCountConfig
569+ } else {
570+ //invalid count config, use default value (1/3 of all nodes)
571+ if len (nodes ) <= 3 {
572+ backendCountResult = len (nodes )
573+ } else {
574+ backendCountResult = len (nodes ) / 3
575+ if backendCountResult < 3 {
576+ backendCountResult = DefaultBackendCount
577+ }
578+ }
579+ }
580+
581+ lbconfog .BackendCountResult = backendCountResult
582+ newNodes = nodes
546583 } else {
547584 // no need to filter
548585 newNodes = nodes
0 commit comments