@@ -239,8 +239,10 @@ func (r *CLBBindingReconciler[T]) createListener(ctx context.Context, bd clbbind
239
239
// 对账单个监听器
240
240
func (r * CLBBindingReconciler [T ]) ensureListener (ctx context.Context , bd clbbinding.CLBBinding , binding * networkingv1alpha1.PortBindingStatus ) (* networkingv1alpha1.PortBindingStatus , error ) {
241
241
log .FromContext (ctx ).V (10 ).Info ("ensureListener" , "binding" , binding )
242
+ log .FromContext (ctx ).V (10 ).Info ("end ensureListener" , "binding" , binding )
242
243
// 如果 lb 已被移除,且当前还未绑定成功,则移除该端口绑定,等待重新分配端口(配错 lb导致一直无法绑定成功,更正后,可以触发重新分配以便能够成功绑定)
243
244
if bd .GetStatus ().State != networkingv1alpha1 .CLBBindingStateBound && ! portpool .Allocator .IsLbExists (binding .Pool , portpool .NewLBKeyFromBinding (binding )) {
245
+ log .FromContext (ctx ).V (10 ).Info ("remove clbbinding" , "reason" , "lb not exists" , "binding" , binding )
244
246
r .Recorder .Eventf (bd .GetObject (), corev1 .EventTypeNormal , "PortBindingRemoved" , "lb %q not exists, remove port binding (lbPort:%s protocol:%s)" , binding .LoadbalancerId , binding .LoadbalancerPort , binding .Protocol )
245
247
return nil , nil
246
248
}
@@ -264,11 +266,15 @@ func (r *CLBBindingReconciler[T]) ensureListener(ctx context.Context, bd clbbind
264
266
}
265
267
}
266
268
if removeMsg != "" {
269
+ log .FromContext (ctx ).V (10 ).Info ("remove clbbinding" , "message" , removeMsg , "binding" , binding )
267
270
r .Recorder .Eventf (bd .GetObject (), corev1 .EventTypeWarning , removeReason , "%s (%s/%s/%d/%s)" , removeMsg , binding .Pool , binding .LoadbalancerId , binding .LoadbalancerPort , binding .Protocol )
268
271
// 确保监听器被清理
269
272
if err := r .cleanupPortBinding (ctx , binding ); err != nil {
270
273
return binding , errors .WithStack (err )
271
274
}
275
+ if portpool .Allocator .ReleaseBinding (binding ) {
276
+ notifyPortPoolReconcile (binding .Pool )
277
+ }
272
278
return nil , nil
273
279
}
274
280
@@ -284,7 +290,9 @@ func (r *CLBBindingReconciler[T]) ensureListener(ctx context.Context, bd clbbind
284
290
}
285
291
286
292
// 已有监听器 ID,对账看是否符合预期
293
+ log .FromContext (ctx ).V (10 ).Info ("try GetListenerById" , "binding" , binding )
287
294
lis , err := clb .GetListenerById (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId )
295
+ log .FromContext (ctx ).V (10 ).Info ("GetListenerById" , "binding" , binding , "lis" , lis )
288
296
if err != nil {
289
297
if clb .IsLoadBalancerNotExistsError (err ) { // lb 已删除,通知关联的端口池重新对账
290
298
r .Recorder .Eventf (
@@ -319,6 +327,7 @@ func (r *CLBBindingReconciler[T]) ensureListener(ctx context.Context, bd clbbind
319
327
return binding , nil
320
328
}
321
329
} else { // 通过 ID 查到了监听器,对比是否符合预期
330
+ log .FromContext (ctx ).V (10 ).Info ("found listener id, ensureListenerExpected" , "binding" , binding , "lis" , lis )
322
331
binding , err = r .ensureListenerExpected (ctx , binding , lis )
323
332
if err != nil {
324
333
return binding , errors .WithStack (err )
@@ -622,6 +631,8 @@ func patchResult(ctx context.Context, c client.Client, obj client.Object, result
622
631
}
623
632
624
633
func (r * CLBBindingReconciler [T ]) ensurePortBound (ctx context.Context , bd clbbinding.CLBBinding , backend clbbinding.Backend , binding * networkingv1alpha1.PortBindingStatus ) error {
634
+ log .FromContext (ctx ).V (10 ).Info ("ensurePortBound" , "binding" , * binding )
635
+ defer log .FromContext (ctx ).V (10 ).Info ("end ensurePortBound" , "binding" , * binding )
625
636
targets , err := clb .DescribeTargetsTryBatch (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId )
626
637
if err != nil {
627
638
return errors .WithStack (err )
@@ -736,7 +747,7 @@ LOOP_PORT:
736
747
before := time .Now ()
737
748
allocated , err := portpool .Allocator .Allocate (ctx , port .Pools , port .Protocol , util .GetValue (port .UseSamePortAcrossPools ))
738
749
cost := time .Since (before )
739
- log .FromContext (ctx ).V (3 ).Info ("allocate port" , "cost" , cost .String (), "allocated" , allocated , "protocol" , port .Protocol , "pools" , port .Pools , "useSamePortAcrossPools" , util .GetValue (port .UseSamePortAcrossPools ), "err" , err )
750
+ log .FromContext (ctx ).V (3 ).Info ("allocate port" , "cost" , cost .String (), "allocated" , allocated . String () , "protocol" , port .Protocol , "pools" , port .Pools , "useSamePortAcrossPools" , util .GetValue (port .UseSamePortAcrossPools ), "err" , err )
740
751
if err != nil {
741
752
return errors .WithStack (err )
742
753
}
@@ -781,6 +792,9 @@ LOOP_PORT:
781
792
releasePorts ()
782
793
return errors .WithStack (err )
783
794
}
795
+ for _ , pool := range allocatedPorts .Pools () {
796
+ notifyPortPoolReconcile (pool )
797
+ }
784
798
}
785
799
return nil
786
800
}
@@ -801,13 +815,21 @@ func (r *CLBBindingReconciler[T]) ensureState(ctx context.Context, bd clbbinding
801
815
802
816
// 清理 CLBBinding
803
817
func (r * CLBBindingReconciler [T ]) cleanup (ctx context.Context , bd T ) (result ctrl.Result , err error ) {
818
+ anno := bd .GetAnnotations ()
819
+ if anno == nil {
820
+ anno = make (map [string ]string )
821
+ }
822
+ if anno [constant .FinalizedKey ] == "true" {
823
+ return result , nil
824
+ }
804
825
log := log .FromContext (ctx )
805
826
status := bd .GetStatus ()
806
827
log .Info ("cleanup " + bd .GetType (), "bindings" , len (status .PortBindings ))
807
828
if err = r .ensureState (ctx , bd , networkingv1alpha1 .CLBBindingStateDeleting ); err != nil {
808
829
return result , errors .WithStack (err )
809
830
}
810
831
ch := make (chan error )
832
+ controllerutil .ContainsFinalizer (bd .GetObject (), constant .Finalizer )
811
833
for _ , binding := range status .PortBindings {
812
834
go func (binding * networkingv1alpha1.PortBindingStatus ) {
813
835
if err := r .cleanupPortBinding (ctx , binding ); err != nil {
@@ -826,6 +848,23 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
826
848
if err != nil {
827
849
return result , errors .WithStack (err )
828
850
}
851
+ // 全部解绑完成,打上标记,避免重复释放端口导致冲突(比如刚释放完端口又被其它 pod 分配,然后再次进入cleanup时又被清理,有可能再次分配给其它 pod,导致相同ip:port被重复分配)
852
+ anno [constant .FinalizedKey ] = "true"
853
+ bd .SetAnnotations (anno )
854
+ if err := r .Update (ctx , bd .GetObject ()); err != nil {
855
+ return result , errors .WithStack (err )
856
+ }
857
+ // 释放已分配端口
858
+ log .V (10 ).Info ("release allocated ports" , "bindings" , status .PortBindings )
859
+ pools := make (map [string ]struct {})
860
+ for _ , binding := range status .PortBindings {
861
+ if portpool .Allocator .ReleaseBinding (& binding ) {
862
+ pools [binding .Pool ] = struct {}{}
863
+ }
864
+ }
865
+ for pool := range pools {
866
+ notifyPortPoolReconcile (pool )
867
+ }
829
868
// 清理完成,检查 obj 是否是正常状态,如果是,通常是手动删除 CLBBinding 场景,此时触发一次 obj 对账,让被删除的 CLBBinding 重新创建出来
830
869
backend , err := bd .GetAssociatedObject (ctx , r .Client )
831
870
if err != nil {
@@ -843,22 +882,17 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
843
882
}
844
883
845
884
func (r * CLBBindingReconciler [T ]) cleanupPortBinding (ctx context.Context , binding * networkingv1alpha1.PortBindingStatus ) error {
846
- releasePort := func () {
847
- if portpool .Allocator .ReleaseBinding (binding ) {
848
- log .FromContext (ctx ).V (3 ).Info ("release allocated port" , "port" , binding .LoadbalancerPort , "protocol" , binding .Protocol , "pool" , binding .Pool , "lb" , binding .LoadbalancerId )
849
- notifyPortPoolReconcile (binding .Pool )
850
- }
851
- }
885
+ log .FromContext (ctx ).V (10 ).Info ("cleanupPortBinding" , "binding" , binding )
852
886
lis , err := clb .GetListenerByIdOrPort (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId , int64 (binding .LoadbalancerPort ), binding .Protocol )
853
887
if err != nil {
854
888
if clb .IsLoadBalancerNotExistsError (err ) { // 忽略 lbid 不存在的错误,就当清理成功
855
- releasePort ( )
889
+ log . FromContext ( ctx ). V ( 10 ). Info ( "ignore cleanup due to lb not exists" , "binding" , binding )
856
890
return nil
857
891
}
858
892
return errors .WithStack (err )
859
893
}
860
894
if lis == nil { // 监听器已删除,忽略
861
- releasePort ( )
895
+ log . FromContext ( ctx ). V ( 10 ). Info ( "ignore cleanup due to listener already deleted" , "binding" , binding )
862
896
return nil
863
897
}
864
898
// 清理监听器
@@ -868,19 +902,16 @@ func (r *CLBBindingReconciler[T]) cleanupPortBinding(ctx context.Context, bindin
868
902
switch errCause {
869
903
case clb .ErrListenerNotFound : // 监听器不存在,忽略
870
904
log .FromContext (ctx ).Info ("delete listener while listener not found, ignore" )
871
- releasePort ()
872
905
return nil
873
906
default :
874
907
if clb .IsLoadBalancerNotExistsError (errCause ) { // lb 不存在,忽略
875
908
log .FromContext (ctx ).Info ("lb not found, ignore when cleanup listener" )
876
- releasePort ()
877
909
return nil
878
910
}
879
911
}
880
912
// 其它错误,不释放端口,返回错误
881
913
return errors .WithStack (err )
882
914
} else { // 没有错误,删除成功
883
- releasePort ()
884
915
return nil
885
916
}
886
917
}
0 commit comments