@@ -112,123 +112,16 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
112
112
g .deleteWrongNetworkTieredResources (loadBalancerName , lbRefStr , netTier )
113
113
}
114
114
115
- // If the feature gate is not enabled, we check for multiple protocols and error out.
116
- if ! g .AlphaFeatureGate .Enabled (AlphaFeatureMultiProtocolLB ) {
117
- fwdRuleExists , fwdRuleNeedsUpdate , fwdRuleIP , err := g .forwardingRuleNeedsUpdate (loadBalancerName , g .region , requestedIP , ports )
118
- if err != nil {
119
- return nil , err
120
- }
121
- if ! fwdRuleExists {
122
- klog .V (2 ).Infof ("ensureExternalLoadBalancer(%s): Forwarding rule %v doesn't exist." , lbRefStr , loadBalancerName )
123
- }
124
- // Single-protocol logic
125
- ipAddressToUse , isSafeToReleaseIP , err := g .ensureIPAddress (loadBalancerName , lbRefStr , apiService .Spec .LoadBalancerIP , fwdRuleIP , netTier )
126
- if err != nil {
127
- return nil , err
128
- }
129
- defer func () {
130
- if isSafeToReleaseIP {
131
- if err := g .DeleteRegionAddress (loadBalancerName , g .region ); err != nil && ! isNotFound (err ) {
132
- klog .Errorf ("ensureExternalLoadBalancer(%s): Failed to release static IP %s in region %v: %v." , lbRefStr , ipAddressToUse , g .region , err )
133
- } else if isNotFound (err ) {
134
- klog .V (2 ).Infof ("ensureExternalLoadBalancer(%s): IP address %s is not reserved." , lbRefStr , ipAddressToUse )
135
- } else {
136
- klog .Infof ("ensureExternalLoadBalancer(%s): Released static IP %s." , lbRefStr , ipAddressToUse )
137
- }
138
- } else {
139
- klog .Warningf ("ensureExternalLoadBalancer(%s): Orphaning static IP %s in region %v: %v." , lbRefStr , ipAddressToUse , g .region , err )
140
- }
141
- }()
142
-
143
- sourceRanges , err := servicehelpers .GetLoadBalancerSourceRanges (apiService )
144
- if err != nil {
145
- return nil , err
146
- }
147
-
148
- firewallExists , firewallNeedsUpdate , err := g .firewallNeedsUpdate (loadBalancerName , serviceName .String (), ipAddressToUse , ports , sourceRanges )
149
- if err != nil {
150
- return nil , err
151
- }
152
-
153
- if firewallNeedsUpdate {
154
- desc := makeFirewallDescription (serviceName .String (), ipAddressToUse )
155
- if firewallExists {
156
- klog .Infof ("ensureExternalLoadBalancer(%s): Updating firewall." , lbRefStr )
157
- if err := g .updateFirewall (apiService , MakeFirewallName (loadBalancerName ), desc , ipAddressToUse , sourceRanges , ports , hosts ); err != nil {
158
- return nil , err
159
- }
160
- klog .Infof ("ensureExternalLoadBalancer(%s): Updated firewall." , lbRefStr )
161
- } else {
162
- klog .Infof ("ensureExternalLoadBalancer(%s): Creating firewall." , lbRefStr )
163
- if err := g .createFirewall (apiService , MakeFirewallName (loadBalancerName ), desc , ipAddressToUse , sourceRanges , ports , hosts ); err != nil {
164
- return nil , err
165
- }
166
- klog .Infof ("ensureExternalLoadBalancer(%s): Created firewall." , lbRefStr )
167
- }
168
- }
169
-
170
- tpExists , tpNeedsRecreation , err := g .targetPoolNeedsRecreation (loadBalancerName , g .region , apiService .Spec .SessionAffinity )
171
- if err != nil {
172
- return nil , err
173
- }
174
- if ! tpExists {
175
- klog .Infof ("ensureExternalLoadBalancer(%s): Target pool for service doesn't exist." , lbRefStr )
176
- }
177
-
178
- var hcToCreate , hcToDelete * compute.HttpHealthCheck
179
- hcLocalTrafficExisting , err := g .GetHTTPHealthCheck (loadBalancerName )
180
- if err != nil && ! isHTTPErrorCode (err , http .StatusNotFound ) {
181
- return nil , fmt .Errorf ("error checking HTTP health check for load balancer (%s): %v" , lbRefStr , err )
182
- }
183
- if path , healthCheckNodePort := servicehelpers .GetServiceHealthCheckPathPort (apiService ); path != "" {
184
- klog .V (4 ).Infof ("ensureExternalLoadBalancer(%s): Service needs local traffic health checks on: %d%s." , lbRefStr , healthCheckNodePort , path )
185
- if hcLocalTrafficExisting == nil {
186
- klog .V (2 ).Infof ("ensureExternalLoadBalancer(%s): Updating from nodes health checks to local traffic health checks." , lbRefStr )
187
- hcToDelete = makeHTTPHealthCheck (MakeNodesHealthCheckName (clusterID ), GetNodesHealthCheckPath (), GetNodesHealthCheckPort ())
188
- tpNeedsRecreation = true
189
- }
190
- hcToCreate = makeHTTPHealthCheck (loadBalancerName , path , healthCheckNodePort )
191
- } else {
192
- klog .V (4 ).Infof ("ensureExternalLoadBalancer(%s): Service needs nodes health checks." , lbRefStr )
193
- if hcLocalTrafficExisting != nil {
194
- klog .V (2 ).Infof ("ensureExternalLoadBalancer(%s): Updating from local traffic health checks to nodes health checks." , lbRefStr )
195
- hcToDelete = hcLocalTrafficExisting
196
- tpNeedsRecreation = true
197
- }
198
- hcToCreate = makeHTTPHealthCheck (MakeNodesHealthCheckName (clusterID ), GetNodesHealthCheckPath (), GetNodesHealthCheckPort ())
199
- }
200
-
201
- if fwdRuleExists && (fwdRuleNeedsUpdate || tpNeedsRecreation ) {
202
- isSafeToReleaseIP = false
203
- if err := g .DeleteRegionForwardingRule (loadBalancerName , g .region ); err != nil && ! isNotFound (err ) {
204
- return nil , fmt .Errorf ("failed to delete existing forwarding rule for load balancer (%s) update: %v" , lbRefStr , err )
205
- }
206
- klog .Infof ("ensureExternalLoadBalancer(%s): Deleted forwarding rule." , lbRefStr )
207
- }
208
-
209
- if err := g .ensureTargetPoolAndHealthCheck (tpExists , tpNeedsRecreation , apiService , loadBalancerName , clusterID , ipAddressToUse , hosts , hcToCreate , hcToDelete ); err != nil {
210
- return nil , err
211
- }
212
-
213
- if tpNeedsRecreation || fwdRuleNeedsUpdate {
214
- klog .Infof ("ensureExternalLoadBalancer(%s): Creating forwarding rule, IP %s (tier: %s)." , lbRefStr , ipAddressToUse , netTier )
215
- if err := createForwardingRule (g , loadBalancerName , serviceName .String (), g .region , ipAddressToUse , g .targetPoolURL (loadBalancerName ), ports , netTier , g .enableDiscretePortForwarding ); err != nil {
216
- return nil , fmt .Errorf ("failed to create forwarding rule for load balancer (%s): %v" , lbRefStr , err )
217
- }
218
- isSafeToReleaseIP = true
219
- klog .Infof ("ensureExternalLoadBalancer(%s): Created forwarding rule, IP %s." , lbRefStr , ipAddressToUse )
115
+ groupedPorts := groupPortsByProtocol (ports )
116
+ if ! g .AlphaFeatureGate .Enabled (AlphaFeatureMultiProtocolLB ) && len (groupedPorts ) > 1 {
117
+ var protocols []string
118
+ for p := range groupedPorts {
119
+ protocols = append (protocols , string (p ))
220
120
}
221
-
222
- status := & v1.LoadBalancerStatus {}
223
- status .Ingress = []v1.LoadBalancerIngress {{IP : ipAddressToUse }}
224
-
225
- return status , nil
121
+ return nil , fmt .Errorf ("load balancer with multiple protocols (%s) is not supported when AlphaFeatureMultiProtocolLB is disabled" , strings .Join (protocols , "," ))
226
122
}
227
123
228
- // Multi-protocol logic starts here
229
- groupedPorts := groupPortsByProtocol (ports )
230
124
var fwdRuleIP string
231
-
232
125
// We need to determine the IP address for all forwarding rules.
233
126
// We check if any of the forwarding rules already exist and use their IP.
234
127
for protocol := range groupedPorts {
@@ -255,29 +148,8 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
255
148
256
149
// Make sure we know which IP address will be used and have properly reserved
257
150
// it as static before moving forward with the rest of our operations.
258
- //
259
- // We use static IP addresses when updating a load balancer to ensure that we
260
- // can replace the load balancer's other components without changing the
261
- // address its service is reachable on. We do it this way rather than always
262
- // keeping the static IP around even though this is more complicated because
263
- // it makes it less likely that we'll run into quota issues. Only 7 static
264
- // IP addresses are allowed per region by default.
265
- //
266
- // We could let an IP be allocated for us when the forwarding rule is created,
267
- // but we need the IP to set up the firewall rule, and we want to keep the
268
- // forwarding rule creation as the last thing that needs to be done in this
269
- // function in order to maintain the invariant that "if the forwarding rule
270
- // exists, the LB has been fully created".
271
151
ipAddressToUse := ""
272
-
273
- // Through this process we try to keep track of whether it is safe to
274
- // release the IP that was allocated. If the user specifically asked for
275
- // an IP, we assume they are managing it themselves. Otherwise, we will
276
- // release the IP in case of early-terminating failure or upon successful
277
- // creating of the LB.
278
- // TODO(#36535): boil this logic down into a set of component functions
279
- // and key the flag values off of errors returned.
280
- isUserOwnedIP := false // if this is set, we never release the IP
152
+ isUserOwnedIP := false
281
153
isSafeToReleaseIP := false
282
154
283
155
defer func () {
@@ -419,9 +291,14 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
419
291
420
292
// Then, iterate over the protocols and create/update forwarding rules.
421
293
for protocol , protocolPorts := range groupedPorts {
422
- frName := g .getProtocolForwardingRuleName (loadBalancerName , protocol )
423
- // If the old forwarding rule matches this protocol, use its name.
424
- if fwd != nil && fwd .IPProtocol == string (protocol ) {
294
+ var frName string
295
+ if g .AlphaFeatureGate .Enabled (AlphaFeatureMultiProtocolLB ) {
296
+ frName = g .getProtocolForwardingRuleName (loadBalancerName , protocol )
297
+ // If the old forwarding rule matches this protocol, use its name.
298
+ if fwd != nil && fwd .IPProtocol == string (protocol ) {
299
+ frName = loadBalancerName
300
+ }
301
+ } else {
425
302
frName = loadBalancerName
426
303
}
427
304
@@ -430,7 +307,7 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
430
307
return nil , err
431
308
}
432
309
433
- if needsUpdate {
310
+ if needsUpdate || tpNeedsRecreation {
434
311
if exists {
435
312
if err := g .DeleteRegionForwardingRule (frName , g .region ); err != nil && ! isNotFound (err ) {
436
313
return nil , err
@@ -445,31 +322,33 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
445
322
}
446
323
447
324
// Garbage collect old forwarding rules.
448
- activeFRNames := sets .NewString ()
449
- for protocol := range groupedPorts {
450
- activeFRNames .Insert (g .getProtocolForwardingRuleName (loadBalancerName , protocol ))
451
- }
452
- // Check for the old forwarding rule name.
453
- if fwd != nil {
454
- protocol , err := getProtocol (fwd .IPProtocol )
455
- if err != nil {
456
- return nil , err
325
+ if g .AlphaFeatureGate .Enabled (AlphaFeatureMultiProtocolLB ) {
326
+ activeFRNames := sets .NewString ()
327
+ for protocol := range groupedPorts {
328
+ activeFRNames .Insert (g .getProtocolForwardingRuleName (loadBalancerName , protocol ))
457
329
}
458
- if _ , ok := groupedPorts [protocol ]; ok {
459
- activeFRNames .Insert (loadBalancerName )
330
+ // Check for the old forwarding rule name.
331
+ if fwd != nil {
332
+ protocol , err := getProtocol (fwd .IPProtocol )
333
+ if err != nil {
334
+ return nil , err
335
+ }
336
+ if _ , ok := groupedPorts [protocol ]; ok {
337
+ activeFRNames .Insert (loadBalancerName )
338
+ }
460
339
}
461
- }
462
340
463
- // List all forwarding rules for this service and delete the ones that are not active.
464
- frs , err := g .ListRegionForwardingRules (g .region )
465
- if err != nil {
466
- return nil , err
467
- }
468
- for _ , fr := range frs {
469
- if strings .HasPrefix (fr .Name , loadBalancerName ) && ! activeFRNames .Has (fr .Name ) {
470
- klog .Infof ("ensureExternalLoadBalancer(%s): Deleting orphaned forwarding rule %s." , lbRefStr , fr .Name )
471
- if err := g .DeleteRegionForwardingRule (fr .Name , g .region ); err != nil && ! isNotFound (err ) {
472
- return nil , err
341
+ // List all forwarding rules for this service and delete the ones that are not active.
342
+ frs , err := g .ListRegionForwardingRules (g .region )
343
+ if err != nil {
344
+ return nil , err
345
+ }
346
+ for _ , fr := range frs {
347
+ if strings .HasPrefix (fr .Name , loadBalancerName ) && ! activeFRNames .Has (fr .Name ) {
348
+ klog .Infof ("ensureExternalLoadBalancer(%s): Deleting orphaned forwarding rule %s." , lbRefStr , fr .Name )
349
+ if err := g .DeleteRegionForwardingRule (fr .Name , g .region ); err != nil && ! isNotFound (err ) {
350
+ return nil , err
351
+ }
473
352
}
474
353
}
475
354
}
@@ -481,41 +360,6 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
481
360
return status , nil
482
361
}
483
362
484
- func (g * Cloud ) ensureIPAddress (loadBalancerName , lbRefStr , requestedIP , fwdRuleIP string , netTier cloud.NetworkTier ) (ipAddress string , isSafeToReleaseIP bool , err error ) {
485
- // Make sure we know which IP address will be used and have properly reserved
486
- // it as static before moving forward with the rest of our operations.
487
- ipAddressToUse := ""
488
- isUserOwnedIP := false
489
-
490
- if requestedIP != "" {
491
- // If user requests a specific IP address, verify first. No mutation to
492
- // the GCE resources will be performed in the verification process.
493
- isUserOwnedIP , err = verifyUserRequestedIP (g , g .region , requestedIP , fwdRuleIP , lbRefStr , netTier )
494
- if err != nil {
495
- return "" , false , err
496
- }
497
- ipAddressToUse = requestedIP
498
- }
499
-
500
- if ! isUserOwnedIP {
501
- // If we are not using the user-owned IP, either promote the
502
- // emphemeral IP used by the fwd rule, or create a new static IP.
503
- ipAddr , existed , err := ensureStaticIP (g , loadBalancerName , lbRefStr , g .region , fwdRuleIP , netTier )
504
- if err != nil {
505
- return "" , false , fmt .Errorf ("failed to ensure a static IP for load balancer (%s): %v" , lbRefStr , err )
506
- }
507
- klog .Infof ("ensureExternalLoadBalancer(%s): Ensured IP address %s (tier: %s)." , lbRefStr , ipAddr , netTier )
508
- // If the IP was not owned by the user, but it already existed, it
509
- // could indicate that the previous update cycle failed. We can use
510
- // this IP and try to run through the process again, but we should
511
- // not release the IP unless it is explicitly flagged as OK.
512
- isSafeToReleaseIP = ! existed
513
- ipAddressToUse = ipAddr
514
- }
515
-
516
- return ipAddressToUse , isSafeToReleaseIP , nil
517
- }
518
-
519
363
520
364
// updateExternalLoadBalancer is the external implementation of LoadBalancer.UpdateLoadBalancer.
521
365
func (g * Cloud ) updateExternalLoadBalancer (clusterName string , service * v1.Service , nodes []* v1.Node ) error {
0 commit comments