Skip to content

Commit d9ad1f5

Browse files
committed
Refactor NodeIPAMController to include a starter
1 parent ce9dc2d commit d9ad1f5

File tree

11 files changed

+327
-229
lines changed

11 files changed

+327
-229
lines changed

cmd/cloud-controller-manager/BUILD

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ go_library(
5151
"//vendor/k8s.io/controller-manager/controller",
5252
"//vendor/k8s.io/klog/v2:klog",
5353
"//vendor/k8s.io/kubernetes/cmd/kube-controller-manager/names",
54-
"//vendor/k8s.io/utils/net",
5554
],
5655
)
5756

@@ -70,9 +69,13 @@ go_test(
7069
"//pkg/controller/nodeipam/config",
7170
"//pkg/controller/service",
7271
"//vendor/k8s.io/api/core/v1:core",
72+
"//vendor/k8s.io/client-go/informers",
73+
"//vendor/k8s.io/client-go/kubernetes/fake",
74+
"//vendor/k8s.io/client-go/rest",
7375
"//vendor/k8s.io/cloud-provider",
7476
"//vendor/k8s.io/cloud-provider/app/config",
7577
"//vendor/k8s.io/cloud-provider/config",
7678
"//vendor/k8s.io/controller-manager/app",
79+
"//vendor/k8s.io/controller-manager/pkg/clientbuilder",
7780
],
7881
)

cmd/cloud-controller-manager/gkenetworkparamsetcontroller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
networkinformers "github.com/GoogleCloudPlatform/gke-networking-api/client/network/informers/externalversions"
1111
cloudprovider "k8s.io/cloud-provider"
1212
gkenetworkparamsetcontroller "k8s.io/cloud-provider-gcp/pkg/controller/gkenetworkparamset"
13+
nodeipam "k8s.io/cloud-provider-gcp/pkg/controller/nodeipam"
1314
"k8s.io/cloud-provider-gcp/pkg/controller/nodeipam/ipam"
1415
"k8s.io/cloud-provider-gcp/providers/gce"
1516
"k8s.io/cloud-provider/app"
@@ -73,7 +74,7 @@ func startGkeNetworkParamsController(ccmConfig *cloudcontrollerconfig.CompletedC
7374
// with stack type and returns a list of typed cidrs and error
7475
func validClusterCIDR(clusterCIDRFromFlag string) ([]*net.IPNet, error) {
7576
// failure: bad cidrs in config
76-
clusterCIDRs, dualStack, err := processCIDRs(clusterCIDRFromFlag)
77+
clusterCIDRs, dualStack, err := nodeipam.ProcessCIDRs(clusterCIDRFromFlag)
7778
if err != nil {
7879
return nil, err
7980
}

cmd/cloud-controller-manager/nodeipamcontroller.go

Lines changed: 17 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,16 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
// This file holds the code related with the sample nodeipamcontroller
18-
// which demonstrates how cloud providers add external controllers to cloud-controller-manager
19-
// This file is copied from k8s.io/kubernetes/cmd/cloud-controller-manager/nodeipamcontroller.go@v1.22
20-
2117
package main
2218

2319
import (
2420
"context"
25-
"errors"
26-
"fmt"
27-
"net"
28-
"strings"
2921
"time"
3022

3123
networkclientset "github.com/GoogleCloudPlatform/gke-networking-api/client/network/clientset/versioned"
3224
networkinformers "github.com/GoogleCloudPlatform/gke-networking-api/client/network/informers/externalversions"
3325
nodetopologyclientset "github.com/GoogleCloudPlatform/gke-networking-api/client/nodetopology/clientset/versioned"
26+
"k8s.io/apimachinery/pkg/util/wait"
3427
cloudprovider "k8s.io/cloud-provider"
3528
nodeipamcontrolleroptions "k8s.io/cloud-provider-gcp/cmd/cloud-controller-manager/options"
3629
nodeipamcontroller "k8s.io/cloud-provider-gcp/pkg/controller/nodeipam"
@@ -41,14 +34,6 @@ import (
4134
genericcontrollermanager "k8s.io/controller-manager/app"
4235
"k8s.io/controller-manager/controller"
4336
"k8s.io/klog/v2"
44-
netutils "k8s.io/utils/net"
45-
)
46-
47-
const (
48-
// defaultNodeMaskCIDRIPv4 is default mask size for IPv4 node cidr
49-
defaultNodeMaskCIDRIPv4 = 24
50-
// defaultNodeMaskCIDRIPv6 is default mask size for IPv6 node cidr
51-
defaultNodeMaskCIDRIPv6 = 64
5237
)
5338

5439
type nodeIPAMController struct {
@@ -69,68 +54,9 @@ func (nodeIpamController *nodeIPAMController) startNodeIpamControllerWrapper(ini
6954
}
7055

7156
func startNodeIpamController(ccmConfig *cloudcontrollerconfig.CompletedConfig, nodeIPAMConfig nodeipamconfig.NodeIPAMControllerConfiguration, ctx genericcontrollermanager.ControllerContext, cloud cloudprovider.Interface) (controller.Interface, bool, error) {
72-
var serviceCIDR *net.IPNet
73-
var secondaryServiceCIDR *net.IPNet
74-
var clusterCIDRs []*net.IPNet
75-
var nodeCIDRMaskSizes []int
76-
77-
// should we start nodeIPAM
78-
if !ccmConfig.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs {
79-
return nil, false, fmt.Errorf("the AllocateNodeCIDRs is not enabled")
80-
}
81-
82-
// failure: bad cidrs in config
83-
cidrs, dualStack, err := processCIDRs(ccmConfig.ComponentConfig.KubeCloudShared.ClusterCIDR)
84-
if err != nil {
85-
return nil, false, err
86-
}
87-
clusterCIDRs = cidrs
88-
89-
// failure: more than one cidr but they are not configured as dual stack
90-
if len(clusterCIDRs) > 1 && !dualStack {
91-
return nil, false, fmt.Errorf("len of ClusterCIDRs==%v and they are not configured as dual stack (at least one from each IPFamily", len(clusterCIDRs))
92-
}
93-
94-
// failure: more than 2 cidrs is not allowed even with dual stack
95-
if len(clusterCIDRs) > 2 {
96-
return nil, false, fmt.Errorf("len of clusters cidrs is:%v > more than max allowed of 2", len(clusterCIDRs))
97-
}
98-
99-
// service cidr processing
100-
if len(strings.TrimSpace(nodeIPAMConfig.ServiceCIDR)) != 0 {
101-
_, serviceCIDR, err = net.ParseCIDR(nodeIPAMConfig.ServiceCIDR)
102-
if err != nil {
103-
klog.Warningf("Unsuccessful parsing of service CIDR %v: %v", nodeIPAMConfig.ServiceCIDR, err)
104-
}
105-
}
106-
107-
if len(strings.TrimSpace(nodeIPAMConfig.SecondaryServiceCIDR)) != 0 {
108-
_, secondaryServiceCIDR, err = net.ParseCIDR(nodeIPAMConfig.SecondaryServiceCIDR)
109-
if err != nil {
110-
klog.Warningf("Unsuccessful parsing of service CIDR %v: %v", nodeIPAMConfig.SecondaryServiceCIDR, err)
111-
}
112-
}
113-
114-
// the following checks are triggered if both serviceCIDR and secondaryServiceCIDR are provided
115-
if serviceCIDR != nil && secondaryServiceCIDR != nil {
116-
// should be dual stack (from different IPFamilies)
117-
dualstackServiceCIDR, err := netutils.IsDualStackCIDRs([]*net.IPNet{serviceCIDR, secondaryServiceCIDR})
118-
if err != nil {
119-
return nil, false, fmt.Errorf("failed to perform dualstack check on serviceCIDR and secondaryServiceCIDR error:%v", err)
120-
}
121-
if !dualstackServiceCIDR {
122-
return nil, false, fmt.Errorf("serviceCIDR and secondaryServiceCIDR are not dualstack (from different IPfamiles)")
123-
}
124-
}
125-
126-
// get list of node cidr mask sizes
127-
nodeCIDRMaskSizes, err = setNodeCIDRMaskSizes(nodeIPAMConfig, clusterCIDRs)
128-
if err != nil {
129-
return nil, false, err
130-
}
131-
13257
kubeConfig := ccmConfig.Complete().Kubeconfig
13358
kubeConfig.ContentType = "application/json" // required to serialize Networks to json
59+
13460
networkClient, err := networkclientset.NewForConfig(kubeConfig)
13561
if err != nil {
13662
return nil, false, err
@@ -139,120 +65,28 @@ func startNodeIpamController(ccmConfig *cloudcontrollerconfig.CompletedConfig, n
13965
if err != nil {
14066
return nil, false, err
14167
}
68+
14269
nwInfFactory := networkinformers.NewSharedInformerFactory(networkClient, 30*time.Second)
14370
nwInformer := nwInfFactory.Networking().V1().Networks()
14471
gnpInformer := nwInfFactory.Networking().V1().GKENetworkParamSets()
145-
nodeIpamController, err := nodeipamcontroller.NewNodeIpamController(
72+
73+
// TODO: Add a flag to control to start this informer specific to required GKE functionality
74+
go nwInfFactory.Start(ctx.Stop)
75+
76+
return nodeipamcontroller.StartNodeIpamController(
77+
wait.ContextForChannel(ctx.Stop),
14678
ccmConfig.SharedInformers.Core().V1().Nodes(),
147-
cloud,
14879
ccmConfig.ClientBuilder.ClientOrDie("node-controller"),
80+
cloud,
81+
ccmConfig.ComponentConfig.KubeCloudShared.ClusterCIDR,
82+
ccmConfig.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs,
83+
nodeIPAMConfig.ServiceCIDR,
84+
nodeIPAMConfig.SecondaryServiceCIDR,
85+
nodeIPAMConfig,
14986
nwInformer,
15087
gnpInformer,
15188
nodeTopologyClient,
152-
nodeIPAMConfig.EnableMultiSubnetCluster,
153-
nodeIPAMConfig.EnableMultiNetworking,
154-
clusterCIDRs,
155-
serviceCIDR,
156-
secondaryServiceCIDR,
157-
nodeCIDRMaskSizes,
15889
ipam.CIDRAllocatorType(ccmConfig.ComponentConfig.KubeCloudShared.CIDRAllocatorType),
90+
ctx.ControllerManagerMetrics,
15991
)
160-
if err != nil {
161-
return nil, false, err
162-
}
163-
nwInfFactory.Start(ctx.Stop)
164-
go nodeIpamController.Run(ctx.Stop, ctx.ControllerManagerMetrics)
165-
return nil, true, nil
166-
}
167-
168-
// processCIDRs is a helper function that works on a comma separated cidrs and returns
169-
// a list of typed cidrs
170-
// a flag if cidrs represents a dual stack
171-
// error if failed to parse any of the cidrs
172-
func processCIDRs(cidrsList string) ([]*net.IPNet, bool, error) {
173-
cidrsSplit := strings.Split(strings.TrimSpace(cidrsList), ",")
174-
175-
cidrs, err := netutils.ParseCIDRs(cidrsSplit)
176-
if err != nil {
177-
return nil, false, err
178-
}
179-
180-
// if cidrs has an error then the previous call will fail
181-
// safe to ignore error checking on next call
182-
dualstack, _ := netutils.IsDualStackCIDRs(cidrs)
183-
184-
return cidrs, dualstack, nil
185-
}
186-
187-
// setNodeCIDRMaskSizes returns the IPv4 and IPv6 node cidr mask sizes to the value provided
188-
// for --node-cidr-mask-size-ipv4 and --node-cidr-mask-size-ipv6 respectively. If value not provided,
189-
// then it will return default IPv4 and IPv6 cidr mask sizes.
190-
func setNodeCIDRMaskSizes(cfg nodeipamconfig.NodeIPAMControllerConfiguration, clusterCIDRs []*net.IPNet) ([]int, error) {
191-
192-
sortedSizes := func(maskSizeIPv4, maskSizeIPv6 int) []int {
193-
nodeMaskCIDRs := make([]int, len(clusterCIDRs))
194-
195-
for idx, clusterCIDR := range clusterCIDRs {
196-
if netutils.IsIPv6CIDR(clusterCIDR) {
197-
nodeMaskCIDRs[idx] = maskSizeIPv6
198-
} else {
199-
nodeMaskCIDRs[idx] = maskSizeIPv4
200-
}
201-
}
202-
return nodeMaskCIDRs
203-
}
204-
205-
// --node-cidr-mask-size flag is incompatible with dual stack clusters.
206-
ipv4Mask, ipv6Mask := defaultNodeMaskCIDRIPv4, defaultNodeMaskCIDRIPv6
207-
isDualstack := len(clusterCIDRs) > 1
208-
209-
// case one: cluster is dualstack (i.e, more than one cidr)
210-
if isDualstack {
211-
// if --node-cidr-mask-size then fail, user must configure the correct dual-stack mask sizes (or use default)
212-
if cfg.NodeCIDRMaskSize != 0 {
213-
return nil, errors.New("usage of --node-cidr-mask-size is not allowed with dual-stack clusters")
214-
}
215-
216-
if cfg.NodeCIDRMaskSizeIPv4 != 0 {
217-
ipv4Mask = int(cfg.NodeCIDRMaskSizeIPv4)
218-
}
219-
if cfg.NodeCIDRMaskSizeIPv6 != 0 {
220-
ipv6Mask = int(cfg.NodeCIDRMaskSizeIPv6)
221-
}
222-
return sortedSizes(ipv4Mask, ipv6Mask), nil
223-
}
224-
225-
maskConfigured := cfg.NodeCIDRMaskSize != 0
226-
maskV4Configured := cfg.NodeCIDRMaskSizeIPv4 != 0
227-
maskV6Configured := cfg.NodeCIDRMaskSizeIPv6 != 0
228-
isSingleStackIPv6 := netutils.IsIPv6CIDR(clusterCIDRs[0])
229-
230-
// original flag is set
231-
if maskConfigured {
232-
// original mask flag is still the main reference.
233-
if maskV4Configured || maskV6Configured {
234-
return nil, errors.New("usage of --node-cidr-mask-size-ipv4 and --node-cidr-mask-size-ipv6 is not allowed if --node-cidr-mask-size is set. For dual-stack clusters please unset it and use IPFamily specific flags")
235-
}
236-
237-
mask := int(cfg.NodeCIDRMaskSize)
238-
return sortedSizes(mask, mask), nil
239-
}
240-
241-
if maskV4Configured {
242-
if isSingleStackIPv6 {
243-
klog.Info("--node-cidr-mask-size-ipv4 should not be used for a single-stack IPv6 cluster")
244-
}
245-
246-
ipv4Mask = int(cfg.NodeCIDRMaskSizeIPv4)
247-
}
248-
249-
// !maskV4Configured && !maskConfigured && maskV6Configured
250-
if maskV6Configured {
251-
if !isSingleStackIPv6 {
252-
klog.Info("--node-cidr-mask-size-ipv6 should not be used for a single-stack IPv4 cluster")
253-
}
254-
255-
ipv6Mask = int(cfg.NodeCIDRMaskSizeIPv6)
256-
}
257-
return sortedSizes(ipv4Mask, ipv6Mask), nil
258-
}
92+
}

0 commit comments

Comments
 (0)