Skip to content

Commit 6dca85c

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 6dca85c

File tree

7 files changed

+81
-7
lines changed

7 files changed

+81
-7
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: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import (
99
"sync"
1010
"time"
1111

12-
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
13-
"k8s.io/utils/ptr"
14-
1512
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
1613
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
1714
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
1815
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
16+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
1917
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
2018
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
2119
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6"
@@ -27,6 +25,7 @@ import (
2725
corev1 "k8s.io/api/core/v1"
2826
"k8s.io/klog/v2"
2927
utilnet "k8s.io/utils/net"
28+
"k8s.io/utils/ptr"
3029
)
3130

3231
const (
@@ -302,6 +301,52 @@ func (a *Azure) GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPCo
302301
return []*NodeEgressIPConfiguration{config}, nil
303302
}
304303

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

pkg/cloudprovider/cloudprovider.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +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

1512
v1 "github.com/openshift/api/cloudnetwork/v1"
13+
configv1 "github.com/openshift/api/config/v1"
14+
apifeatures "github.com/openshift/api/features"
15+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
1616
corev1 "k8s.io/api/core/v1"
1717
)
1818

@@ -60,6 +60,10 @@ type CloudProviderIntf interface {
6060
// instance and IP family (AWS), also: the interface is either keyed by name
6161
// (GCP) or ID (Azure, AWS).
6262
GetNodeEgressIPConfiguration(node *corev1.Node, cloudPrivateIPConfigs []*v1.CloudPrivateIPConfig) ([]*NodeEgressIPConfiguration, error)
63+
64+
// SyncLBBackend removes any egress IP which is already added to backend pool of
65+
// a public load balancer. This is mostly Azure specific and may be removed later.
66+
SyncLBBackend(ip net.IP, node *corev1.Node) error
6367
}
6468

6569
// 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)