8
8
"k8s.io/apimachinery/pkg/types"
9
9
utilerrors "k8s.io/apimachinery/pkg/util/errors"
10
10
"k8s.io/apimachinery/pkg/util/intstr"
11
+ "k8s.io/apimachinery/pkg/util/sets"
11
12
utilfeature "k8s.io/apiserver/pkg/util/feature"
12
13
ctrlCfg "k8s.io/cloud-provider-alibaba-cloud/pkg/config"
13
14
"k8s.io/cloud-provider-alibaba-cloud/pkg/controller/service/reconcile/annotation"
@@ -35,6 +36,7 @@ func NewVGroupManager(kubeClient client.Client, cloud prvd.Provider) (*VGroupMan
35
36
if err != nil {
36
37
return nil , err
37
38
}
39
+
38
40
return & VGroupManager {
39
41
kubeClient : kubeClient ,
40
42
cloud : cloud ,
@@ -69,36 +71,84 @@ func (mgr *VGroupManager) BuildLocalModel(reqCtx *svcCtx.RequestContext, m *mode
69
71
return err
70
72
}
71
73
72
- vpcCIDRs , err := mgr .cloud .DescribeVpcCIDRBlock (reqCtx .Ctx , mgr .vpcId , candidates .AddressIPVersion )
74
+ var vgs []model.VServerGroup
75
+ containsPotentialReadyEndpoints := false
76
+ for _ , port := range reqCtx .Service .Spec .Ports {
77
+ vg , cpr , err := mgr .buildVGroupForServicePort (reqCtx , port , candidates , m .LoadBalancerAttribute .IsUserManaged )
78
+ if err != nil {
79
+ return fmt .Errorf ("build vgroup for port %d error: %s" , port .Port , err .Error ())
80
+ }
81
+ vgs = append (vgs , vg )
82
+ containsPotentialReadyEndpoints = containsPotentialReadyEndpoints || cpr
83
+ }
84
+
85
+ err = mgr .updateVServerGroupENIBackendID (reqCtx , vgs , candidates .AddressIPVersion )
73
86
if err != nil {
74
- return fmt . Errorf ( "get vpc cidr error: %s" , err . Error ())
87
+ return err
75
88
}
76
89
77
- vgs := make ([]model.VServerGroup , len (reqCtx .Service .Spec .Ports ))
78
- errs := make ([]error , len (reqCtx .Service .Spec .Ports ))
79
- containsPotentialReadyEndpoints := make ([]bool , len (reqCtx .Service .Spec .Ports ))
80
- parallel .Parallelize (reqCtx .Ctx , ctrlCfg .ControllerCFG .MaxConcurrentActions , len (vgs ), func (i int ) {
81
- port := reqCtx .Service .Spec .Ports [i ]
82
- vg , cpr , err := mgr .buildVGroupForServicePort (reqCtx , vpcCIDRs , port , candidates , m .LoadBalancerAttribute .IsUserManaged )
83
- if err != nil {
84
- errs [i ] = fmt .Errorf ("build vgroup for port %d error: %s" , port .Port , err .Error ())
85
- return
90
+ m .VServerGroups = vgs
91
+ m .ContainsPotentialReadyEndpoints = containsPotentialReadyEndpoints
92
+ return nil
93
+ }
94
+
95
+ func (mgr * VGroupManager ) updateVServerGroupENIBackendID (reqCtx * svcCtx.RequestContext , vgs []model.VServerGroup , ipVersion model.AddressIPVersionType ) error {
96
+ eniIPs := sets.Set [string ]{}
97
+ for _ , vg := range vgs {
98
+ for _ , b := range vg .Backends {
99
+ if b .Type == model .ENIBackendType {
100
+ eniIPs .Insert (b .ServerIp )
101
+ }
86
102
}
87
- vgs [i ] = vg
88
- containsPotentialReadyEndpoints [i ] = cpr
89
- })
103
+ }
90
104
91
- cpr := false
92
- for _ , c := range containsPotentialReadyEndpoints {
93
- if c {
94
- cpr = true
95
- break
105
+ ips := eniIPs .UnsortedList ()
106
+ if len (ips ) == 0 {
107
+ return nil
108
+ }
109
+ result , err := mgr .cloud .DescribeNetworkInterfaces (mgr .vpcId , ips , ipVersion )
110
+ if err != nil {
111
+ return fmt .Errorf ("call DescribeNetworkInterfaces: %s" , err .Error ())
112
+ }
113
+
114
+ var vpcCIDRs []* net.IPNet
115
+ for i := range vgs {
116
+ var filteredBackends []model.BackendAttribute
117
+ var skipIPs []string
118
+ for _ , b := range vgs [i ].Backends {
119
+ if b .Type == model .ENIBackendType {
120
+ eniid , ok := result [b .ServerIp ]
121
+ if ! ok {
122
+ if vpcCIDRs == nil {
123
+ vpcCIDRs , err = mgr .cloud .DescribeVpcCIDRBlock (reqCtx .Ctx , mgr .vpcId , ipVersion )
124
+ if err != nil {
125
+ return fmt .Errorf ("call DescribeVpcCIDRBlock: %s" , err .Error ())
126
+ }
127
+ }
128
+ if containsIP (vpcCIDRs , b .ServerIp ) {
129
+ return fmt .Errorf ("can not find eniid for ip %s in vpc %s" , b .ServerIp , mgr .vpcId )
130
+ } else {
131
+ skipIPs = append (skipIPs , b .ServerIp )
132
+ continue
133
+ }
134
+ }
135
+ b .ServerId = eniid
136
+ }
137
+ filteredBackends = append (filteredBackends , b )
138
+ }
139
+ vgs [i ].Backends = filteredBackends
140
+ if len (skipIPs ) > 0 {
141
+ reqCtx .Log .Info (fmt .Sprintf ("warning: filter pods by vpc cidr %+v, podIPs=%+v" , vpcCIDRs , skipIPs ))
142
+ reqCtx .Recorder .Event (
143
+ reqCtx .Service ,
144
+ v1 .EventTypeNormal ,
145
+ helper .SkipSyncBackends ,
146
+ fmt .Sprintf ("Not sync pods [%s] whose ip is not in vpc cidrs" , strings .Join (skipIPs , "," )),
147
+ )
96
148
}
97
149
}
98
150
99
- m .VServerGroups = vgs
100
- m .ContainsPotentialReadyEndpoints = cpr
101
- return utilerrors .NewAggregate (errs )
151
+ return nil
102
152
}
103
153
104
154
func (mgr * VGroupManager ) BuildRemoteModel (reqCtx * svcCtx.RequestContext , m * model.LoadBalancer ) error {
@@ -386,7 +436,7 @@ func isReusedVGroup(reusedVgIDs []string, vGroupId string) bool {
386
436
return false
387
437
}
388
438
389
- func (mgr * VGroupManager ) buildVGroupForServicePort (reqCtx * svcCtx.RequestContext , vpcCIDRs [] * net. IPNet ,
439
+ func (mgr * VGroupManager ) buildVGroupForServicePort (reqCtx * svcCtx.RequestContext ,
390
440
port v1.ServicePort , candidates * backend.EndpointWithENI , isUserManagedLB bool ) (model.VServerGroup , bool , error ) {
391
441
392
442
vg := model.VServerGroup {
@@ -446,19 +496,19 @@ func (mgr *VGroupManager) buildVGroupForServicePort(reqCtx *svcCtx.RequestContex
446
496
switch candidates .TrafficPolicy {
447
497
case helper .ENITrafficPolicy :
448
498
reqCtx .Log .Info (fmt .Sprintf ("eni mode, build backends for %s" , vg .NamedKey ))
449
- backends , err = mgr .buildENIBackends (reqCtx , vpcCIDRs , candidates , initialBackends , vg )
499
+ backends , err = mgr .buildENIBackends (reqCtx , candidates , initialBackends , vg )
450
500
if err != nil {
451
501
return vg , false , fmt .Errorf ("build eni backends error: %s" , err .Error ())
452
502
}
453
503
case helper .LocalTrafficPolicy :
454
504
reqCtx .Log .Info (fmt .Sprintf ("local mode, build backends for %s" , vg .NamedKey ))
455
- backends , err = mgr .buildLocalBackends (reqCtx , vpcCIDRs , candidates , initialBackends , vg )
505
+ backends , err = mgr .buildLocalBackends (reqCtx , candidates , initialBackends , vg )
456
506
if err != nil {
457
507
return vg , false , fmt .Errorf ("build local backends error: %s" , err .Error ())
458
508
}
459
509
case helper .ClusterTrafficPolicy :
460
510
reqCtx .Log .Info (fmt .Sprintf ("cluster mode, build backends for %s" , vg .NamedKey ))
461
- backends , err = mgr .buildClusterBackends (reqCtx , vpcCIDRs , candidates , initialBackends , vg )
511
+ backends , err = mgr .buildClusterBackends (reqCtx , candidates , initialBackends , vg )
462
512
if err != nil {
463
513
return vg , false , fmt .Errorf ("build cluster backends error: %s" , err .Error ())
464
514
}
@@ -681,22 +731,22 @@ func (mgr *VGroupManager) setBackendsFromEndpointSlices(reqCtx *svcCtx.RequestCo
681
731
return backends , containsPotentialReadyEndpoints , nil
682
732
}
683
733
684
- func (mgr * VGroupManager ) buildENIBackends (reqCtx * svcCtx.RequestContext , vpcCIDRs [] * net. IPNet ,
685
- candidates * backend. EndpointWithENI , backends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
734
+ func (mgr * VGroupManager ) buildENIBackends (reqCtx * svcCtx.RequestContext , candidates * backend. EndpointWithENI ,
735
+ backends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
686
736
if len (backends ) == 0 {
687
737
return nil , nil
688
738
}
689
739
690
- backends , err := updateENIBackends (reqCtx , mgr , vpcCIDRs , backends , candidates .AddressIPVersion )
740
+ backends , err := updateENIBackends (reqCtx , mgr , backends , candidates .AddressIPVersion )
691
741
if err != nil {
692
742
return backends , err
693
743
}
694
744
695
745
return setWeightBackends (helper .ENITrafficPolicy , backends , vgroup .VGroupWeight ), nil
696
746
}
697
747
698
- func (mgr * VGroupManager ) buildLocalBackends (reqCtx * svcCtx.RequestContext , vpcCIDRs [] * net. IPNet ,
699
- candidates * backend. EndpointWithENI , initBackends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
748
+ func (mgr * VGroupManager ) buildLocalBackends (reqCtx * svcCtx.RequestContext , candidates * backend. EndpointWithENI ,
749
+ initBackends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
700
750
var (
701
751
ecsBackends , eciBackends []model.BackendAttribute
702
752
err error
@@ -743,7 +793,7 @@ func (mgr *VGroupManager) buildLocalBackends(reqCtx *svcCtx.RequestContext, vpcC
743
793
// 2. add eci backends
744
794
if len (eciBackends ) != 0 {
745
795
reqCtx .Log .Info ("add eciBackends" )
746
- eciBackends , err = updateENIBackends (reqCtx , mgr , vpcCIDRs , eciBackends , candidates .AddressIPVersion )
796
+ eciBackends , err = updateENIBackends (reqCtx , mgr , eciBackends , candidates .AddressIPVersion )
747
797
if err != nil {
748
798
return nil , fmt .Errorf ("update eci backends error: %s" , err .Error ())
749
799
}
@@ -772,8 +822,8 @@ func removeDuplicatedECS(backends []model.BackendAttribute) []model.BackendAttri
772
822
773
823
}
774
824
775
- func (mgr * VGroupManager ) buildClusterBackends (reqCtx * svcCtx.RequestContext , vpcCIDRs [] * net. IPNet ,
776
- candidates * backend. EndpointWithENI , initBackends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
825
+ func (mgr * VGroupManager ) buildClusterBackends (reqCtx * svcCtx.RequestContext , candidates * backend. EndpointWithENI ,
826
+ initBackends []model.BackendAttribute , vgroup model.VServerGroup ) ([]model.BackendAttribute , error ) {
777
827
var (
778
828
ecsBackends , eciBackends []model.BackendAttribute
779
829
err error
@@ -823,7 +873,7 @@ func (mgr *VGroupManager) buildClusterBackends(reqCtx *svcCtx.RequestContext, vp
823
873
}
824
874
825
875
if len (eciBackends ) != 0 {
826
- eciBackends , err = updateENIBackends (reqCtx , mgr , vpcCIDRs , eciBackends , candidates .AddressIPVersion )
876
+ eciBackends , err = updateENIBackends (reqCtx , mgr , eciBackends , candidates .AddressIPVersion )
827
877
if err != nil {
828
878
return nil , fmt .Errorf ("update eci backends error: %s" , err .Error ())
829
879
}
@@ -834,44 +884,12 @@ func (mgr *VGroupManager) buildClusterBackends(reqCtx *svcCtx.RequestContext, vp
834
884
return setWeightBackends (helper .ClusterTrafficPolicy , backends , vgroup .VGroupWeight ), nil
835
885
}
836
886
837
- func updateENIBackends (reqCtx * svcCtx.RequestContext , mgr * VGroupManager , vpcCIDRs []* net.IPNet ,
838
- backends []model.BackendAttribute , ipVersion model.AddressIPVersionType ) (
839
- []model.BackendAttribute , error ) {
840
- var ips []string
841
- for _ , b := range backends {
842
- ips = append (ips , b .ServerIp )
843
- }
844
- result , err := mgr .cloud .DescribeNetworkInterfaces (mgr .vpcId , ips , ipVersion )
845
- if err != nil {
846
- return nil , fmt .Errorf ("call DescribeNetworkInterfaces: %s" , err .Error ())
847
- }
848
-
849
- var skipIPs []string
887
+ func updateENIBackends (reqCtx * svcCtx.RequestContext , mgr * VGroupManager , backends []model.BackendAttribute , ipVersion model.AddressIPVersionType ) ([]model.BackendAttribute , error ) {
850
888
for i := range backends {
851
- eniid , ok := result [backends [i ].ServerIp ]
852
- if ! ok {
853
- // if ip in vpcCIDRs, it should have a eni id
854
- if containsIP (vpcCIDRs , backends [i ].ServerIp ) {
855
- return nil , fmt .Errorf ("can not find eniid for ip %s in vpc %s" , backends [i ].ServerIp , mgr .vpcId )
856
- } else {
857
- skipIPs = append (skipIPs , backends [i ].ServerIp )
858
- }
859
- }
860
889
// for ENI backend type, port should be set to targetPort (default value), no need to update
861
- backends [i ].ServerId = eniid
862
890
backends [i ].Type = model .ENIBackendType
863
891
}
864
892
865
- if len (skipIPs ) > 0 {
866
- reqCtx .Log .Info (fmt .Sprintf ("warning: filter pods by vpc cidr %+v, podIPs=%+v" , vpcCIDRs , skipIPs ))
867
- reqCtx .Recorder .Event (
868
- reqCtx .Service ,
869
- v1 .EventTypeNormal ,
870
- helper .SkipSyncBackends ,
871
- fmt .Sprintf ("Not sync pods [%s] whose ip is not in vpc cidrs" , strings .Join (skipIPs , "," )),
872
- )
873
- }
874
-
875
893
return backends , nil
876
894
}
877
895
0 commit comments