Skip to content

Commit 736bfbc

Browse files
authored
Merge pull request #5332 from nawazkh/make_ilb_ip_configurable
let users configure private IP of the internal LB
2 parents f35cdf1 + ded1922 commit 736bfbc

16 files changed

+1597
-83
lines changed

api/v1beta1/azurecluster_default.go

+30
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"fmt"
2121

2222
"k8s.io/utils/ptr"
23+
24+
"sigs.k8s.io/cluster-api-provider-azure/feature"
2325
)
2426

2527
const (
@@ -245,6 +247,29 @@ func (c *AzureCluster) setAPIServerLBDefaults() {
245247
},
246248
}
247249
}
250+
// If the API Server ILB feature is enabled, create a default internal LB IP or use the specified one
251+
if feature.Gates.Enabled(feature.APIServerILB) {
252+
privateIPFound := false
253+
for i := range lb.FrontendIPs {
254+
if lb.FrontendIPs[i].FrontendIPClass.PrivateIPAddress != "" {
255+
if lb.FrontendIPs[i].Name == "" {
256+
lb.FrontendIPs[i].Name = generatePrivateIPConfigName(lb.Name)
257+
}
258+
privateIPFound = true
259+
break
260+
}
261+
}
262+
// if no private IP is found, we should create a default internal LB IP
263+
if !privateIPFound {
264+
privateIP := FrontendIP{
265+
Name: generatePrivateIPConfigName(lb.Name),
266+
FrontendIPClass: FrontendIPClass{
267+
PrivateIPAddress: DefaultInternalLBIPAddress,
268+
},
269+
}
270+
lb.FrontendIPs = append(lb.FrontendIPs, privateIP)
271+
}
272+
}
248273
} else if lb.Type == Internal {
249274
if lb.Name == "" {
250275
lb.Name = generateInternalLBName(c.ObjectMeta.Name)
@@ -530,6 +555,11 @@ func generateFrontendIPConfigName(lbName string) string {
530555
return fmt.Sprintf("%s-%s", lbName, "frontEnd")
531556
}
532557

558+
// generateFrontendIPConfigName generates a load balancer frontend IP config name.
559+
func generatePrivateIPConfigName(lbName string) string {
560+
return fmt.Sprintf("%s-%s", lbName, "frontEnd-internal-ip")
561+
}
562+
533563
// generateNodeOutboundIPName generates a public IP name, based on the cluster name.
534564
func generateNodeOutboundIPName(clusterName string) string {
535565
return fmt.Sprintf("pip-%s-node-outbound", clusterName)

api/v1beta1/azurecluster_default_test.go

+227-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ import (
2323

2424
corev1 "k8s.io/api/core/v1"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/component-base/featuregate"
27+
featuregatetesting "k8s.io/component-base/featuregate/testing"
2628
"k8s.io/utils/ptr"
29+
30+
"sigs.k8s.io/cluster-api-provider-azure/feature"
2731
)
2832

2933
func TestResourceGroupDefault(t *testing.T) {
@@ -1236,9 +1240,10 @@ func TestVnetPeeringDefaults(t *testing.T) {
12361240

12371241
func TestAPIServerLBDefaults(t *testing.T) {
12381242
cases := []struct {
1239-
name string
1240-
cluster *AzureCluster
1241-
output *AzureCluster
1243+
name string
1244+
featureGate featuregate.Feature
1245+
cluster *AzureCluster
1246+
output *AzureCluster
12421247
}{
12431248
{
12441249
name: "no lb",
@@ -1282,6 +1287,55 @@ func TestAPIServerLBDefaults(t *testing.T) {
12821287
},
12831288
},
12841289
},
1290+
{
1291+
name: "no lb with APIServerILB feature gate enabled",
1292+
featureGate: feature.APIServerILB,
1293+
cluster: &AzureCluster{
1294+
ObjectMeta: metav1.ObjectMeta{
1295+
Name: "cluster-test",
1296+
},
1297+
Spec: AzureClusterSpec{
1298+
ControlPlaneEnabled: true,
1299+
NetworkSpec: NetworkSpec{},
1300+
},
1301+
},
1302+
output: &AzureCluster{
1303+
ObjectMeta: metav1.ObjectMeta{
1304+
Name: "cluster-test",
1305+
},
1306+
Spec: AzureClusterSpec{
1307+
ControlPlaneEnabled: true,
1308+
NetworkSpec: NetworkSpec{
1309+
APIServerLB: &LoadBalancerSpec{
1310+
Name: "cluster-test-public-lb",
1311+
FrontendIPs: []FrontendIP{
1312+
{
1313+
Name: "cluster-test-public-lb-frontEnd",
1314+
PublicIP: &PublicIPSpec{
1315+
Name: "pip-cluster-test-apiserver",
1316+
DNSName: "",
1317+
},
1318+
},
1319+
{
1320+
Name: "cluster-test-public-lb-frontEnd-internal-ip",
1321+
FrontendIPClass: FrontendIPClass{
1322+
PrivateIPAddress: DefaultInternalLBIPAddress,
1323+
},
1324+
},
1325+
},
1326+
BackendPool: BackendPool{
1327+
Name: "cluster-test-public-lb-backendPool",
1328+
},
1329+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1330+
SKU: SKUStandard,
1331+
Type: Public,
1332+
IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes),
1333+
},
1334+
},
1335+
},
1336+
},
1337+
},
1338+
},
12851339
{
12861340
name: "internal lb",
12871341
cluster: &AzureCluster{
@@ -1327,6 +1381,52 @@ func TestAPIServerLBDefaults(t *testing.T) {
13271381
},
13281382
},
13291383
},
1384+
{
1385+
name: "internal lb with feature gate API Server ILB enabled",
1386+
featureGate: feature.APIServerILB,
1387+
cluster: &AzureCluster{
1388+
ObjectMeta: metav1.ObjectMeta{
1389+
Name: "cluster-test",
1390+
},
1391+
Spec: AzureClusterSpec{
1392+
NetworkSpec: NetworkSpec{
1393+
APIServerLB: &LoadBalancerSpec{
1394+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1395+
Type: Internal,
1396+
},
1397+
},
1398+
},
1399+
},
1400+
},
1401+
output: &AzureCluster{
1402+
ObjectMeta: metav1.ObjectMeta{
1403+
Name: "cluster-test",
1404+
},
1405+
Spec: AzureClusterSpec{
1406+
NetworkSpec: NetworkSpec{
1407+
APIServerLB: &LoadBalancerSpec{
1408+
FrontendIPs: []FrontendIP{
1409+
{
1410+
Name: "cluster-test-internal-lb-frontEnd",
1411+
FrontendIPClass: FrontendIPClass{
1412+
PrivateIPAddress: DefaultInternalLBIPAddress,
1413+
},
1414+
},
1415+
},
1416+
BackendPool: BackendPool{
1417+
Name: "cluster-test-internal-lb-backendPool",
1418+
},
1419+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1420+
SKU: SKUStandard,
1421+
Type: Internal,
1422+
IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes),
1423+
},
1424+
Name: "cluster-test-internal-lb",
1425+
},
1426+
},
1427+
},
1428+
},
1429+
},
13301430
{
13311431
name: "with custom backend pool name",
13321432
cluster: &AzureCluster{
@@ -1375,12 +1475,135 @@ func TestAPIServerLBDefaults(t *testing.T) {
13751475
},
13761476
},
13771477
},
1478+
{
1479+
name: "with custom backend pool name with feature gate API Server ILB enabled",
1480+
featureGate: feature.APIServerILB,
1481+
cluster: &AzureCluster{
1482+
ObjectMeta: metav1.ObjectMeta{
1483+
Name: "cluster-test",
1484+
},
1485+
Spec: AzureClusterSpec{
1486+
NetworkSpec: NetworkSpec{
1487+
APIServerLB: &LoadBalancerSpec{
1488+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1489+
Type: Internal,
1490+
},
1491+
BackendPool: BackendPool{
1492+
Name: "custom-backend-pool",
1493+
},
1494+
},
1495+
},
1496+
},
1497+
},
1498+
output: &AzureCluster{
1499+
ObjectMeta: metav1.ObjectMeta{
1500+
Name: "cluster-test",
1501+
},
1502+
Spec: AzureClusterSpec{
1503+
NetworkSpec: NetworkSpec{
1504+
APIServerLB: &LoadBalancerSpec{
1505+
FrontendIPs: []FrontendIP{
1506+
{
1507+
Name: "cluster-test-internal-lb-frontEnd",
1508+
FrontendIPClass: FrontendIPClass{
1509+
PrivateIPAddress: DefaultInternalLBIPAddress,
1510+
},
1511+
},
1512+
},
1513+
BackendPool: BackendPool{
1514+
Name: "custom-backend-pool",
1515+
},
1516+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1517+
SKU: SKUStandard,
1518+
Type: Internal,
1519+
IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes),
1520+
},
1521+
Name: "cluster-test-internal-lb",
1522+
},
1523+
},
1524+
},
1525+
},
1526+
},
1527+
{
1528+
name: "public lb with APIServerILB feature gate enabled and custom private IP belonging to default control plane CIDR",
1529+
featureGate: feature.APIServerILB,
1530+
cluster: &AzureCluster{
1531+
ObjectMeta: metav1.ObjectMeta{
1532+
Name: "cluster-test",
1533+
},
1534+
Spec: AzureClusterSpec{
1535+
ControlPlaneEnabled: true,
1536+
NetworkSpec: NetworkSpec{
1537+
APIServerLB: &LoadBalancerSpec{
1538+
Name: "cluster-test-public-lb",
1539+
FrontendIPs: []FrontendIP{
1540+
{
1541+
Name: "cluster-test-public-lb-frontEnd",
1542+
PublicIP: &PublicIPSpec{
1543+
Name: "pip-cluster-test-apiserver",
1544+
DNSName: "",
1545+
},
1546+
},
1547+
{
1548+
Name: "my-internal-ip",
1549+
FrontendIPClass: FrontendIPClass{
1550+
PrivateIPAddress: "10.0.0.111",
1551+
},
1552+
},
1553+
},
1554+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1555+
Type: Public,
1556+
SKU: SKUStandard,
1557+
},
1558+
},
1559+
},
1560+
},
1561+
},
1562+
output: &AzureCluster{
1563+
ObjectMeta: metav1.ObjectMeta{
1564+
Name: "cluster-test",
1565+
},
1566+
Spec: AzureClusterSpec{
1567+
ControlPlaneEnabled: true,
1568+
NetworkSpec: NetworkSpec{
1569+
APIServerLB: &LoadBalancerSpec{
1570+
Name: "cluster-test-public-lb",
1571+
FrontendIPs: []FrontendIP{
1572+
{
1573+
Name: "cluster-test-public-lb-frontEnd",
1574+
PublicIP: &PublicIPSpec{
1575+
Name: "pip-cluster-test-apiserver",
1576+
DNSName: "",
1577+
},
1578+
},
1579+
{
1580+
Name: "my-internal-ip",
1581+
FrontendIPClass: FrontendIPClass{
1582+
PrivateIPAddress: "10.0.0.111",
1583+
},
1584+
},
1585+
},
1586+
BackendPool: BackendPool{
1587+
Name: "cluster-test-public-lb-backendPool",
1588+
},
1589+
LoadBalancerClassSpec: LoadBalancerClassSpec{
1590+
SKU: SKUStandard,
1591+
Type: Public,
1592+
IdleTimeoutInMinutes: ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes),
1593+
},
1594+
},
1595+
},
1596+
},
1597+
},
1598+
},
13781599
}
13791600

13801601
for _, c := range cases {
13811602
tc := c
13821603
t.Run(tc.name, func(t *testing.T) {
1383-
t.Parallel()
1604+
if tc.featureGate != "" {
1605+
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.Gates, tc.featureGate, true)()
1606+
}
13841607
tc.cluster.setAPIServerLBDefaults()
13851608
if !reflect.DeepEqual(tc.cluster, tc.output) {
13861609
expected, _ := json.MarshalIndent(tc.output, "", "\t")

0 commit comments

Comments
 (0)