Merge pull request #79993 from aramase/controller-manager-multiple-cidr

Allow multiple node cidr masks in kube-controller-manager
This commit is contained in:
Kubernetes Prow Robot 2019-11-14 23:23:42 -08:00 committed by GitHub
commit ded6ee953c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 343 additions and 198 deletions

View File

@ -662,6 +662,8 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,K
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,ConcurrentNamespaceSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,ConcurrentNamespaceSyncs
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,NamespaceSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NamespaceControllerConfiguration,NamespaceSyncPeriod
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,NodeCIDRMaskSize API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,NodeCIDRMaskSize
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,NodeCIDRMaskSizeIPv4
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,NodeCIDRMaskSizeIPv6
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,SecondaryServiceCIDR API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,SecondaryServiceCIDR
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,ServiceCIDR API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeIPAMControllerConfiguration,ServiceCIDR
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,EnableTaintManager API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,EnableTaintManager

View File

@ -60,6 +60,7 @@ go_library(
"//pkg/controller/job:go_default_library", "//pkg/controller/job:go_default_library",
"//pkg/controller/namespace:go_default_library", "//pkg/controller/namespace:go_default_library",
"//pkg/controller/nodeipam:go_default_library", "//pkg/controller/nodeipam:go_default_library",
"//pkg/controller/nodeipam/config:go_default_library",
"//pkg/controller/nodeipam/ipam:go_default_library", "//pkg/controller/nodeipam/ipam:go_default_library",
"//pkg/controller/nodelifecycle:go_default_library", "//pkg/controller/nodelifecycle:go_default_library",
"//pkg/controller/podautoscaler:go_default_library", "//pkg/controller/podautoscaler:go_default_library",

View File

@ -21,6 +21,7 @@ limitations under the License.
package app package app
import ( import (
"errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -29,7 +30,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
v1 "k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
cacheddiscovery "k8s.io/client-go/discovery/cached/memory" cacheddiscovery "k8s.io/client-go/discovery/cached/memory"
@ -46,6 +47,7 @@ import (
"k8s.io/kubernetes/pkg/controller/garbagecollector" "k8s.io/kubernetes/pkg/controller/garbagecollector"
namespacecontroller "k8s.io/kubernetes/pkg/controller/namespace" namespacecontroller "k8s.io/kubernetes/pkg/controller/namespace"
nodeipamcontroller "k8s.io/kubernetes/pkg/controller/nodeipam" nodeipamcontroller "k8s.io/kubernetes/pkg/controller/nodeipam"
nodeipamconfig "k8s.io/kubernetes/pkg/controller/nodeipam/config"
"k8s.io/kubernetes/pkg/controller/nodeipam/ipam" "k8s.io/kubernetes/pkg/controller/nodeipam/ipam"
lifecyclecontroller "k8s.io/kubernetes/pkg/controller/nodelifecycle" lifecyclecontroller "k8s.io/kubernetes/pkg/controller/nodelifecycle"
"k8s.io/kubernetes/pkg/controller/podgc" "k8s.io/kubernetes/pkg/controller/podgc"
@ -69,6 +71,13 @@ import (
netutils "k8s.io/utils/net" netutils "k8s.io/utils/net"
) )
const (
// defaultNodeMaskCIDRIPv4 is default mask size for IPv4 node cidr
defaultNodeMaskCIDRIPv4 = 24
// defaultNodeMaskCIDRIPv6 is default mask size for IPv6 node cidr
defaultNodeMaskCIDRIPv6 = 64
)
func startServiceController(ctx ControllerContext) (http.Handler, bool, error) { func startServiceController(ctx ControllerContext) (http.Handler, bool, error) {
serviceController, err := servicecontroller.New( serviceController, err := servicecontroller.New(
ctx.Cloud, ctx.Cloud,
@ -85,6 +94,7 @@ func startServiceController(ctx ControllerContext) (http.Handler, bool, error) {
go serviceController.Run(ctx.Stop, int(ctx.ComponentConfig.ServiceController.ConcurrentServiceSyncs)) go serviceController.Run(ctx.Stop, int(ctx.ComponentConfig.ServiceController.ConcurrentServiceSyncs))
return nil, true, nil return nil, true, nil
} }
func startNodeIpamController(ctx ControllerContext) (http.Handler, bool, error) { func startNodeIpamController(ctx ControllerContext) (http.Handler, bool, error) {
var serviceCIDR *net.IPNet var serviceCIDR *net.IPNet
var secondaryServiceCIDR *net.IPNet var secondaryServiceCIDR *net.IPNet
@ -147,6 +157,20 @@ func startNodeIpamController(ctx ControllerContext) (http.Handler, bool, error)
} }
} }
var nodeCIDRMaskSizeIPv4, nodeCIDRMaskSizeIPv6 int
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.IPv6DualStack) {
nodeCIDRMaskSizeIPv4, nodeCIDRMaskSizeIPv6, err = setNodeCIDRMaskSizesDualStack(ctx.ComponentConfig.NodeIPAMController)
} else {
nodeCIDRMaskSizeIPv4, nodeCIDRMaskSizeIPv6, err = setNodeCIDRMaskSizes(ctx.ComponentConfig.NodeIPAMController)
}
if err != nil {
return nil, false, err
}
// get list of node cidr mask sizes
nodeCIDRMaskSizes := getNodeCIDRMaskSizes(clusterCIDRs, nodeCIDRMaskSizeIPv4, nodeCIDRMaskSizeIPv6)
nodeIpamController, err := nodeipamcontroller.NewNodeIpamController( nodeIpamController, err := nodeipamcontroller.NewNodeIpamController(
ctx.InformerFactory.Core().V1().Nodes(), ctx.InformerFactory.Core().V1().Nodes(),
ctx.Cloud, ctx.Cloud,
@ -154,7 +178,7 @@ func startNodeIpamController(ctx ControllerContext) (http.Handler, bool, error)
clusterCIDRs, clusterCIDRs,
serviceCIDR, serviceCIDR,
secondaryServiceCIDR, secondaryServiceCIDR,
int(ctx.ComponentConfig.NodeIPAMController.NodeCIDRMaskSize), nodeCIDRMaskSizes,
ipam.CIDRAllocatorType(ctx.ComponentConfig.KubeCloudShared.CIDRAllocatorType), ipam.CIDRAllocatorType(ctx.ComponentConfig.KubeCloudShared.CIDRAllocatorType),
) )
if err != nil { if err != nil {
@ -562,3 +586,50 @@ func processCIDRs(cidrsList string) ([]*net.IPNet, bool, error) {
return cidrs, dualstack, nil return cidrs, dualstack, nil
} }
// setNodeCIDRMaskSizes returns the IPv4 and IPv6 node cidr mask sizes.
// If --node-cidr-mask-size not set, then it will return default IPv4 and IPv6 cidr mask sizes.
func setNodeCIDRMaskSizes(cfg nodeipamconfig.NodeIPAMControllerConfiguration) (int, int, error) {
ipv4Mask, ipv6Mask := defaultNodeMaskCIDRIPv4, defaultNodeMaskCIDRIPv6
// NodeCIDRMaskSizeIPv4 and NodeCIDRMaskSizeIPv6 can be used only for dual-stack clusters
if cfg.NodeCIDRMaskSizeIPv4 != 0 || cfg.NodeCIDRMaskSizeIPv6 != 0 {
return ipv4Mask, ipv6Mask, errors.New("usage of --node-cidr-mask-size-ipv4 and --node-cidr-mask-size-ipv6 are not allowed with non dual-stack clusters")
}
if cfg.NodeCIDRMaskSize != 0 {
ipv4Mask = int(cfg.NodeCIDRMaskSize)
ipv6Mask = int(cfg.NodeCIDRMaskSize)
}
return ipv4Mask, ipv6Mask, nil
}
// setNodeCIDRMaskSizesDualStack returns the IPv4 and IPv6 node cidr mask sizes to the value provided
// for --node-cidr-mask-size-ipv4 and --node-cidr-mask-size-ipv6 respectively. If value not provided,
// then it will return default IPv4 and IPv6 cidr mask sizes.
func setNodeCIDRMaskSizesDualStack(cfg nodeipamconfig.NodeIPAMControllerConfiguration) (int, int, error) {
ipv4Mask, ipv6Mask := defaultNodeMaskCIDRIPv4, defaultNodeMaskCIDRIPv6
// NodeCIDRMaskSize can be used only for single stack clusters
if cfg.NodeCIDRMaskSize != 0 {
return ipv4Mask, ipv6Mask, errors.New("usage of --node-cidr-mask-size is not allowed with dual-stack clusters")
}
if cfg.NodeCIDRMaskSizeIPv4 != 0 {
ipv4Mask = int(cfg.NodeCIDRMaskSizeIPv4)
}
if cfg.NodeCIDRMaskSizeIPv6 != 0 {
ipv6Mask = int(cfg.NodeCIDRMaskSizeIPv6)
}
return ipv4Mask, ipv6Mask, nil
}
// getNodeCIDRMaskSizes is a helper function that helps the generate the node cidr mask
// sizes slice based on the cluster cidr slice
func getNodeCIDRMaskSizes(clusterCIDRs []*net.IPNet, maskSizeIPv4, maskSizeIPv6 int) []int {
nodeMaskCIDRs := []int{}
for _, clusterCIDR := range clusterCIDRs {
if netutils.IsIPv6CIDR(clusterCIDR) {
nodeMaskCIDRs = append(nodeMaskCIDRs, maskSizeIPv6)
} else {
nodeMaskCIDRs = append(nodeMaskCIDRs, maskSizeIPv4)
}
}
return nodeMaskCIDRs
}

View File

@ -36,7 +36,9 @@ func (o *NodeIPAMControllerOptions) AddFlags(fs *pflag.FlagSet) {
return return
} }
fs.StringVar(&o.ServiceCIDR, "service-cluster-ip-range", o.ServiceCIDR, "CIDR Range for Services in cluster. Requires --allocate-node-cidrs to be true") fs.StringVar(&o.ServiceCIDR, "service-cluster-ip-range", o.ServiceCIDR, "CIDR Range for Services in cluster. Requires --allocate-node-cidrs to be true")
fs.Int32Var(&o.NodeCIDRMaskSize, "node-cidr-mask-size", o.NodeCIDRMaskSize, "Mask size for node cidr in cluster.") fs.Int32Var(&o.NodeCIDRMaskSize, "node-cidr-mask-size", o.NodeCIDRMaskSize, "Mask size for node cidr in cluster. Default is 24 for IPv4 and 64 for IPv6.")
fs.Int32Var(&o.NodeCIDRMaskSizeIPv4, "node-cidr-mask-size-ipv4", o.NodeCIDRMaskSizeIPv4, "Mask size for IPv4 node cidr in dual-stack cluster. Default is 24.")
fs.Int32Var(&o.NodeCIDRMaskSizeIPv6, "node-cidr-mask-size-ipv6", o.NodeCIDRMaskSizeIPv6, "Mask size for IPv6 node cidr in dual-stack cluster. Default is 64.")
} }
// ApplyTo fills up NodeIpamController config with options. // ApplyTo fills up NodeIpamController config with options.

View File

@ -117,6 +117,8 @@ func TestAddFlags(t *testing.T) {
"--min-resync-period=8h", "--min-resync-period=8h",
"--namespace-sync-period=10m", "--namespace-sync-period=10m",
"--node-cidr-mask-size=48", "--node-cidr-mask-size=48",
"--node-cidr-mask-size-ipv4=48",
"--node-cidr-mask-size-ipv6=108",
"--node-eviction-rate=0.2", "--node-eviction-rate=0.2",
"--node-monitor-grace-period=30s", "--node-monitor-grace-period=30s",
"--node-monitor-period=10s", "--node-monitor-period=10s",
@ -280,6 +282,8 @@ func TestAddFlags(t *testing.T) {
NodeIPAMController: &NodeIPAMControllerOptions{ NodeIPAMController: &NodeIPAMControllerOptions{
&nodeipamconfig.NodeIPAMControllerConfiguration{ &nodeipamconfig.NodeIPAMControllerConfiguration{
NodeCIDRMaskSize: 48, NodeCIDRMaskSize: 48,
NodeCIDRMaskSizeIPv4: 48,
NodeCIDRMaskSizeIPv6: 108,
}, },
}, },
NodeLifecycleController: &NodeLifecycleControllerOptions{ NodeLifecycleController: &NodeLifecycleControllerOptions{

View File

@ -22,6 +22,10 @@ type NodeIPAMControllerConfiguration struct {
ServiceCIDR string ServiceCIDR string
// secondaryServiceCIDR is CIDR Range for Services in cluster. This is used in dual stack clusters. SecondaryServiceCIDR must be of different IP family than ServiceCIDR // secondaryServiceCIDR is CIDR Range for Services in cluster. This is used in dual stack clusters. SecondaryServiceCIDR must be of different IP family than ServiceCIDR
SecondaryServiceCIDR string SecondaryServiceCIDR string
// NodeCIDRMaskSize is the mask size for node cidr in cluster. // NodeCIDRMaskSize is the mask size for node cidr in single-stack cluster.
NodeCIDRMaskSize int32 NodeCIDRMaskSize int32
// NodeCIDRMaskSizeIPv4 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv4 int32
// NodeCIDRMaskSizeIPv6 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv6 int32
} }

View File

@ -30,7 +30,6 @@ import (
// be no easy way to opt-out. Instead, if you want to use this defaulting method // be no easy way to opt-out. Instead, if you want to use this defaulting method
// run it in your wrapper struct of this type in its `SetDefaults_` method. // run it in your wrapper struct of this type in its `SetDefaults_` method.
func RecommendedDefaultNodeIPAMControllerConfiguration(obj *kubectrlmgrconfigv1alpha1.NodeIPAMControllerConfiguration) { func RecommendedDefaultNodeIPAMControllerConfiguration(obj *kubectrlmgrconfigv1alpha1.NodeIPAMControllerConfiguration) {
if obj.NodeCIDRMaskSize == 0 { // The default mask size is not set here because we need to determine the cluster cidr family before setting the
obj.NodeCIDRMaskSize = 24 // appropriate mask size.
}
} }

View File

@ -84,6 +84,8 @@ func autoConvert_v1alpha1_NodeIPAMControllerConfiguration_To_config_NodeIPAMCont
out.ServiceCIDR = in.ServiceCIDR out.ServiceCIDR = in.ServiceCIDR
out.SecondaryServiceCIDR = in.SecondaryServiceCIDR out.SecondaryServiceCIDR = in.SecondaryServiceCIDR
out.NodeCIDRMaskSize = in.NodeCIDRMaskSize out.NodeCIDRMaskSize = in.NodeCIDRMaskSize
out.NodeCIDRMaskSizeIPv4 = in.NodeCIDRMaskSizeIPv4
out.NodeCIDRMaskSizeIPv6 = in.NodeCIDRMaskSizeIPv6
return nil return nil
} }
@ -91,5 +93,7 @@ func autoConvert_config_NodeIPAMControllerConfiguration_To_v1alpha1_NodeIPAMCont
out.ServiceCIDR = in.ServiceCIDR out.ServiceCIDR = in.ServiceCIDR
out.SecondaryServiceCIDR = in.SecondaryServiceCIDR out.SecondaryServiceCIDR = in.SecondaryServiceCIDR
out.NodeCIDRMaskSize = in.NodeCIDRMaskSize out.NodeCIDRMaskSize = in.NodeCIDRMaskSize
out.NodeCIDRMaskSizeIPv4 = in.NodeCIDRMaskSizeIPv4
out.NodeCIDRMaskSizeIPv6 = in.NodeCIDRMaskSizeIPv6
return nil return nil
} }

View File

@ -88,8 +88,21 @@ type CIDRAllocator interface {
Run(stopCh <-chan struct{}) Run(stopCh <-chan struct{})
} }
// CIDRAllocatorParams is parameters that's required for creating new
// cidr range allocator.
type CIDRAllocatorParams struct {
// ClusterCIDRs is list of cluster cidrs
ClusterCIDRs []*net.IPNet
// ServiceCIDR is primary service cidr for cluster
ServiceCIDR *net.IPNet
// SecondaryServiceCIDR is secondary service cidr for cluster
SecondaryServiceCIDR *net.IPNet
// NodeCIDRMaskSizes is list of node cidr mask sizes
NodeCIDRMaskSizes []int
}
// New creates a new CIDR range allocator. // New creates a new CIDR range allocator.
func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInformer informers.NodeInformer, allocatorType CIDRAllocatorType, clusterCIDRs []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSize int) (CIDRAllocator, error) { func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInformer informers.NodeInformer, allocatorType CIDRAllocatorType, allocatorParams CIDRAllocatorParams) (CIDRAllocator, error) {
nodeList, err := listNodes(kubeClient) nodeList, err := listNodes(kubeClient)
if err != nil { if err != nil {
return nil, err return nil, err
@ -97,7 +110,7 @@ func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInfo
switch allocatorType { switch allocatorType {
case RangeAllocatorType: case RangeAllocatorType:
return NewCIDRRangeAllocator(kubeClient, nodeInformer, clusterCIDRs, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, nodeList) return NewCIDRRangeAllocator(kubeClient, nodeInformer, allocatorParams, nodeList)
case CloudAllocatorType: case CloudAllocatorType:
return NewCloudCIDRAllocator(kubeClient, cloud, nodeInformer) return NewCloudCIDRAllocator(kubeClient, cloud, nodeInformer)
default: default:

View File

@ -43,6 +43,8 @@ const (
// The subnet mask size cannot be greater than 16 more than the cluster mask size // The subnet mask size cannot be greater than 16 more than the cluster mask size
// TODO: https://github.com/kubernetes/kubernetes/issues/44918 // TODO: https://github.com/kubernetes/kubernetes/issues/44918
// clusterSubnetMaxDiff limited to 16 due to the uncompressed bitmap // clusterSubnetMaxDiff limited to 16 due to the uncompressed bitmap
// Due to this limitation the subnet mask for IPv6 cluster cidr needs to be >= 48
// as default mask size for IPv6 is 64.
clusterSubnetMaxDiff = 16 clusterSubnetMaxDiff = 16
// halfIPv6Len is the half of the IPv6 length // halfIPv6Len is the half of the IPv6 length
halfIPv6Len = net.IPv6len / 2 halfIPv6Len = net.IPv6len / 2

View File

@ -21,9 +21,9 @@ import (
"net" "net"
"sync" "sync"
"k8s.io/api/core/v1"
"k8s.io/klog" "k8s.io/klog"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@ -71,7 +71,7 @@ type rangeAllocator struct {
// Caller must always pass in a list of existing nodes so the new allocator. // Caller must always pass in a list of existing nodes so the new allocator.
// Caller must ensure that ClusterCIDRs are semantically correct e.g (1 for non DualStack, 2 for DualStack etc..) // Caller must ensure that ClusterCIDRs are semantically correct e.g (1 for non DualStack, 2 for DualStack etc..)
// can initialize its CIDR map. NodeList is only nil in testing. // can initialize its CIDR map. NodeList is only nil in testing.
func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.NodeInformer, clusterCIDRs []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, subNetMaskSize int, nodeList *v1.NodeList) (CIDRAllocator, error) { func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.NodeInformer, allocatorParams CIDRAllocatorParams, nodeList *v1.NodeList) (CIDRAllocator, error) {
if client == nil { if client == nil {
klog.Fatalf("kubeClient is nil when starting NodeController") klog.Fatalf("kubeClient is nil when starting NodeController")
} }
@ -84,9 +84,9 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
// create a cidrSet for each cidr we operate on // create a cidrSet for each cidr we operate on
// cidrSet are mapped to clusterCIDR by index // cidrSet are mapped to clusterCIDR by index
cidrSets := make([]*cidrset.CidrSet, len(clusterCIDRs)) cidrSets := make([]*cidrset.CidrSet, len(allocatorParams.ClusterCIDRs))
for idx, cidr := range clusterCIDRs { for idx, cidr := range allocatorParams.ClusterCIDRs {
cidrSet, err := cidrset.NewCIDRSet(cidr, subNetMaskSize) cidrSet, err := cidrset.NewCIDRSet(cidr, allocatorParams.NodeCIDRMaskSizes[idx])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -95,7 +95,7 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
ra := &rangeAllocator{ ra := &rangeAllocator{
client: client, client: client,
clusterCIDRs: clusterCIDRs, clusterCIDRs: allocatorParams.ClusterCIDRs,
cidrSets: cidrSets, cidrSets: cidrSets,
nodeLister: nodeInformer.Lister(), nodeLister: nodeInformer.Lister(),
nodesSynced: nodeInformer.Informer().HasSynced, nodesSynced: nodeInformer.Informer().HasSynced,
@ -104,14 +104,14 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
nodesInProcessing: sets.NewString(), nodesInProcessing: sets.NewString(),
} }
if serviceCIDR != nil { if allocatorParams.ServiceCIDR != nil {
ra.filterOutServiceRange(serviceCIDR) ra.filterOutServiceRange(allocatorParams.ServiceCIDR)
} else { } else {
klog.V(0).Info("No Service CIDR provided. Skipping filtering out service addresses.") klog.V(0).Info("No Service CIDR provided. Skipping filtering out service addresses.")
} }
if secondaryServiceCIDR != nil { if allocatorParams.SecondaryServiceCIDR != nil {
ra.filterOutServiceRange(secondaryServiceCIDR) ra.filterOutServiceRange(allocatorParams.SecondaryServiceCIDR)
} else { } else {
klog.V(0).Info("No Secondary Service CIDR provided. Skipping filtering out secondary service addresses.") klog.V(0).Info("No Secondary Service CIDR provided. Skipping filtering out secondary service addresses.")
} }

View File

@ -62,10 +62,7 @@ func getFakeNodeInformer(fakeNodeHandler *testutil.FakeNodeHandler) coreinformer
type testCase struct { type testCase struct {
description string description string
fakeNodeHandler *testutil.FakeNodeHandler fakeNodeHandler *testutil.FakeNodeHandler
clusterCIDRs []*net.IPNet allocatorParams CIDRAllocatorParams
serviceCIDR *net.IPNet
secondaryServiceCIDR *net.IPNet
subNetMaskSize int
// key is index of the cidr allocated // key is index of the cidr allocated
expectedAllocatedCIDR map[int]string expectedAllocatedCIDR map[int]string
allocatedCIDRs map[int][]string allocatedCIDRs map[int][]string
@ -88,13 +85,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4} return []*net.IPNet{clusterCIDRv4}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: false, ctrlCreateFail: false,
@ -111,14 +110,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: false, ctrlCreateFail: false,
@ -138,13 +139,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4} return []*net.IPNet{clusterCIDRv4}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: false, ctrlCreateFail: false,
@ -164,14 +167,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: false, ctrlCreateFail: false,
@ -192,13 +197,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4} return []*net.IPNet{clusterCIDRv4}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: true, ctrlCreateFail: true,
@ -219,13 +226,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4} return []*net.IPNet{clusterCIDRv4}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: true, ctrlCreateFail: true,
@ -246,14 +255,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: true, ctrlCreateFail: true,
@ -274,14 +285,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16") _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 24, NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil, allocatedCIDRs: nil,
expectedAllocatedCIDR: nil, expectedAllocatedCIDR: nil,
ctrlCreateFail: true, ctrlCreateFail: true,
@ -294,7 +307,7 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
// Initialize the range allocator. // Initialize the range allocator.
fakeNodeInformer := getFakeNodeInformer(tc.fakeNodeHandler) fakeNodeInformer := getFakeNodeInformer(tc.fakeNodeHandler)
nodeList, _ := tc.fakeNodeHandler.List(metav1.ListOptions{}) nodeList, _ := tc.fakeNodeHandler.List(metav1.ListOptions{})
_, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, fakeNodeInformer, tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nodeList) _, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, fakeNodeInformer, tc.allocatorParams, nodeList)
if err == nil && tc.ctrlCreateFail { if err == nil && tc.ctrlCreateFail {
t.Fatalf("creating range allocator was expected to fail, but it did not") t.Fatalf("creating range allocator was expected to fail, but it did not")
} }
@ -320,13 +333,15 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
expectedAllocatedCIDR: map[int]string{ expectedAllocatedCIDR: map[int]string{
0: "127.123.234.0/30", 0: "127.123.234.0/30",
}, },
@ -343,16 +358,18 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: func() *net.IPNet { ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26") _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR return serviceCIDR
}(), }(),
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
// it should return first /30 CIDR after service range // it should return first /30 CIDR after service range
expectedAllocatedCIDR: map[int]string{ expectedAllocatedCIDR: map[int]string{
0: "127.123.234.64/30", 0: "127.123.234.64/30",
@ -370,16 +387,18 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: func() *net.IPNet { ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26") _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR return serviceCIDR
}(), }(),
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{ allocatedCIDRs: map[int][]string{
0: {"127.123.234.64/30", "127.123.234.68/30", "127.123.234.72/30", "127.123.234.80/30"}, 0: {"127.123.234.64/30", "127.123.234.68/30", "127.123.234.72/30", "127.123.234.80/30"},
}, },
@ -399,16 +418,19 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8") _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(), }(),
serviceCIDR: func() *net.IPNet { ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26") _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR return serviceCIDR
}(), }(),
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 98},
},
}, },
{ {
description: "Dualstack CIDRs v6,v4", description: "Dualstack CIDRs v6,v4",
@ -422,18 +444,20 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8") _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
return []*net.IPNet{clusterCIDRv6, clusterCIDRv4} return []*net.IPNet{clusterCIDRv6, clusterCIDRv4}
}(), }(),
serviceCIDR: func() *net.IPNet { ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26") _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR return serviceCIDR
}(), }(),
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{98, 24},
},
}, },
{ {
description: "Dualstack CIDRs, more than two", description: "Dualstack CIDRs, more than two",
fakeNodeHandler: &testutil.FakeNodeHandler{ fakeNodeHandler: &testutil.FakeNodeHandler{
@ -446,24 +470,27 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8") _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8") _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
_, clusterCIDRv4_2, _ := net.ParseCIDR("10.0.0.0/8") _, clusterCIDRv4_2, _ := net.ParseCIDR("10.0.0.0/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6, clusterCIDRv4_2} return []*net.IPNet{clusterCIDRv4, clusterCIDRv6, clusterCIDRv4_2}
}(), }(),
serviceCIDR: func() *net.IPNet { ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26") _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR return serviceCIDR
}(), }(),
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 98, 24},
},
}, },
} }
// test function // test function
testFunc := func(tc testCase) { testFunc := func(tc testCase) {
// Initialize the range allocator. // Initialize the range allocator.
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil) allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
if err != nil { if err != nil {
t.Errorf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err) t.Errorf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
return return
@ -535,13 +562,15 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{ allocatedCIDRs: map[int][]string{
0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"}, 0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
}, },
@ -550,7 +579,7 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
testFunc := func(tc testCase) { testFunc := func(tc testCase) {
// Initialize the range allocator. // Initialize the range allocator.
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil) allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
if err != nil { if err != nil {
t.Logf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err) t.Logf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
} }
@ -609,10 +638,7 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
type releaseTestCase struct { type releaseTestCase struct {
description string description string
fakeNodeHandler *testutil.FakeNodeHandler fakeNodeHandler *testutil.FakeNodeHandler
clusterCIDRs []*net.IPNet allocatorParams CIDRAllocatorParams
serviceCIDR *net.IPNet
secondaryServiceCIDR *net.IPNet
subNetMaskSize int
expectedAllocatedCIDRFirstRound map[int]string expectedAllocatedCIDRFirstRound map[int]string
expectedAllocatedCIDRSecondRound map[int]string expectedAllocatedCIDRSecondRound map[int]string
allocatedCIDRs map[int][]string allocatedCIDRs map[int][]string
@ -633,13 +659,15 @@ func TestReleaseCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{ allocatedCIDRs: map[int][]string{
0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"}, 0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
}, },
@ -663,13 +691,15 @@ func TestReleaseCIDRSuccess(t *testing.T) {
}, },
Clientset: fake.NewSimpleClientset(), Clientset: fake.NewSimpleClientset(),
}, },
clusterCIDRs: func() []*net.IPNet { allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28") _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR} return []*net.IPNet{clusterCIDR}
}(), }(),
serviceCIDR: nil, ServiceCIDR: nil,
secondaryServiceCIDR: nil, SecondaryServiceCIDR: nil,
subNetMaskSize: 30, NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{ allocatedCIDRs: map[int][]string{
0: {"127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"}, 0: {"127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
}, },
@ -687,7 +717,7 @@ func TestReleaseCIDRSuccess(t *testing.T) {
testFunc := func(tc releaseTestCase) { testFunc := func(tc releaseTestCase) {
// Initialize the range allocator. // Initialize the range allocator.
allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil) allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
rangeAllocator, ok := allocator.(*rangeAllocator) rangeAllocator, ok := allocator.(*rangeAllocator)
if !ok { if !ok {
t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description) t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description)

View File

@ -37,7 +37,7 @@ func startLegacyIPAM(
kubeClient clientset.Interface, kubeClient clientset.Interface,
clusterCIDRs []*net.IPNet, clusterCIDRs []*net.IPNet,
serviceCIDR *net.IPNet, serviceCIDR *net.IPNet,
nodeCIDRMaskSize int, nodeCIDRMaskSizes []int,
) { ) {
cfg := &ipam.Config{ cfg := &ipam.Config{
Resync: ipamResyncInterval, Resync: ipamResyncInterval,
@ -59,7 +59,7 @@ func startLegacyIPAM(
if len(clusterCIDRs) > 1 { if len(clusterCIDRs) > 1 {
klog.Warningf("Multiple cidrs were configured with FromCluster or FromCloud. cidrs except first one were discarded") klog.Warningf("Multiple cidrs were configured with FromCluster or FromCloud. cidrs except first one were discarded")
} }
ipamc, err := ipam.NewController(cfg, kubeClient, cloud, cidr, serviceCIDR, nodeCIDRMaskSize) ipamc, err := ipam.NewController(cfg, kubeClient, cloud, cidr, serviceCIDR, nodeCIDRMaskSizes[0])
if err != nil { if err != nil {
klog.Fatalf("Error creating ipam controller: %v", err) klog.Fatalf("Error creating ipam controller: %v", err)
} }

View File

@ -81,7 +81,7 @@ func NewNodeIpamController(
clusterCIDRs []*net.IPNet, clusterCIDRs []*net.IPNet,
serviceCIDR *net.IPNet, serviceCIDR *net.IPNet,
secondaryServiceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet,
nodeCIDRMaskSize int, nodeCIDRMaskSizes []int,
allocatorType ipam.CIDRAllocatorType) (*Controller, error) { allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
if kubeClient == nil { if kubeClient == nil {
@ -111,11 +111,11 @@ func NewNodeIpamController(
// - modify mask to allow flexible masks for IPv4 and IPv6 // - modify mask to allow flexible masks for IPv4 and IPv6
// - for alpha status they are the same // - for alpha status they are the same
// for each cidr, cidr mask size must be <= node mask // for each cidr, node mask size must be <= cidr mask
for _, cidr := range clusterCIDRs { for idx, cidr := range clusterCIDRs {
mask := cidr.Mask mask := cidr.Mask
if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSize { if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSizes[idx] {
klog.Fatal("Controller: Invalid --cluster-cidr, mask size of cluster CIDR must be less than or equal to --node-cidr-mask-size") klog.Fatal("Controller: Invalid --cluster-cidr, mask size of cluster CIDR must be less than or equal to --node-cidr-mask-size configured for CIDR family")
} }
} }
} }
@ -132,10 +132,18 @@ func NewNodeIpamController(
// TODO: Abstract this check into a generic controller manager should run method. // TODO: Abstract this check into a generic controller manager should run method.
if ic.allocatorType == ipam.IPAMFromClusterAllocatorType || ic.allocatorType == ipam.IPAMFromCloudAllocatorType { if ic.allocatorType == ipam.IPAMFromClusterAllocatorType || ic.allocatorType == ipam.IPAMFromCloudAllocatorType {
startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSize) startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSizes)
} else { } else {
var err error var err error
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, clusterCIDRs, ic.serviceCIDR, ic.secondaryServiceCIDR, nodeCIDRMaskSize)
allocatorParams := ipam.CIDRAllocatorParams{
ClusterCIDRs: clusterCIDRs,
ServiceCIDR: ic.serviceCIDR,
SecondaryServiceCIDR: ic.secondaryServiceCIDR,
NodeCIDRMaskSizes: nodeCIDRMaskSizes,
}
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, allocatorParams)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -34,7 +34,7 @@ import (
netutils "k8s.io/utils/net" netutils "k8s.io/utils/net"
) )
func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSize int, allocatorType ipam.CIDRAllocatorType) (*Controller, error) { func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSizes []int, allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
clientSet := fake.NewSimpleClientset() clientSet := fake.NewSimpleClientset()
fakeNodeHandler := &testutil.FakeNodeHandler{ fakeNodeHandler := &testutil.FakeNodeHandler{
Existing: []*v1.Node{ Existing: []*v1.Node{
@ -53,7 +53,7 @@ func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet,
fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues())
return NewNodeIpamController( return NewNodeIpamController(
fakeNodeInformer, fakeGCE, clientSet, fakeNodeInformer, fakeGCE, clientSet,
clusterCIDR, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, allocatorType, clusterCIDR, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSizes, allocatorType,
) )
} }
@ -66,23 +66,24 @@ func TestNewNodeIpamControllerWithCIDRMasks(t *testing.T) {
clusterCIDR string clusterCIDR string
serviceCIDR string serviceCIDR string
secondaryServiceCIDR string secondaryServiceCIDR string
maskSize int maskSize []int
allocatorType ipam.CIDRAllocatorType allocatorType ipam.CIDRAllocatorType
wantFatal bool wantFatal bool
}{ }{
{"valid_range_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.RangeAllocatorType, false}, {"valid_range_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack", "10.0.0.0/21,2000::/10", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.RangeAllocatorType, false}, {"valid_range_allocator_dualstack", "10.0.0.0/21,2000::/10", "10.1.0.0/21", emptyServiceCIDR, []int{24, 98}, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack_dualstackservice", "10.0.0.0/21,2000::/10", "10.1.0.0/21", "3000::/10", 24, ipam.RangeAllocatorType, false}, {"valid_range_allocator_dualstack_dualstackservice", "10.0.0.0/21,2000::/10", "10.1.0.0/21", "3000::/10", []int{24, 98}, ipam.RangeAllocatorType, false},
{"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false}, {"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, false}, {"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, false},
{"valid_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, false}, {"valid_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromCloudAllocatorType, false},
{"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false}, {"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, true}, {"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, true},
{"valid_CIDR_smaller_than_mask_cloud_allocator", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false}, {"valid_CIDR_smaller_than_mask_cloud_allocator", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, true}, {"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromCloudAllocatorType, true},
{"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, true}, {"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, true},
{"invalid_CIDR_mask_size", "10.0.0.0/24,2000::/64", "10.1.0.0/21", emptyServiceCIDR, []int{24, 48}, ipam.IPAMFromClusterAllocatorType, true},
} { } {
t.Run(tc.desc, func(t *testing.T) { t.Run(tc.desc, func(t *testing.T) {
clusterCidrs, _ := netutils.ParseCIDRs(strings.Split(tc.clusterCIDR, ",")) clusterCidrs, _ := netutils.ParseCIDRs(strings.Split(tc.clusterCIDR, ","))

View File

@ -382,6 +382,10 @@ type NodeIPAMControllerConfiguration struct {
SecondaryServiceCIDR string SecondaryServiceCIDR string
// NodeCIDRMaskSize is the mask size for node cidr in cluster. // NodeCIDRMaskSize is the mask size for node cidr in cluster.
NodeCIDRMaskSize int32 NodeCIDRMaskSize int32
// NodeCIDRMaskSizeIPv4 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv4 int32
// NodeCIDRMaskSizeIPv6 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv6 int32
} }
// NodeLifecycleControllerConfiguration contains elements describing NodeLifecycleController. // NodeLifecycleControllerConfiguration contains elements describing NodeLifecycleController.

View File

@ -52,7 +52,7 @@ func setupAllocator(apiURL string, config *Config, clusterCIDR, serviceCIDR *net
sharedInformer := informers.NewSharedInformerFactory(clientSet, 1*time.Hour) sharedInformer := informers.NewSharedInformerFactory(clientSet, 1*time.Hour)
ipamController, err := nodeipam.NewNodeIpamController( ipamController, err := nodeipam.NewNodeIpamController(
sharedInformer.Core().V1().Nodes(), config.Cloud, clientSet, sharedInformer.Core().V1().Nodes(), config.Cloud, clientSet,
[]*net.IPNet{clusterCIDR}, serviceCIDR, nil, subnetMaskSize, config.AllocatorType, []*net.IPNet{clusterCIDR}, serviceCIDR, nil, []int{subnetMaskSize}, config.AllocatorType,
) )
if err != nil { if err != nil {
return nil, shutdownFunc, err return nil, shutdownFunc, err