Skip to content

Commit d3e8572

Browse files
committed
cluster ip allocator should check first on the legacy allocators
Kubernetes clusters allow to define an IPv6 range of /108 for IPv6 despite the old allocators will only use the first /112 of that range. The new allocators does not have this limitation, so they can allocate IPs on the whole space, the problem happens on upgrades from clusters that were already using this size, since the new allocators by default will try to allocate addresses that works for both new and old allocatos to allow safe upgrades. The new allocators, when configured to keep compatibility with the old allocators, must try first to allocate an IP that is compatible with the old allocators and only fall back to the new behavior if it is not possible.
1 parent f6f0680 commit d3e8572

File tree

3 files changed

+22
-23
lines changed

3 files changed

+22
-23
lines changed

pkg/registry/core/service/ipallocator/cidrallocator.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,20 @@ func (c *MetaAllocator) Allocate(ip net.IP) error {
361361
}
362362

363363
func (c *MetaAllocator) AllocateNextService(service *api.Service) (net.IP, error) {
364+
// If the cluster is still using the old allocators use them first to try to
365+
// get an IP address to keep backwards compatibility.
366+
if !utilfeature.DefaultFeatureGate.Enabled(features.DisableAllocatorDualWrite) {
367+
ip, err := c.bitmapAllocator.AllocateNext()
368+
if err == nil {
369+
allocator, err := c.getAllocator(ip, true)
370+
if err != nil {
371+
return nil, err
372+
}
373+
return ip, allocator.AllocateService(service, ip)
374+
} else {
375+
klog.Infof("no IP address available on the old ClusterIP allocator, trying to get a new address using the new allocators")
376+
}
377+
}
364378
c.mu.Lock()
365379
defer c.mu.Unlock()
366380
// TODO(aojea) add strategy to return a random allocator but
@@ -376,15 +390,6 @@ func (c *MetaAllocator) AllocateNextService(service *api.Service) (net.IP, error
376390
}
377391
ip, err := item.allocator.AllocateNextService(service)
378392
if err == nil {
379-
if !utilfeature.DefaultFeatureGate.Enabled(features.DisableAllocatorDualWrite) {
380-
cidr := c.bitmapAllocator.CIDR()
381-
if cidr.Contains(ip) {
382-
err := c.bitmapAllocator.Allocate(ip)
383-
if err != nil {
384-
continue
385-
}
386-
}
387-
}
388393
return ip, nil
389394
}
390395
}

pkg/registry/core/service/ipallocator/cidrallocator_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,6 @@ func TestCIDRAllocateDualWrite(t *testing.T) {
484484
if f := r.Free(); f != 0 {
485485
t.Errorf("free: %d", f)
486486
}
487-
if _, err := r.AllocateNext(); err == nil {
488-
t.Error(err)
489-
}
490487

491488
cidr := newServiceCIDR("test", "192.168.0.0/28")
492489
_, err = r.client.ServiceCIDRs().Create(context.Background(), cidr, metav1.CreateOptions{})
@@ -554,9 +551,6 @@ func TestCIDRAllocateDualWriteCollision(t *testing.T) {
554551
if f := r.Free(); f != 0 {
555552
t.Errorf("free: %d", f)
556553
}
557-
if _, err := r.AllocateNext(); err == nil {
558-
t.Error(err)
559-
}
560554

561555
cidr := newServiceCIDR("test", "192.168.0.0/28")
562556
_, err = r.client.ServiceCIDRs().Create(context.Background(), cidr, metav1.CreateOptions{})

test/integration/dualstack/dualstack_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func TestCreateServiceSingleStackIPv6(t *testing.T) {
298298
apiServerOptions,
299299
[]string{
300300
fmt.Sprintf("--runtime-config=networking.k8s.io/v1beta1=%v", enableMultiServiceCIDR),
301-
"--service-cluster-ip-range=2001:db8:1::/112",
301+
"--service-cluster-ip-range=2001:db8:1::/108",
302302
"--advertise-address=2001:db8::10",
303303
"--disable-admission-plugins=ServiceAccount",
304304
fmt.Sprintf("--feature-gates=%s=%v,%s=%v", features.MultiCIDRServiceAllocator, enableMultiServiceCIDR, features.DisableAllocatorDualWrite, disableAllocatorDualWrite),
@@ -529,7 +529,7 @@ func TestCreateServiceDualStackIPv4IPv6(t *testing.T) {
529529
apiServerOptions,
530530
[]string{
531531
fmt.Sprintf("--runtime-config=networking.k8s.io/v1beta1=%v", enableMultiServiceCIDR),
532-
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/112",
532+
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/108",
533533
"--advertise-address=10.0.0.1",
534534
"--disable-admission-plugins=ServiceAccount",
535535
fmt.Sprintf("--feature-gates=%s=%v,%s=%v", features.MultiCIDRServiceAllocator, enableMultiServiceCIDR, features.DisableAllocatorDualWrite, disableAllocatorDualWrite),
@@ -808,7 +808,7 @@ func TestCreateServiceDualStackIPv6IPv4(t *testing.T) {
808808
apiServerOptions,
809809
[]string{
810810
fmt.Sprintf("--runtime-config=networking.k8s.io/v1beta1=%v", enableMultiServiceCIDR),
811-
"--service-cluster-ip-range=2001:db8:1::/112,10.0.0.0/16",
811+
"--service-cluster-ip-range=2001:db8:1::/108,10.0.0.0/16",
812812
"--advertise-address=2001:db8::10",
813813
"--disable-admission-plugins=ServiceAccount",
814814
fmt.Sprintf("--feature-gates=%s=%v,%s=%v", features.MultiCIDRServiceAllocator, enableMultiServiceCIDR, features.DisableAllocatorDualWrite, disableAllocatorDualWrite),
@@ -1038,7 +1038,7 @@ func TestUpgradeDowngrade(t *testing.T) {
10381038
s := kubeapiservertesting.StartTestServerOrDie(t,
10391039
apiServerOptions,
10401040
[]string{
1041-
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/112",
1041+
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/108",
10421042
"--advertise-address=10.0.0.1",
10431043
"--disable-admission-plugins=ServiceAccount",
10441044
},
@@ -1149,7 +1149,7 @@ func TestConvertToFromExternalName(t *testing.T) {
11491149
s := kubeapiservertesting.StartTestServerOrDie(t,
11501150
apiServerOptions,
11511151
[]string{
1152-
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/112",
1152+
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/108",
11531153
"--advertise-address=10.0.0.1",
11541154
"--disable-admission-plugins=ServiceAccount",
11551155
},
@@ -1238,7 +1238,7 @@ func TestPreferDualStack(t *testing.T) {
12381238
s := kubeapiservertesting.StartTestServerOrDie(t,
12391239
apiServerOptions,
12401240
[]string{
1241-
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/112",
1241+
"--service-cluster-ip-range=10.0.0.0/16,2001:db8:1::/108",
12421242
"--advertise-address=10.0.0.1",
12431243
"--disable-admission-plugins=ServiceAccount",
12441244
},
@@ -1552,7 +1552,7 @@ func TestUpgradeServicePreferToDualStack(t *testing.T) {
15521552
s = kubeapiservertesting.StartTestServerOrDie(t,
15531553
apiServerOptions,
15541554
[]string{
1555-
"--service-cluster-ip-range=192.168.0.0/24,2001:db8:1::/112",
1555+
"--service-cluster-ip-range=192.168.0.0/24,2001:db8:1::/108",
15561556
"--disable-admission-plugins=ServiceAccount",
15571557
},
15581558
sharedEtcd)
@@ -1593,7 +1593,7 @@ func TestDowngradeServicePreferToDualStack(t *testing.T) {
15931593
s := kubeapiservertesting.StartTestServerOrDie(t,
15941594
apiServerOptions,
15951595
[]string{
1596-
"--service-cluster-ip-range=192.168.0.0/24,2001:db8:1::/112",
1596+
"--service-cluster-ip-range=192.168.0.0/24,2001:db8:1::/108",
15971597
"--advertise-address=10.0.0.1",
15981598
"--disable-admission-plugins=ServiceAccount",
15991599
},

0 commit comments

Comments
 (0)