Skip to content

Commit ee00896

Browse files
committed
add support for single stack IPv6
1 parent ac25069 commit ee00896

File tree

6 files changed

+157
-125
lines changed

6 files changed

+157
-125
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure_loadbalancer.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -549,23 +549,21 @@ func (az *Cloud) ensurePublicIPExists(service *v1.Service, pipName string, domai
549549
}
550550
}
551551

552-
if az.ipv6DualStackEnabled {
553-
// TODO: (khenidak) if we ever enable IPv6 single stack, then we should
554-
// not wrap the following in a feature gate
555-
ipv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
556-
if ipv6 {
557-
pip.PublicIPAddressVersion = network.IPv6
558-
klog.V(2).Infof("service(%s): pip(%s) - creating as ipv6 for clusterIP:%v", serviceName, *pip.Name, service.Spec.ClusterIP)
559-
560-
pip.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod = network.Dynamic
561-
if az.useStandardLoadBalancer() {
562-
// standard sku must have static allocation method for ipv6
563-
pip.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod = network.Static
564-
}
565-
} else {
566-
pip.PublicIPAddressVersion = network.IPv4
567-
klog.V(2).Infof("service(%s): pip(%s) - creating as ipv4 for clusterIP:%v", serviceName, *pip.Name, service.Spec.ClusterIP)
552+
// use the same family as the clusterIP as we support IPv6 single stack as well
553+
// as dual-stack clusters
554+
ipv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
555+
if ipv6 {
556+
pip.PublicIPAddressVersion = network.IPv6
557+
klog.V(2).Infof("service(%s): pip(%s) - creating as ipv6 for clusterIP:%v", serviceName, *pip.Name, service.Spec.ClusterIP)
558+
559+
pip.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod = network.Dynamic
560+
if az.useStandardLoadBalancer() {
561+
// standard sku must have static allocation method for ipv6
562+
pip.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod = network.Static
568563
}
564+
} else {
565+
pip.PublicIPAddressVersion = network.IPv4
566+
klog.V(2).Infof("service(%s): pip(%s) - creating as ipv4 for clusterIP:%v", serviceName, *pip.Name, service.Spec.ClusterIP)
569567
}
570568

571569
klog.V(2).Infof("ensurePublicIPExists for service(%s): pip(%s) - creating", serviceName, *pip.Name)
@@ -685,7 +683,7 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service,
685683
klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s/%s) wantLb(%t) resolved load balancer name", serviceName, lbResourceGroup, lbName, wantLb)
686684
lbFrontendIPConfigName := az.getFrontendIPConfigName(service)
687685
lbFrontendIPConfigID := az.getFrontendIPConfigID(lbName, lbResourceGroup, lbFrontendIPConfigName)
688-
lbBackendPoolName := getBackendPoolName(az.ipv6DualStackEnabled, clusterName, service)
686+
lbBackendPoolName := getBackendPoolName(clusterName, service)
689687
lbBackendPoolID := az.getBackendPoolID(lbName, lbResourceGroup, lbBackendPoolName)
690688

691689
lbIdleTimeout, err := getIdleTimeout(service)

staging/src/k8s.io/legacy-cloud-providers/azure/azure_loadbalancer_test.go

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ func TestEnsureLoadBalancerDeleted(t *testing.T) {
363363
}{
364364
{
365365
desc: "external service should be created and deleted successfully",
366-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
366+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
367367
},
368368
{
369369
desc: "internal service should be created and deleted successfully",
@@ -612,7 +612,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
612612
},
613613
},
614614
},
615-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
615+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
616616
wantLB: false,
617617
expectedLB: &network.LoadBalancer{
618618
Name: to.StringPtr("lb1"),
@@ -633,7 +633,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
633633
},
634634
{
635635
desc: "getServiceLoadBalancer shall report error if there're loadbalancer mode annotations on a standard lb",
636-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
636+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
637637
annotations: map[string]string{ServiceAnnotationLoadBalancerMode: "__auto__"},
638638
sku: "standard",
639639
expectedExists: false,
@@ -671,7 +671,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
671671
},
672672
},
673673
},
674-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
674+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
675675
annotations: map[string]string{ServiceAnnotationLoadBalancerMode: "__auto__"},
676676
wantLB: true,
677677
expectedLB: &network.LoadBalancer{
@@ -687,7 +687,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
687687
},
688688
{
689689
desc: "getServiceLoadBalancer shall create a new lb otherwise",
690-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
690+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
691691
expectedLB: &network.LoadBalancer{
692692
Name: to.StringPtr("testCluster"),
693693
Location: to.StringPtr("westus"),
@@ -839,7 +839,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
839839
},
840840
},
841841
lbFrontendIPConfigName: "btest1-name",
842-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
842+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
843843
expectedFlag: false,
844844
expectedError: false,
845845
},
@@ -852,7 +852,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
852852
},
853853
},
854854
lbFrontendIPConfigName: "btest1-name",
855-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
855+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
856856
loadBalancerIP: "1.1.1.1",
857857
exsistingPIPs: []network.PublicIPAddress{
858858
{
@@ -875,7 +875,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
875875
},
876876
},
877877
lbFrontendIPConfigName: "btest1-name",
878-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
878+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
879879
loadBalancerIP: "1.1.1.1",
880880
exsistingPIPs: []network.PublicIPAddress{
881881
{
@@ -898,7 +898,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
898898
},
899899
},
900900
lbFrontendIPConfigName: "btest1-name",
901-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
901+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
902902
loadBalancerIP: "1.1.1.1",
903903
exsistingPIPs: []network.PublicIPAddress{
904904
{
@@ -978,7 +978,7 @@ func TestDeterminePublicIPName(t *testing.T) {
978978
}
979979
for i, test := range testCases {
980980
az := GetTestCloud(ctrl)
981-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
981+
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
982982
service.Spec.LoadBalancerIP = test.loadBalancerIP
983983
for _, existingPIP := range test.exsistingPIPs {
984984
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", "test", existingPIP)
@@ -1007,12 +1007,12 @@ func TestReconcileLoadBalancerRule(t *testing.T) {
10071007
}{
10081008
{
10091009
desc: "reconcileLoadBalancerRule shall return nil if wantLb is false",
1010-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1010+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
10111011
wantLb: false,
10121012
},
10131013
{
10141014
desc: "reconcileLoadBalancerRule shall return corresponding probe and lbRule(blb)",
1015-
service: getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, 80),
1015+
service: getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, false, 80),
10161016
wantLb: true,
10171017
expectedProbes: []network.Probe{
10181018
{
@@ -1053,7 +1053,7 @@ func TestReconcileLoadBalancerRule(t *testing.T) {
10531053
},
10541054
{
10551055
desc: "reconcileLoadBalancerRule shall return corresponding probe and lbRule (slb without tcp reset)",
1056-
service: getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "True"}, 80),
1056+
service: getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "True"}, false, 80),
10571057
loadBalancerSku: "standard",
10581058
wantLb: true,
10591059
expectedProbes: []network.Probe{
@@ -1095,7 +1095,7 @@ func TestReconcileLoadBalancerRule(t *testing.T) {
10951095
},
10961096
{
10971097
desc: "reconcileLoadBalancerRule shall return corresponding probe and lbRule(slb with tcp reset)",
1098-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1098+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
10991099
loadBalancerSku: "standard",
11001100
wantLb: true,
11011101
expectedProbes: []network.Probe{
@@ -1214,10 +1214,10 @@ func TestReconcileLoadBalancer(t *testing.T) {
12141214
ctrl := gomock.NewController(t)
12151215
defer ctrl.Finish()
12161216

1217-
service1 := getTestService("test1", v1.ProtocolTCP, nil, 80)
1217+
service1 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
12181218
basicLb1 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service1, "Basic")
12191219

1220-
service2 := getTestService("test1", v1.ProtocolTCP, nil, 80)
1220+
service2 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
12211221
basicLb2 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("btest1"), service2, "Basic")
12221222
basicLb2.Name = to.StringPtr("testCluster")
12231223
basicLb2.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
@@ -1229,7 +1229,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
12291229
},
12301230
}
12311231

1232-
service3 := getTestService("test1", v1.ProtocolTCP, nil, 80)
1232+
service3 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
12331233
modifiedLb1 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service3, "Basic")
12341234
modifiedLb1.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
12351235
{
@@ -1280,7 +1280,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
12801280
},
12811281
}
12821282

1283-
service4 := getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, 80)
1283+
service4 := getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, false, 80)
12841284
existingSLB := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service4, "Standard")
12851285
existingSLB.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
12861286
{
@@ -1332,7 +1332,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
13321332
},
13331333
}
13341334

1335-
service5 := getTestService("test1", v1.ProtocolTCP, nil, 80)
1335+
service5 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
13361336
slb5 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service5, "Standard")
13371337
slb5.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
13381338
{
@@ -1386,7 +1386,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
13861386
},
13871387
}
13881388

1389-
service6 := getTestService("test1", v1.ProtocolUDP, nil, 80)
1389+
service6 := getTestService("test1", v1.ProtocolUDP, nil, false, 80)
13901390
lb6 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service6, "basic")
13911391
lb6.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{}
13921392
lb6.Probes = &[]network.Probe{}
@@ -1405,7 +1405,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
14051405
},
14061406
}
14071407

1408-
service7 := getTestService("test1", v1.ProtocolUDP, nil, 80)
1408+
service7 := getTestService("test1", v1.ProtocolUDP, nil, false, 80)
14091409
service7.Spec.HealthCheckNodePort = 10081
14101410
service7.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeLocal
14111411
lb7 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service7, "basic")
@@ -1440,7 +1440,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
14401440
},
14411441
}
14421442

1443-
service8 := getTestService("test1", v1.ProtocolTCP, nil, 80)
1443+
service8 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
14441444
lb8 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("anotherRG"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service8, "Standard")
14451445
lb8.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{}
14461446
lb8.Probes = &[]network.Probe{}
@@ -1610,7 +1610,7 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
16101610
defer ctrl.Finish()
16111611

16121612
az := GetTestCloud(ctrl)
1613-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
1613+
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
16141614
internalService := getInternalTestService("test1", 80)
16151615

16161616
PIPClient := newFakeAzurePIPClient(az.Config.SubscriptionID)
@@ -1772,25 +1772,25 @@ func TestReconcileSecurityGroup(t *testing.T) {
17721772
},
17731773
{
17741774
desc: "reconcileSecurityGroup shall report error if no such sg can be found",
1775-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1775+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
17761776
expectedError: true,
17771777
},
17781778
{
17791779
desc: "reconcileSecurityGroup shall report error if wantLb is true and lbIP is nil",
1780-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1780+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
17811781
wantLb: true,
17821782
existingSgs: map[string]network.SecurityGroup{"nsg": {}},
17831783
expectedError: true,
17841784
},
17851785
{
17861786
desc: "reconcileSecurityGroup shall remain the existingSgs intact if nothing needs to be modified",
1787-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1787+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
17881788
existingSgs: map[string]network.SecurityGroup{"nsg": {}},
17891789
expectedSg: &network.SecurityGroup{},
17901790
},
17911791
{
17921792
desc: "reconcileSecurityGroup shall delete unwanted sgs and create needed ones",
1793-
service: getTestService("test1", v1.ProtocolTCP, nil, 80),
1793+
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
17941794
existingSgs: map[string]network.SecurityGroup{"nsg": {
17951795
Name: to.StringPtr("nsg"),
17961796
SecurityGroupPropertiesFormat: &network.SecurityGroupPropertiesFormat{
@@ -1896,7 +1896,7 @@ func TestSafeDeletePublicIP(t *testing.T) {
18961896
if err != nil {
18971897
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
18981898
}
1899-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
1899+
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
19001900
rerr := az.safeDeletePublicIP(&service, "rg", test.pip, test.lb)
19011901
assert.Equal(t, 0, len(*test.lb.FrontendIPConfigurations), "TestCase[%d]: %s", i, test.desc)
19021902
assert.Equal(t, 0, len(*test.lb.LoadBalancingRules), "TestCase[%d]: %s", i, test.desc)
@@ -2007,7 +2007,7 @@ func TestReconcilePublicIP(t *testing.T) {
20072007

20082008
for i, test := range testCases {
20092009
az := GetTestCloud(ctrl)
2010-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
2010+
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
20112011
service.Annotations = test.annotations
20122012
for _, pip := range test.existingPIPs {
20132013
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", to.String(pip.Name), pip)
@@ -2036,6 +2036,7 @@ func TestEnsurePublicIPExists(t *testing.T) {
20362036
foundDNSLabelAnnotation bool
20372037
expectedPIP *network.PublicIPAddress
20382038
expectedID string
2039+
isIPv6 bool
20392040
expectedError bool
20402041
}{
20412042
{
@@ -2072,6 +2073,7 @@ func TestEnsurePublicIPExists(t *testing.T) {
20722073
DNSSettings: &network.PublicIPAddressDNSSettings{
20732074
DomainNameLabel: to.StringPtr("newdns"),
20742075
},
2076+
PublicIPAddressVersion: "IPv4",
20752077
},
20762078
},
20772079
},
@@ -2091,7 +2093,8 @@ func TestEnsurePublicIPExists(t *testing.T) {
20912093
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg" +
20922094
"/providers/Microsoft.Network/publicIPAddresses/pip1"),
20932095
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
2094-
DNSSettings: nil,
2096+
DNSSettings: nil,
2097+
PublicIPAddressVersion: "IPv4",
20952098
},
20962099
},
20972100
},
@@ -2114,14 +2117,41 @@ func TestEnsurePublicIPExists(t *testing.T) {
21142117
DNSSettings: &network.PublicIPAddressDNSSettings{
21152118
DomainNameLabel: to.StringPtr("previousdns"),
21162119
},
2120+
PublicIPAddressVersion: "IPv4",
2121+
},
2122+
},
2123+
},
2124+
{
2125+
desc: "ensurePublicIPExists shall update existed PIP's dns label for IPv6",
2126+
inputDNSLabel: "newdns",
2127+
foundDNSLabelAnnotation: true,
2128+
isIPv6: true,
2129+
existingPIPs: []network.PublicIPAddress{{
2130+
Name: to.StringPtr("pip1"),
2131+
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
2132+
DNSSettings: &network.PublicIPAddressDNSSettings{
2133+
DomainNameLabel: to.StringPtr("previousdns"),
2134+
},
2135+
},
2136+
}},
2137+
expectedPIP: &network.PublicIPAddress{
2138+
Name: to.StringPtr("pip1"),
2139+
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg" +
2140+
"/providers/Microsoft.Network/publicIPAddresses/pip1"),
2141+
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
2142+
DNSSettings: &network.PublicIPAddressDNSSettings{
2143+
DomainNameLabel: to.StringPtr("newdns"),
2144+
},
2145+
PublicIPAllocationMethod: "Dynamic",
2146+
PublicIPAddressVersion: "IPv6",
21172147
},
21182148
},
21192149
},
21202150
}
21212151

21222152
for i, test := range testCases {
21232153
az := GetTestCloud(ctrl)
2124-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
2154+
service := getTestService("test1", v1.ProtocolTCP, nil, test.isIPv6, 80)
21252155
for _, pip := range test.existingPIPs {
21262156
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", to.String(pip.Name), pip)
21272157
if err != nil {
@@ -2176,7 +2206,7 @@ func TestShouldUpdateLoadBalancer(t *testing.T) {
21762206

21772207
for i, test := range testCases {
21782208
az := GetTestCloud(ctrl)
2179-
service := getTestService("test1", v1.ProtocolTCP, nil, 80)
2209+
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
21802210
if test.lbHasDeletionTimestamp {
21812211
service.ObjectMeta.DeletionTimestamp = &metav1.Time{Time: time.Now()}
21822212
}
@@ -2271,7 +2301,7 @@ func TestIsBackendPoolPreConfigured(t *testing.T) {
22712301
if test.isInternalService {
22722302
service = getInternalTestService("test", 80)
22732303
} else {
2274-
service = getTestService("test", v1.ProtocolTCP, nil, 80)
2304+
service = getTestService("test", v1.ProtocolTCP, nil, false, 80)
22752305
}
22762306

22772307
isPreConfigured := az.isBackendPoolPreConfigured(&service)

0 commit comments

Comments
 (0)