Skip to content

Commit 5450c2a

Browse files
authored
Clean backend pool node destination while reconciling security group (#9417) (#9422)
* Retain managed destination while reconciling security group * Add docstring
1 parent 2c7e313 commit 5450c2a

File tree

11 files changed

+915
-549
lines changed

11 files changed

+915
-549
lines changed

pkg/provider/azure.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ type Cloud struct {
142142
pipCache azcache.Resource
143143
// Add service lister to always get latest service
144144
serviceLister corelisters.ServiceLister
145+
nodeLister corelisters.NodeLister
145146
// node-sync-loop routine and service-reconcile routine should not update LoadBalancer at the same time
146147
serviceReconcileLock sync.Mutex
147148

@@ -722,6 +723,7 @@ func (az *Cloud) SetInformers(informerFactory informers.SharedInformerFactory) {
722723
az.nodeInformerSynced = nodeInformer.HasSynced
723724

724725
az.serviceLister = informerFactory.Core().V1().Services().Lister()
726+
az.nodeLister = informerFactory.Core().V1().Nodes().Lister()
725727

726728
az.setUpEndpointSlicesInformer(informerFactory)
727729
}

pkg/provider/azure_fakes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ func GetTestCloud(ctrl *gomock.Controller) (az *Cloud) {
172172
kubeClient := fake.NewSimpleClientset() // FIXME: inject kubeClient
173173
informerFactory := informers.NewSharedInformerFactory(kubeClient, 0)
174174
az.serviceLister = informerFactory.Core().V1().Services().Lister()
175+
az.nodeLister = informerFactory.Core().V1().Nodes().Lister()
175176
informerFactory.Start(wait.NeverStop)
176177
informerFactory.WaitForCacheSync(wait.NeverStop)
177178
}

pkg/provider/azure_loadbalancer.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,6 +3201,25 @@ func (az *Cloud) reconcileSecurityGroup(
32013201
}
32023202
}
32033203

3204+
{
3205+
// Retain all destinations that are managed by cloud-provider.
3206+
managedDestinations, err := az.listAvailableSecurityGroupDestinations(ctx)
3207+
if err != nil {
3208+
logger.Error(err, "Failed to list available security group destinations")
3209+
return nil, err
3210+
}
3211+
3212+
managedDestinations = append(managedDestinations, lbIPAddresses...)
3213+
managedDestinations = append(managedDestinations, additionalIPs...)
3214+
logger.Info("Retaining security group", "managed-destinations", managedDestinations)
3215+
3216+
ipv4Addresses, ipv6Addresses := iputil.GroupAddressesByFamily(managedDestinations)
3217+
if err := accessControl.RetainSecurityGroup(ipv4Addresses, ipv6Addresses); err != nil {
3218+
logger.Error(err, "Failed to retain security group")
3219+
return nil, err
3220+
}
3221+
}
3222+
32043223
rv, updated, err := accessControl.SecurityGroup()
32053224
if err != nil {
32063225
err = fmt.Errorf("unable to apply access control configuration to security group: %w", err)

pkg/provider/azure_loadbalancer_accesscontrol.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,63 @@ func (az *Cloud) listSharedIPPortMapping(
106106

107107
return rv, nil
108108
}
109+
110+
func (az *Cloud) listAvailableSecurityGroupDestinations(_ context.Context) ([]netip.Addr, error) {
111+
services, err := az.serviceLister.List(labels.Everything())
112+
if err != nil {
113+
return nil, fmt.Errorf("list all services: %w", err)
114+
}
115+
116+
nodes, err := az.nodeLister.List(labels.NewSelector())
117+
if err != nil {
118+
return nil, fmt.Errorf("list all nodes: %w", err)
119+
}
120+
121+
var rv []netip.Addr
122+
for _, svc := range services {
123+
// Add additional public IPs
124+
{
125+
ips, err := loadbalancer.AdditionalPublicIPs(svc)
126+
if err == nil {
127+
rv = append(rv, ips...)
128+
}
129+
}
130+
131+
// Add ingress IPs
132+
{
133+
for _, ing := range svc.Status.LoadBalancer.Ingress {
134+
ip, err := netip.ParseAddr(ing.IP)
135+
if err == nil {
136+
rv = append(rv, ip)
137+
}
138+
}
139+
}
140+
}
141+
142+
// Add backend node IPs
143+
{
144+
for _, node := range nodes {
145+
if !az.isNodeManagedByCloudProvider(node) {
146+
continue
147+
}
148+
for _, addr := range node.Status.Addresses {
149+
if addr.Type != v1.NodeInternalIP {
150+
continue
151+
}
152+
ip, err := netip.ParseAddr(addr.Address)
153+
if err == nil {
154+
rv = append(rv, ip)
155+
}
156+
}
157+
}
158+
}
159+
160+
return rv, nil
161+
}
162+
163+
func (az *Cloud) isNodeManagedByCloudProvider(node *v1.Node) bool {
164+
az.nodeCachesLock.Lock()
165+
defer az.nodeCachesLock.Unlock()
166+
167+
return !az.unmanagedNodes.Has(node.ObjectMeta.Name)
168+
}

0 commit comments

Comments
 (0)