mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-25 11:31:44 +00:00
phase 2: ipam filter secondary service cidr
This commit is contained in:
parent
93c06821e6
commit
313a5c5734
@ -636,6 +636,7 @@ 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,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
|
||||||
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,LargeClusterSizeThreshold
|
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,NodeLifecycleControllerConfiguration,LargeClusterSizeThreshold
|
||||||
|
@ -83,6 +83,7 @@ func startServiceController(ctx ControllerContext) (http.Handler, bool, error) {
|
|||||||
}
|
}
|
||||||
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
|
||||||
|
|
||||||
// should we start nodeIPAM
|
// should we start nodeIPAM
|
||||||
if !ctx.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs {
|
if !ctx.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs {
|
||||||
@ -118,12 +119,37 @@ func startNodeIpamController(ctx ControllerContext) (http.Handler, bool, error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(strings.TrimSpace(ctx.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR)) != 0 {
|
||||||
|
_, secondaryServiceCIDR, err = net.ParseCIDR(ctx.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR)
|
||||||
|
if err != nil {
|
||||||
|
klog.Warningf("Unsuccessful parsing of service CIDR %v: %v", ctx.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following checks are triggered if both serviceCIDR and secondaryServiceCIDR are provided
|
||||||
|
if serviceCIDR != nil && secondaryServiceCIDR != nil {
|
||||||
|
// should have dual stack flag enabled
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.IPv6DualStack) {
|
||||||
|
return nil, false, fmt.Errorf("secondary service cidr is provided and IPv6DualStack feature is not enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be dual stack (from different IPFamilies)
|
||||||
|
dualstackServiceCIDR, err := netutils.IsDualStackCIDRs([]*net.IPNet{serviceCIDR, secondaryServiceCIDR})
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("failed to perform dualstack check on serviceCIDR and secondaryServiceCIDR error:%v", err)
|
||||||
|
}
|
||||||
|
if !dualstackServiceCIDR {
|
||||||
|
return nil, false, fmt.Errorf("serviceCIDR and secondaryServiceCIDR are not dualstack (from different IPfamiles)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodeIpamController, err := nodeipamcontroller.NewNodeIpamController(
|
nodeIpamController, err := nodeipamcontroller.NewNodeIpamController(
|
||||||
ctx.InformerFactory.Core().V1().Nodes(),
|
ctx.InformerFactory.Core().V1().Nodes(),
|
||||||
ctx.Cloud,
|
ctx.Cloud,
|
||||||
ctx.ClientBuilder.ClientOrDie("node-controller"),
|
ctx.ClientBuilder.ClientOrDie("node-controller"),
|
||||||
clusterCIDRs,
|
clusterCIDRs,
|
||||||
serviceCIDR,
|
serviceCIDR,
|
||||||
|
secondaryServiceCIDR,
|
||||||
int(ctx.ComponentConfig.NodeIPAMController.NodeCIDRMaskSize),
|
int(ctx.ComponentConfig.NodeIPAMController.NodeCIDRMaskSize),
|
||||||
ipam.CIDRAllocatorType(ctx.ComponentConfig.KubeCloudShared.CIDRAllocatorType),
|
ipam.CIDRAllocatorType(ctx.ComponentConfig.KubeCloudShared.CIDRAllocatorType),
|
||||||
)
|
)
|
||||||
|
@ -17,6 +17,9 @@ limitations under the License.
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
nodeipamconfig "k8s.io/kubernetes/pkg/controller/nodeipam/config"
|
nodeipamconfig "k8s.io/kubernetes/pkg/controller/nodeipam/config"
|
||||||
@ -32,7 +35,6 @@ func (o *NodeIPAMControllerOptions) AddFlags(fs *pflag.FlagSet) {
|
|||||||
if o == nil {
|
if o == nil {
|
||||||
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.")
|
||||||
}
|
}
|
||||||
@ -43,7 +45,15 @@ func (o *NodeIPAMControllerOptions) ApplyTo(cfg *nodeipamconfig.NodeIPAMControll
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.ServiceCIDR = o.ServiceCIDR
|
// split the cidrs list and assign primary and secondary
|
||||||
|
serviceCIDRList := strings.Split(o.ServiceCIDR, ",")
|
||||||
|
if len(serviceCIDRList) > 0 {
|
||||||
|
cfg.ServiceCIDR = serviceCIDRList[0]
|
||||||
|
}
|
||||||
|
if len(serviceCIDRList) > 1 {
|
||||||
|
cfg.SecondaryServiceCIDR = serviceCIDRList[1]
|
||||||
|
}
|
||||||
|
|
||||||
cfg.NodeCIDRMaskSize = o.NodeCIDRMaskSize
|
cfg.NodeCIDRMaskSize = o.NodeCIDRMaskSize
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -54,7 +64,12 @@ func (o *NodeIPAMControllerOptions) Validate() []error {
|
|||||||
if o == nil {
|
if o == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
errs := make([]error, 0)
|
||||||
|
|
||||||
|
serviceCIDRList := strings.Split(o.ServiceCIDR, ",")
|
||||||
|
if len(serviceCIDRList) > 2 {
|
||||||
|
errs = append(errs, fmt.Errorf("--service-cluster-ip-range can not contain more than two entries"))
|
||||||
|
}
|
||||||
|
|
||||||
errs := []error{}
|
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ package config
|
|||||||
type NodeIPAMControllerConfiguration struct {
|
type NodeIPAMControllerConfiguration struct {
|
||||||
// serviceCIDR is CIDR Range for Services in cluster.
|
// serviceCIDR is CIDR Range for Services in cluster.
|
||||||
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 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
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ type CIDRAllocator interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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, nodeCIDRMaskSize int) (CIDRAllocator, error) {
|
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) {
|
||||||
nodeList, err := listNodes(kubeClient)
|
nodeList, err := listNodes(kubeClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -97,7 +97,7 @@ func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInfo
|
|||||||
|
|
||||||
switch allocatorType {
|
switch allocatorType {
|
||||||
case RangeAllocatorType:
|
case RangeAllocatorType:
|
||||||
return NewCIDRRangeAllocator(kubeClient, nodeInformer, clusterCIDRs, serviceCIDR, nodeCIDRMaskSize, nodeList)
|
return NewCIDRRangeAllocator(kubeClient, nodeInformer, clusterCIDRs, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, nodeList)
|
||||||
case CloudAllocatorType:
|
case CloudAllocatorType:
|
||||||
return NewCloudCIDRAllocator(kubeClient, cloud, nodeInformer)
|
return NewCloudCIDRAllocator(kubeClient, cloud, nodeInformer)
|
||||||
default:
|
default:
|
||||||
|
@ -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, subNetMaskSize int, nodeList *v1.NodeList) (CIDRAllocator, error) {
|
func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.NodeInformer, clusterCIDRs []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, subNetMaskSize int, 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")
|
||||||
}
|
}
|
||||||
@ -110,6 +110,12 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
|
|||||||
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 {
|
||||||
|
ra.filterOutServiceRange(secondaryServiceCIDR)
|
||||||
|
} else {
|
||||||
|
klog.V(0).Info("No Secondary Service CIDR provided. Skipping filtering out secondary service addresses.")
|
||||||
|
}
|
||||||
|
|
||||||
if nodeList != nil {
|
if nodeList != nil {
|
||||||
for _, node := range nodeList.Items {
|
for _, node := range nodeList.Items {
|
||||||
if len(node.Spec.PodCIDRs) == 0 {
|
if len(node.Spec.PodCIDRs) == 0 {
|
||||||
@ -295,6 +301,7 @@ func (r *rangeAllocator) filterOutServiceRange(serviceCIDR *net.IPNet) {
|
|||||||
// serviceCIDR) or vice versa (which means that serviceCIDR contains
|
// serviceCIDR) or vice versa (which means that serviceCIDR contains
|
||||||
// clusterCIDR).
|
// clusterCIDR).
|
||||||
for idx, cidr := range r.clusterCIDRs {
|
for idx, cidr := range r.clusterCIDRs {
|
||||||
|
// if they don't overlap then ignore the filtering
|
||||||
if !cidr.Contains(serviceCIDR.IP.Mask(cidr.Mask)) && !serviceCIDR.Contains(cidr.IP.Mask(serviceCIDR.Mask)) {
|
if !cidr.Contains(serviceCIDR.IP.Mask(cidr.Mask)) && !serviceCIDR.Contains(cidr.IP.Mask(serviceCIDR.Mask)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,12 @@ 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
|
clusterCIDRs []*net.IPNet
|
||||||
serviceCIDR *net.IPNet
|
serviceCIDR *net.IPNet
|
||||||
subNetMaskSize int
|
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
|
||||||
@ -89,8 +90,9 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, 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,
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 30,
|
||||||
expectedAllocatedCIDR: map[int]string{
|
expectedAllocatedCIDR: map[int]string{
|
||||||
0: "127.123.234.0/30",
|
0: "127.123.234.0/30",
|
||||||
},
|
},
|
||||||
@ -115,7 +117,8 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
||||||
return serviceCIDR
|
return serviceCIDR
|
||||||
}(),
|
}(),
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 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",
|
||||||
@ -141,7 +144,8 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
||||||
return serviceCIDR
|
return serviceCIDR
|
||||||
}(),
|
}(),
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 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"},
|
||||||
},
|
},
|
||||||
@ -170,6 +174,7 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
||||||
return serviceCIDR
|
return serviceCIDR
|
||||||
}(),
|
}(),
|
||||||
|
secondaryServiceCIDR: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Dualstack CIDRs v6,v4",
|
description: "Dualstack CIDRs v6,v4",
|
||||||
@ -192,6 +197,7 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
||||||
return serviceCIDR
|
return serviceCIDR
|
||||||
}(),
|
}(),
|
||||||
|
secondaryServiceCIDR: nil,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -216,13 +222,14 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
|
|||||||
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
|
||||||
return serviceCIDR
|
return serviceCIDR
|
||||||
}(),
|
}(),
|
||||||
|
secondaryServiceCIDR: nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.subNetMaskSize, nil)
|
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, 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
|
||||||
@ -298,8 +305,9 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
|
|||||||
_, 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,
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 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"},
|
||||||
},
|
},
|
||||||
@ -308,7 +316,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.subNetMaskSize, nil)
|
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, 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)
|
||||||
}
|
}
|
||||||
@ -369,6 +377,7 @@ type releaseTestCase struct {
|
|||||||
fakeNodeHandler *testutil.FakeNodeHandler
|
fakeNodeHandler *testutil.FakeNodeHandler
|
||||||
clusterCIDRs []*net.IPNet
|
clusterCIDRs []*net.IPNet
|
||||||
serviceCIDR *net.IPNet
|
serviceCIDR *net.IPNet
|
||||||
|
secondaryServiceCIDR *net.IPNet
|
||||||
subNetMaskSize int
|
subNetMaskSize int
|
||||||
expectedAllocatedCIDRFirstRound map[int]string
|
expectedAllocatedCIDRFirstRound map[int]string
|
||||||
expectedAllocatedCIDRSecondRound map[int]string
|
expectedAllocatedCIDRSecondRound map[int]string
|
||||||
@ -394,8 +403,9 @@ func TestReleaseCIDRSuccess(t *testing.T) {
|
|||||||
_, 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,
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 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"},
|
||||||
},
|
},
|
||||||
@ -423,8 +433,9 @@ func TestReleaseCIDRSuccess(t *testing.T) {
|
|||||||
_, 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,
|
||||||
subNetMaskSize: 30,
|
secondaryServiceCIDR: nil,
|
||||||
|
subNetMaskSize: 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"},
|
||||||
},
|
},
|
||||||
@ -442,7 +453,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.subNetMaskSize, nil)
|
allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, 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)
|
||||||
|
@ -53,10 +53,11 @@ const (
|
|||||||
type Controller struct {
|
type Controller struct {
|
||||||
allocatorType ipam.CIDRAllocatorType
|
allocatorType ipam.CIDRAllocatorType
|
||||||
|
|
||||||
cloud cloudprovider.Interface
|
cloud cloudprovider.Interface
|
||||||
clusterCIDRs []*net.IPNet
|
clusterCIDRs []*net.IPNet
|
||||||
serviceCIDR *net.IPNet
|
serviceCIDR *net.IPNet
|
||||||
kubeClient clientset.Interface
|
secondaryServiceCIDR *net.IPNet
|
||||||
|
kubeClient clientset.Interface
|
||||||
// Method for easy mocking in unittest.
|
// Method for easy mocking in unittest.
|
||||||
lookupIP func(host string) ([]net.IP, error)
|
lookupIP func(host string) ([]net.IP, error)
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ func NewNodeIpamController(
|
|||||||
kubeClient clientset.Interface,
|
kubeClient clientset.Interface,
|
||||||
clusterCIDRs []*net.IPNet,
|
clusterCIDRs []*net.IPNet,
|
||||||
serviceCIDR *net.IPNet,
|
serviceCIDR *net.IPNet,
|
||||||
|
secondaryServiceCIDR *net.IPNet,
|
||||||
nodeCIDRMaskSize int,
|
nodeCIDRMaskSize int,
|
||||||
allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
|
allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
|
||||||
|
|
||||||
@ -119,12 +121,13 @@ func NewNodeIpamController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ic := &Controller{
|
ic := &Controller{
|
||||||
cloud: cloud,
|
cloud: cloud,
|
||||||
kubeClient: kubeClient,
|
kubeClient: kubeClient,
|
||||||
lookupIP: net.LookupIP,
|
lookupIP: net.LookupIP,
|
||||||
clusterCIDRs: clusterCIDRs,
|
clusterCIDRs: clusterCIDRs,
|
||||||
serviceCIDR: serviceCIDR,
|
serviceCIDR: serviceCIDR,
|
||||||
allocatorType: allocatorType,
|
secondaryServiceCIDR: secondaryServiceCIDR,
|
||||||
|
allocatorType: allocatorType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Abstract this check into a generic controller manager should run method.
|
// TODO: Abstract this check into a generic controller manager should run method.
|
||||||
@ -132,7 +135,7 @@ func NewNodeIpamController(
|
|||||||
startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSize)
|
startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSize)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, clusterCIDRs, ic.serviceCIDR, nodeCIDRMaskSize)
|
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, clusterCIDRs, ic.serviceCIDR, ic.secondaryServiceCIDR, nodeCIDRMaskSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import (
|
|||||||
netutils "k8s.io/utils/net"
|
netutils "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, nodeCIDRMaskSize int, allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
|
func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSize 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,39 +53,45 @@ 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, nodeCIDRMaskSize, allocatorType,
|
clusterCIDR, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, allocatorType,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestNewNodeIpamControllerWithCIDRMasks tests if the controller can be
|
// TestNewNodeIpamControllerWithCIDRMasks tests if the controller can be
|
||||||
// created with combinations of network CIDRs and masks.
|
// created with combinations of network CIDRs and masks.
|
||||||
func TestNewNodeIpamControllerWithCIDRMasks(t *testing.T) {
|
func TestNewNodeIpamControllerWithCIDRMasks(t *testing.T) {
|
||||||
|
emptyServiceCIDR := ""
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
desc string
|
desc string
|
||||||
clusterCIDR string
|
clusterCIDR string
|
||||||
serviceCIDR string
|
serviceCIDR string
|
||||||
maskSize int
|
secondaryServiceCIDR string
|
||||||
allocatorType ipam.CIDRAllocatorType
|
maskSize int
|
||||||
wantFatal bool
|
allocatorType ipam.CIDRAllocatorType
|
||||||
|
wantFatal bool
|
||||||
}{
|
}{
|
||||||
{"valid_range_allocator", "10.0.0.0/21", "10.1.0.0/21", 24, ipam.RangeAllocatorType, false},
|
{"valid_range_allocator", "10.0.0.0/21", "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", 24, ipam.RangeAllocatorType, false},
|
|
||||||
{"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", 24, ipam.CloudAllocatorType, false},
|
{"valid_range_allocator_dualstack", "10.0.0.0/21,2000::/10", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.RangeAllocatorType, false},
|
||||||
{"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", 24, ipam.IPAMFromClusterAllocatorType, 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_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", 24, ipam.IPAMFromCloudAllocatorType, false},
|
|
||||||
{"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", 24, ipam.CloudAllocatorType, false},
|
{"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false},
|
||||||
{"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", 24, ipam.IPAMFromClusterAllocatorType, true},
|
{"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, false},
|
||||||
{"valid_CIDR_smaller_than_mask_cloud_allocator", "10.0.0.0/26", "10.1.0.0/21", 24, ipam.CloudAllocatorType, false},
|
{"valid_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, false},
|
||||||
{"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", 24, ipam.IPAMFromCloudAllocatorType, true},
|
{"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false},
|
||||||
{"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", 24, ipam.IPAMFromClusterAllocatorType, true},
|
{"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", emptyServiceCIDR, 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},
|
||||||
|
{"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, true},
|
||||||
|
{"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", emptyServiceCIDR, 24, 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, ","))
|
||||||
_, serviceCIDRIpNet, _ := net.ParseCIDR(tc.serviceCIDR)
|
_, serviceCIDRIpNet, _ := net.ParseCIDR(tc.serviceCIDR)
|
||||||
|
_, secondaryServiceCIDRIpNet, _ := net.ParseCIDR(tc.secondaryServiceCIDR)
|
||||||
|
|
||||||
if os.Getenv("EXIT_ON_FATAL") == "1" {
|
if os.Getenv("EXIT_ON_FATAL") == "1" {
|
||||||
// This is the subprocess which runs the actual code.
|
// This is the subprocess which runs the actual code.
|
||||||
newTestNodeIpamController(clusterCidrs, serviceCIDRIpNet, tc.maskSize, tc.allocatorType)
|
newTestNodeIpamController(clusterCidrs, serviceCIDRIpNet, secondaryServiceCIDRIpNet, tc.maskSize, tc.allocatorType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// This is the host process that monitors the exit code of the subprocess.
|
// This is the host process that monitors the exit code of the subprocess.
|
||||||
|
@ -361,6 +361,8 @@ type NamespaceControllerConfiguration struct {
|
|||||||
type NodeIPAMControllerConfiguration struct {
|
type NodeIPAMControllerConfiguration struct {
|
||||||
// serviceCIDR is CIDR Range for Services in cluster.
|
// serviceCIDR is CIDR Range for Services in cluster.
|
||||||
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 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
|
||||||
}
|
}
|
||||||
|
@ -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, subnetMaskSize, config.AllocatorType,
|
[]*net.IPNet{clusterCIDR}, serviceCIDR, nil, subnetMaskSize, config.AllocatorType,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, shutdownFunc, err
|
return nil, shutdownFunc, err
|
||||||
|
Loading…
Reference in New Issue
Block a user