@@ -678,50 +678,25 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
678678 if err = r .ensureState (ctx , bd , networkingv1alpha1 .CLBBindingStateDeleting ); err != nil {
679679 return result , errors .WithStack (err )
680680 }
681+ ch := make (chan error )
681682 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
719688 }
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 )
723695 }
724696 }
697+ if err != nil {
698+ return result , errors .WithStack (err )
699+ }
725700 // 清理完成,检查 obj 是否是正常状态,如果是,通常是手动删除 CLBBinding 场景,此时触发一次 obj 对账,让被删除的 CLBBinding 重新创建出来
726701 backend , err := bd .GetAssociatedObject (ctx , r .Client )
727702 if err != nil {
@@ -738,6 +713,44 @@ func (r *CLBBindingReconciler[T]) cleanup(ctx context.Context, bd T) (result ctr
738713 return result , nil
739714}
740715
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+
741754func generatePortsFromAnnotation (anno string ) (ports []networkingv1alpha1.PortEntry , err error ) {
742755 rd := bufio .NewReader (strings .NewReader (anno ))
743756 for {
@@ -886,8 +899,8 @@ func (r *CLBBindingReconciler[T]) syncCLBBinding(ctx context.Context, obj client
886899 }
887900 }
888901 default :
889- // 没有配置注解,如发现有 CLBBinding,则删除掉
890- if err == nil {
902+ // 没有配置注解
903+ if err == nil { // 没有错误,说明获取 CLBBinding 成功,删除掉这个多余的 CLBBinding
891904 r .Recorder .Eventf (obj , corev1 .EventTypeNormal , "DeleteCLBBinding" , "delete %s %s" , binding .GetType (), obj .GetName ())
892905 if err := r .Delete (ctx , bd ); err != nil {
893906 return result , errors .WithStack (err )
0 commit comments