@@ -678,50 +678,25 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
678
678
if err = r .ensureState (ctx , bd , networkingv1alpha1 .CLBBindingStateDeleting ); err != nil {
679
679
return result , errors .WithStack (err )
680
680
}
681
+ ch := make (chan error )
681
682
for _ , binding := range status .PortBindings {
682
- releasePort := func () {
683
- log .V (3 ).Info ("release allocated port" , "port" , binding .LoadbalancerPort , "protocol" , binding .Protocol , "pool" , binding .Pool , "lb" , binding .LoadbalancerId )
684
- portpool .Allocator .Release (binding .Pool , binding .LoadbalancerId , portFromPortBindingStatus (& binding ))
685
- }
686
- if lis , err := clb .GetListenerByIdOrPort (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId , int64 (binding .LoadbalancerPort ), binding .Protocol ); err != nil {
687
- if errors .Is (err , clb .ErrListenerNotFound ) { // 监听器已删除,忽略
688
- releasePort ()
689
- continue
690
- }
691
- } else {
692
- if lis == nil { // 监听器已删除,忽略
693
- releasePort ()
694
- continue
695
- }
696
- }
697
- // 解绑 lb
698
- if err := clb .DeleteListenerByIdOrPort (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId , int64 (binding .LoadbalancerPort ), binding .Protocol ); err != nil {
699
- e := errors .Cause (err )
700
- switch e {
701
- case clb .ErrListenerNotFound : // 监听器不存在,认为成功,从端口池释放
702
- log .Info ("delete listener while listener not found, ignore" )
703
- releasePort ()
704
- continue
705
- case clb .ErrOtherListenerNotFound : // 因同一批次删除的其它监听器不存在导致删除失败,需重试
706
- log .Error (err , "requeue due to delete listener failed cuz other listener not found" )
707
- result .RequeueAfter = 20 * time .Millisecond
708
- return result , nil
709
- }
710
- if clb .IsLoadBalancerNotExistsError (e ) { // lb 不存在,忽略
711
- log .Info ("lb not found, ignore when cleanup listener" )
712
- releasePort ()
713
- continue
714
- }
715
- if clb .IsRequestLimitExceededError (e ) {
716
- log .Info ("requeue due to clb api request limit exceeded when cleanup listener" )
717
- result .RequeueAfter = time .Second
718
- return result , nil
683
+ go func (binding * networkingv1alpha1.PortBindingStatus ) {
684
+ if err := r .cleanupPortBinding (ctx , binding ); err != nil {
685
+ ch <- err
686
+ } else {
687
+ ch <- nil
719
688
}
720
- return result , errors .Wrapf (err , "failed to delete listener (%s/%d/%s/%s)" , binding .LoadbalancerId , binding .LoadbalancerPort , binding .Protocol , binding .ListenerId )
721
- } else { // 删除成功,释放端口
722
- releasePort ()
689
+ }(& binding )
690
+ }
691
+ for range status .PortBindings {
692
+ e := <- ch
693
+ if e != nil {
694
+ err = multierr .Append (err , e )
723
695
}
724
696
}
697
+ if err != nil {
698
+ return result , errors .WithStack (err )
699
+ }
725
700
// 清理完成,检查 obj 是否是正常状态,如果是,通常是手动删除 CLBBinding 场景,此时触发一次 obj 对账,让被删除的 CLBBinding 重新创建出来
726
701
backend , err := bd .GetAssociatedObject (ctx , r .Client )
727
702
if err != nil {
@@ -738,6 +713,44 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
738
713
return result , nil
739
714
}
740
715
716
+ func (r * CLBBindingReconciler [T ]) cleanupPortBinding (ctx context.Context , binding * networkingv1alpha1.PortBindingStatus ) error {
717
+ lis , err := clb .GetListenerByIdOrPort (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId , int64 (binding .LoadbalancerPort ), binding .Protocol )
718
+ if err != nil {
719
+ return errors .WithStack (err )
720
+ }
721
+ releasePort := func () {
722
+ if portpool .Allocator .Release (binding .Pool , binding .LoadbalancerId , portFromPortBindingStatus (binding )) {
723
+ log .FromContext (ctx ).V (3 ).Info ("release allocated port" , "port" , binding .LoadbalancerPort , "protocol" , binding .Protocol , "pool" , binding .Pool , "lb" , binding .LoadbalancerId )
724
+ }
725
+ }
726
+ if lis == nil { // 监听器已删除,忽略
727
+ releasePort ()
728
+ return nil
729
+ }
730
+ // 解绑 lb
731
+ err = clb .DeleteListenerByIdOrPort (ctx , binding .Region , binding .LoadbalancerId , binding .ListenerId , int64 (binding .LoadbalancerPort ), binding .Protocol )
732
+ if err != nil {
733
+ errCause := errors .Cause (err )
734
+ switch errCause {
735
+ case clb .ErrListenerNotFound : // 监听器不存在,忽略
736
+ log .FromContext (ctx ).Info ("delete listener while listener not found, ignore" )
737
+ releasePort ()
738
+ return nil
739
+ default :
740
+ if clb .IsLoadBalancerNotExistsError (errCause ) { // lb 不存在,忽略
741
+ log .FromContext (ctx ).Info ("lb not found, ignore when cleanup listener" )
742
+ releasePort ()
743
+ return nil
744
+ }
745
+ }
746
+ // 其它错误,不释放端口,返回错误
747
+ return errors .WithStack (err )
748
+ } else { // 没有错误,删除成功
749
+ releasePort ()
750
+ return nil
751
+ }
752
+ }
753
+
741
754
func generatePortsFromAnnotation (anno string ) (ports []networkingv1alpha1.PortEntry , err error ) {
742
755
rd := bufio .NewReader (strings .NewReader (anno ))
743
756
for {
@@ -886,8 +899,8 @@ func (r *CLBBindingReconciler[T]) syncCLBBinding(ctx context.Context, obj client
886
899
}
887
900
}
888
901
default :
889
- // 没有配置注解,如发现有 CLBBinding,则删除掉
890
- if err == nil {
902
+ // 没有配置注解
903
+ if err == nil { // 没有错误,说明获取 CLBBinding 成功,删除掉这个多余的 CLBBinding
891
904
r .Recorder .Eventf (obj , corev1 .EventTypeNormal , "DeleteCLBBinding" , "delete %s %s" , binding .GetType (), obj .GetName ())
892
905
if err := r .Delete (ctx , bd ); err != nil {
893
906
return result , errors .WithStack (err )
0 commit comments