Skip to content

Commit c2b5065

Browse files
committed
Remove any Egress IP from Azure public LB backend
The consensus is to not add egress IP to public load balancer backend pool regardless of the presence of an OutBoundRule. During upgrade this PR let cobtroller removes any egress IP added to public load balancer backend pool previously. Signed-off-by: Arnab Ghosh <[email protected]>
1 parent 4dde249 commit c2b5065

File tree

7 files changed

+80
-4
lines changed

7 files changed

+80
-4
lines changed

pkg/cloudprovider/aws.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ func (a *AWS) GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPConf
224224
return []*NodeEgressIPConfiguration{config}, nil
225225
}
226226

227+
func (a *AWS) SyncLBBackend(_ net.IP, _ *corev1.Node) error {
228+
// We dont add Egress IP to AWS public LB backend; nothing to do
229+
return nil
230+
}
231+
227232
// Unfortunately the AWS API (WaitUntilInstanceRunning) only handles equality
228233
// assertion: so on delete we can't specify and assert that the IP which is
229234
// being removed is completely removed, we are forced to do the inverse, i.e:

pkg/cloudprovider/azure.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,52 @@ func (a *Azure) GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPCo
302302
return []*NodeEgressIPConfiguration{config}, nil
303303
}
304304

305+
// The consensus is to not add egress IP to public load balancer
306+
// backend pool regardless of the presence of an OutBoundRule.
307+
// During upgrade this function removes any egress IP added to
308+
// public load balancer backend pool previously.
309+
func (a *Azure) SyncLBBackend(ip net.IP, node *corev1.Node) error {
310+
ipc := ip.String()
311+
klog.Infof("Acquiring node lock for modifying load balancer backend pool, node: %s, ip: %s", node.Name, ipc)
312+
nodeLock := a.getNodeLock(node.Name)
313+
nodeLock.Lock()
314+
defer nodeLock.Unlock()
315+
instance, err := a.getInstance(node)
316+
if err != nil {
317+
return err
318+
}
319+
networkInterfaces, err := a.getNetworkInterfaces(instance)
320+
if err != nil {
321+
return err
322+
}
323+
if networkInterfaces[0].Properties == nil {
324+
return fmt.Errorf("nil network interface properties")
325+
}
326+
// Perform the operation against the first interface listed, which will be
327+
// the primary interface (if it's defined as such) or the first one returned
328+
// following the order Azure specifies.
329+
networkInterface := networkInterfaces[0]
330+
var loadBalanceerBackendPoolModified bool
331+
// omit Egress IP from LB backend pool
332+
ipConfigurations := networkInterface.Properties.IPConfigurations
333+
for _, ipCfg := range ipConfigurations {
334+
if ptr.Deref(ipCfg.Properties.PrivateIPAddress, "") == ipc &&
335+
ipCfg.Properties.LoadBalancerBackendAddressPools != nil {
336+
ipCfg.Properties.LoadBalancerBackendAddressPools = nil
337+
loadBalanceerBackendPoolModified = true
338+
}
339+
}
340+
if loadBalanceerBackendPoolModified {
341+
networkInterface.Properties.IPConfigurations = ipConfigurations
342+
poller, err := a.createOrUpdate(networkInterface)
343+
if err != nil {
344+
return err
345+
}
346+
return a.waitForCompletion(poller)
347+
}
348+
return nil
349+
}
350+
305351
func (a *Azure) createOrUpdate(networkInterface armnetwork.Interface) (*runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], error) {
306352
ctx, cancel := context.WithTimeout(a.ctx, defaultAzureOperationTimeout)
307353
defer cancel()

pkg/cloudprovider/cloudprovider.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
apifeatures "github.com/openshift/api/features"
8-
configv1 "github.com/openshift/api/config/v1"
9-
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
107
"net"
118
"os"
129
"path/filepath"
1310
"sync"
1411

12+
configv1 "github.com/openshift/api/config/v1"
13+
apifeatures "github.com/openshift/api/features"
14+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
15+
1516
v1 "github.com/openshift/api/cloudnetwork/v1"
1617
corev1 "k8s.io/api/core/v1"
1718
)
@@ -60,6 +61,10 @@ type CloudProviderIntf interface {
6061
// instance and IP family (AWS), also: the interface is either keyed by name
6162
// (GCP) or ID (Azure, AWS).
6263
GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPConfigs []*v1.CloudPrivateIPConfig) ([]*NodeEgressIPConfiguration, error)
64+
65+
// SyncLBBackend removes any egress IP which is already added to backend pool of
66+
// a public load balancer. This is mostly Azure specific and may be removed later.
67+
SyncLBBackend(ip net.IP, node *corev1.Node) error
6368
}
6469

6570
// CloudProviderWithMoveIntf is additional interface that can be added to cloud

pkg/cloudprovider/cloudprovider_fake.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ func (f *FakeCloudProvider) GetNodeEgressIPConfiguration(node *corev1.Node, clou
6969
}
7070
return nil, nil
7171
}
72+
73+
func (a *FakeCloudProvider) SyncLBBackend(_ net.IP, _ *corev1.Node) error {
74+
return nil
75+
}

pkg/cloudprovider/gcp.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ func (g *GCP) GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPConf
189189
return nil, nil
190190
}
191191

192+
func (a *GCP) SyncLBBackend(_ net.IP, _ *corev1.Node) error {
193+
// We dont add Egress IP to GCP public LB backend; nothing to do
194+
return nil
195+
}
196+
192197
// The GCP zone operations API call. All GCP infrastructure modifications are
193198
// assigned a unique operation ID and are queued in a global/zone operations
194199
// queue. In the case of assignments of private IP addresses to instances, the

pkg/cloudprovider/openstack.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,11 @@ func (o *OpenStack) GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivate
545545
return nil, fmt.Errorf("no suitable interface configurations found")
546546
}
547547

548+
func (a *OpenStack) SyncLBBackend(_ net.IP, _ *corev1.Node) error {
549+
// We dont add Egress IP to OpenStack public LB backend; nothing to do
550+
return nil
551+
}
552+
548553
// getNeutronPortNodeEgressIPConfiguration renders the NeutronPortNodeEgressIPConfiguration for a given port.
549554
// The interface is keyed by a neutron UUID.
550555
// If multiple IPv4 repectively multiple IPv6 subnets are attached to the same port, throw an error.

pkg/controller/cloudprivateipconfig/cloudprivateipconfig_controller.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,14 @@ func (c *CloudPrivateIPConfigController) SyncHandler(key string) error {
180180

181181
nodeNameToAdd, nodeNameToDel := c.computeOp(cloudPrivateIPConfig)
182182
switch {
183-
// Dequeue on NOOP, there's nothing to do
184183
case nodeNameToAdd == "" && nodeNameToDel == "":
184+
node, err := c.nodesLister.Get(cloudPrivateIPConfig.Spec.Node)
185+
if err != nil {
186+
return err
187+
}
188+
if err := c.cloudProviderClient.SyncLBBackend(ip, node); err != nil {
189+
return fmt.Errorf("error while syncing egress IP %q added to LB backend pool", key)
190+
}
185191
return nil
186192
case nodeNameToAdd != "" && nodeNameToDel != "":
187193
klog.Infof("CloudPrivateIPConfig: %q will be moved from node %q to node %q", key, nodeNameToDel, nodeNameToAdd)

0 commit comments

Comments
 (0)