Skip to content

Commit d9b77d5

Browse files
committed
azure: Add support for single zone NAT gateway
Adding the option for the users to create a NAT gateway for the compute nodes as an option to replace the traditional load balancer setup. This is only for a single NAT gateway in the compute subnet as CAPZ expects an outbound LB for control planes.
1 parent 25b5d21 commit d9b77d5

6 files changed

Lines changed: 41 additions & 48 deletions

File tree

data/data/install.openshift.io_installconfigs.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4847,13 +4847,12 @@ spec:
48474847
type: string
48484848
outboundType:
48494849
default: Loadbalancer
4850-
description: |-
4851-
OutboundType is a strategy for how egress from cluster is achieved. When not specified default is "Loadbalancer".
4852-
"NatGateway" is only available in TechPreview.
4850+
description: OutboundType is a strategy for how egress from cluster
4851+
is achieved. When not specified default is "Loadbalancer".
48534852
enum:
48544853
- ""
48554854
- Loadbalancer
4856-
- NatGateway
4855+
- NATGatewaySingleZone
48574856
- UserDefinedRouting
48584857
type: string
48594858
region:

pkg/asset/manifests/azure/cluster.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,13 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
8383
// CAPZ enables NAT Gateways by default, so we are using this hack to disable
8484
// nat gateways when we prefer to use load balancers for node egress.
8585
nodeSubnetID := ""
86-
if installConfig.Config.Platform.Azure.OutboundType != azure.NatGatewayOutboundType {
87-
// Because the node subnet does not already exist, we are using an arbitrary value.
88-
// We could populate this with the proper subnet ID in the case of BYO VNET, but
89-
// the value currently has no practical effect.
86+
switch installConfig.Config.Platform.Azure.OutboundType {
87+
// Because the node subnet does not already exist, we are using an arbitrary value.
88+
// We could populate this with the proper subnet ID in the case of BYO VNET, but
89+
// the value currently has no practical effect.
90+
case azure.LoadbalancerOutboundType:
91+
fallthrough
92+
case azure.UserDefinedRoutingOutboundType:
9093
nodeSubnetID = "UNKNOWN"
9194
}
9295

@@ -104,6 +107,7 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
104107
Name: clusterID.InfraID,
105108
FrontendIPsCount: to.Ptr(int32(1)),
106109
}
110+
107111
if installConfig.Config.Platform.Azure.OutboundType == azure.UserDefinedRoutingOutboundType {
108112
controlPlaneOutboundLB = nil
109113
}
@@ -175,6 +179,24 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
175179

176180
azEnv := string(installConfig.Azure.CloudName)
177181

182+
computeSubnetSpec := capz.SubnetSpec{
183+
ID: nodeSubnetID,
184+
SubnetClassSpec: capz.SubnetClassSpec{
185+
Name: computeSubnet,
186+
Role: capz.SubnetNode,
187+
CIDRBlocks: []string{
188+
subnets[1].String(),
189+
},
190+
},
191+
SecurityGroup: securityGroup,
192+
}
193+
194+
if installConfig.Config.Azure.OutboundType == azure.NATGatewaySingleZoneOutboundType {
195+
computeSubnetSpec.NatGateway = capz.NatGateway{
196+
NatGatewayClassSpec: capz.NatGatewayClassSpec{Name: fmt.Sprintf("%s-natgw", clusterID.InfraID)},
197+
}
198+
}
199+
178200
azureCluster := &capz.AzureCluster{
179201
ObjectMeta: metav1.ObjectMeta{
180202
Name: clusterID.InfraID,
@@ -225,17 +247,7 @@ func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID
225247
},
226248
SecurityGroup: securityGroup,
227249
},
228-
{
229-
ID: nodeSubnetID,
230-
SubnetClassSpec: capz.SubnetClassSpec{
231-
Name: computeSubnet,
232-
Role: capz.SubnetNode,
233-
CIDRBlocks: []string{
234-
subnets[1].String(),
235-
},
236-
},
237-
SecurityGroup: securityGroup,
238-
},
250+
computeSubnetSpec,
239251
},
240252
},
241253
},

pkg/explain/printer_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,8 @@ platform configuration.
332332
333333
outboundType <string>
334334
Default: "Loadbalancer"
335-
Valid Values: "","Loadbalancer","NatGateway","UserDefinedRouting"
335+
Valid Values: "","Loadbalancer","NATGatewaySingleZone","UserDefinedRouting"
336336
OutboundType is a strategy for how egress from cluster is achieved. When not specified default is "Loadbalancer".
337-
"NatGateway" is only available in TechPreview.
338337
339338
region <string> -required-
340339
Region specifies the Azure region where the cluster will be created.

pkg/types/azure/platform.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import (
99
var aro bool
1010

1111
// OutboundType is a strategy for how egress from cluster is achieved.
12-
// +kubebuilder:validation:Enum="";Loadbalancer;NatGateway;UserDefinedRouting
12+
// +kubebuilder:validation:Enum="";Loadbalancer;NATGatewaySingleZone;UserDefinedRouting
1313
type OutboundType string
1414

1515
const (
1616
// LoadbalancerOutboundType uses Standard loadbalancer for egress from the cluster.
1717
// see https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections#lb
1818
LoadbalancerOutboundType OutboundType = "Loadbalancer"
1919

20-
// NatGatewayOutboundType uses NAT gateway for egress from the cluster
20+
// NATGatewaySingleZoneOutboundType uses a single (non-zone-resilient) NAT Gateway for compute node outbound access.
2121
// see https://learn.microsoft.com/en-us/azure/virtual-network/nat-gateway/nat-gateway-resource
22-
NatGatewayOutboundType OutboundType = "NatGateway"
22+
NATGatewaySingleZoneOutboundType OutboundType = "NATGatewaySingleZone"
2323

2424
// UserDefinedRoutingOutboundType uses user defined routing for egress from the cluster.
2525
// see https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview
@@ -76,7 +76,6 @@ type Platform struct {
7676
CloudName CloudEnvironment `json:"cloudName,omitempty"`
7777

7878
// OutboundType is a strategy for how egress from cluster is achieved. When not specified default is "Loadbalancer".
79-
// "NatGateway" is only available in TechPreview.
8079
//
8180
// +kubebuilder:default=Loadbalancer
8281
// +optional

pkg/types/azure/validation/platform.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"k8s.io/apimachinery/pkg/util/validation/field"
1010

11-
configv1 "github.com/openshift/api/config/v1"
1211
"github.com/openshift/installer/pkg/types"
1312
"github.com/openshift/installer/pkg/types/azure"
1413
)
@@ -98,13 +97,10 @@ func ValidatePlatform(p *azure.Platform, publish types.PublishingStrategy, fldPa
9897
if p.OutboundType == azure.UserDefinedRoutingOutboundType && p.VirtualNetwork == "" {
9998
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, fmt.Sprintf("%s is only allowed when installing to pre-existing network", azure.UserDefinedRoutingOutboundType)))
10099
}
101-
if p.OutboundType == azure.NatGatewayOutboundType {
102-
if ic.FeatureSet != configv1.TechPreviewNoUpgrade {
103-
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, "not supported in this feature set"))
104-
}
100+
if p.OutboundType == azure.NATGatewaySingleZoneOutboundType {
105101
if p.VirtualNetwork != "" {
106102
// For now, BYO network and NAT gateways are not compatible
107-
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, fmt.Sprintf("%s is not allowed when installing to pre-existing network", azure.NatGatewayOutboundType)))
103+
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, fmt.Sprintf("%s is not allowed when installing to pre-existing network", p.OutboundType)))
108104
}
109105
}
110106

@@ -242,9 +238,9 @@ func findDuplicateTagKeys(tagSet map[string]string) error {
242238

243239
var (
244240
validOutboundTypes = map[azure.OutboundType]struct{}{
245-
azure.LoadbalancerOutboundType: {},
246-
azure.NatGatewayOutboundType: {},
247-
azure.UserDefinedRoutingOutboundType: {},
241+
azure.LoadbalancerOutboundType: {},
242+
azure.NATGatewaySingleZoneOutboundType: {},
243+
azure.UserDefinedRoutingOutboundType: {},
248244
}
249245

250246
validOutboundTypeValues = func() []string {
@@ -262,10 +258,7 @@ func validateAzureStack(p *azure.Platform, fldPath *field.Path) field.ErrorList
262258
if p.ARMEndpoint == "" {
263259
allErrs = append(allErrs, field.Required(fldPath.Child("armEndpoint"), "ARM endpoint must be set when installing on Azure Stack"))
264260
}
265-
switch p.OutboundType {
266-
case azure.UserDefinedRoutingOutboundType:
267-
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, "Azure Stack does not support user-defined routing"))
268-
case azure.NatGatewayOutboundType:
261+
if p.OutboundType != azure.LoadbalancerOutboundType {
269262
allErrs = append(allErrs, field.Invalid(fldPath.Child("outboundType"), p.OutboundType, "Azure Stack does not support NAT routing currently"))
270263
}
271264
return allErrs

pkg/types/azure/validation/platform_test.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func TestValidatePlatform(t *testing.T) {
134134
p.OutboundType = "random-egress"
135135
return p
136136
}(),
137-
expected: `^test-path\.outboundType: Unsupported value: "random-egress": supported values: "Loadbalancer", "NatGateway", "UserDefinedRouting"$`,
137+
expected: `^test-path\.outboundType: Unsupported value: "random-egress": supported values: "Loadbalancer", "NATGatewaySingleZone", "UserDefinedRouting"$`,
138138
},
139139
{
140140
name: "invalid user defined type",
@@ -145,15 +145,6 @@ func TestValidatePlatform(t *testing.T) {
145145
}(),
146146
expected: `^test-path\.outboundType: Invalid value: "UserDefinedRouting": UserDefinedRouting is only allowed when installing to pre-existing network$`,
147147
},
148-
{
149-
name: "invalid nat gateway",
150-
platform: func() *azure.Platform {
151-
p := validPlatform()
152-
p.OutboundType = azure.NatGatewayOutboundType
153-
return p
154-
}(),
155-
expected: `^test-path\.outboundType: Invalid value: "NatGateway": not supported in this feature set$`,
156-
},
157148
{
158149
name: "missing key vault name",
159150
platform: func() *azure.Platform {

0 commit comments

Comments
 (0)