Skip to content

Commit 2f2ab91

Browse files
author
Kubernetes Submit Queue
authored
Merge pull request kubernetes#55752 from kevinkim9264/fix-azure-loadbalancer
Automatic merge from submit-queue (batch tested with PRs 55812, 55752, 55447, 55848, 50984). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Azure Load Balancer reconciliation should consider all Kubernetes-controlled properties of a LB NSG **What this PR does / why we need it**: This PR refers to issue kubernetes#55733 With this PR, Kubernetes will update Azure nsg rules based on not just name, but also based on other properties such as destination port range and destination ip address. We need it because right now Kubernetes will detect the difference and update only if there is difference in Name of nsg rule. It's been working fine for changing destination port range and source IP address because these two are part of the Name. (which external users should not assume) Basically right now, Kubernetes won't detect the difference if I go ahead and change any part of nsg rule using port UI. This PR will let Kubernetes detect the difference and always try to reconcile nsg rules with service definition. **Which issue(s) this PR fixes** : Fixes kubernetes#55733 **Special notes for your reviewer**: None **Release note**: ```release-note Kubernetes update Azure nsg rules based on not just difference in Name, but also in Protocol, SourcePortRange, DestinationPortRange, SourceAddressPrefix, DestinationAddressPrefix, Access, and Direction. ```
2 parents 25ebf87 + 8514537 commit 2f2ab91

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

pkg/cloudprovider/providers/azure/azure_loadbalancer.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,11 +1205,39 @@ func findRule(rules []network.LoadBalancingRule, rule network.LoadBalancingRule)
12051205
return false
12061206
}
12071207

1208+
// This compares rule's Name, Protocol, SourcePortRange, DestinationPortRange, SourceAddressPrefix, Access, and Direction.
1209+
// Note that it compares rule's DestinationAddressPrefix only when it's not consolidated rule as such rule does not have DestinationAddressPrefix defined.
1210+
// We intentionally do not compare DestinationAddressPrefixes in consolidated case because reconcileSecurityRule has to consider the two rules equal,
1211+
// despite different DestinationAddressPrefixes, in order to give it a chance to consolidate the two rules.
12081212
func findSecurityRule(rules []network.SecurityRule, rule network.SecurityRule) bool {
12091213
for _, existingRule := range rules {
1210-
if strings.EqualFold(*existingRule.Name, *rule.Name) {
1211-
return true
1214+
if !strings.EqualFold(*existingRule.Name, *rule.Name) {
1215+
continue
1216+
}
1217+
if existingRule.Protocol != rule.Protocol {
1218+
continue
1219+
}
1220+
if !strings.EqualFold(*existingRule.SourcePortRange, *rule.SourcePortRange) {
1221+
continue
1222+
}
1223+
if !strings.EqualFold(*existingRule.DestinationPortRange, *rule.DestinationPortRange) {
1224+
continue
1225+
}
1226+
if !strings.EqualFold(*existingRule.SourceAddressPrefix, *rule.SourceAddressPrefix) {
1227+
continue
1228+
}
1229+
if !allowsConsolidation(existingRule) && !allowsConsolidation(rule) {
1230+
if !strings.EqualFold(*existingRule.DestinationAddressPrefix, *rule.DestinationAddressPrefix) {
1231+
continue
1232+
}
1233+
}
1234+
if existingRule.Access != rule.Access {
1235+
continue
1236+
}
1237+
if existingRule.Direction != rule.Direction {
1238+
continue
12121239
}
1240+
return true
12131241
}
12141242
return false
12151243
}

pkg/cloudprovider/providers/azure/azure_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,36 @@ func TestReconcileLoadBalancerAddServiceOnInternalSubnet(t *testing.T) {
392392
validateLoadBalancer(t, lb, svc)
393393
}
394394

395+
func TestReconcileSecurityGroupFromAnyDestinationAddressPrefixToLoadBalancerIP(t *testing.T) {
396+
az := getTestCloud()
397+
svc1 := getTestService("serviceea", v1.ProtocolTCP, 80)
398+
svc1.Spec.LoadBalancerIP = "192.168.0.0"
399+
sg := getTestSecurityGroup(az)
400+
// Simulate a pre-Kubernetes 1.8 NSG, where we do not specify the destination address prefix
401+
sg, err := az.reconcileSecurityGroup(testClusterName, &svc1, to.StringPtr(""), true)
402+
if err != nil {
403+
t.Errorf("Unexpected error: %q", err)
404+
}
405+
sg, err = az.reconcileSecurityGroup(testClusterName, &svc1, to.StringPtr(svc1.Spec.LoadBalancerIP), true)
406+
if err != nil {
407+
t.Errorf("Unexpected error: %q", err)
408+
}
409+
validateSecurityGroup(t, sg, svc1)
410+
}
411+
412+
func TestReconcileSecurityGroupDynamicLoadBalancerIP(t *testing.T) {
413+
az := getTestCloud()
414+
svc1 := getTestService("servicea", v1.ProtocolTCP, 80)
415+
svc1.Spec.LoadBalancerIP = ""
416+
sg := getTestSecurityGroup(az)
417+
dynamicallyAssignedIP := "192.168.0.0"
418+
sg, err := az.reconcileSecurityGroup(testClusterName, &svc1, to.StringPtr(dynamicallyAssignedIP), true)
419+
if err != nil {
420+
t.Errorf("unexpected error: %q", err)
421+
}
422+
validateSecurityGroup(t, sg, svc1)
423+
}
424+
395425
// Test addition of services on an internal LB using both default and explicit subnets.
396426
func TestReconcileLoadBalancerAddServicesOnMultipleSubnets(t *testing.T) {
397427
az := getTestCloud()

0 commit comments

Comments
 (0)