diff --git a/cluster/gce/trusty/configure-helper.sh b/cluster/gce/trusty/configure-helper.sh index bf916258c9b..5b0b5708a1e 100644 --- a/cluster/gce/trusty/configure-helper.sh +++ b/cluster/gce/trusty/configure-helper.sh @@ -483,6 +483,9 @@ start_kube_controller_manager() { if [ -n "${CLUSTER_IP_RANGE:-}" ]; then params="${params} --cluster-cidr=${CLUSTER_IP_RANGE}" fi + if [ -n "${SERVICE_IP_RANGE:-}" ]; then + params="${params} --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}" + fi if [ "${ALLOCATE_NODE_CIDRS:-}" = "true" ]; then params="${params} --allocate-node-cidrs=${ALLOCATE_NODE_CIDRS}" fi diff --git a/cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest b/cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest index e13048abeaa..57ddf07dde7 100644 --- a/cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest +++ b/cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest @@ -1,6 +1,7 @@ {% set cluster_name = "" -%} {% set cluster_cidr = "" -%} {% set allocate_node_cidrs = "" -%} +{% set service_cluster_ip_range = "" %} {% set terminated_pod_gc = "" -%} @@ -10,6 +11,9 @@ {% if pillar['cluster_cidr'] is defined and pillar['cluster_cidr'] != "" -%} {% set cluster_cidr = "--cluster-cidr=" + pillar['cluster_cidr'] -%} {% endif -%} +{% if pillar['service_cluster_ip_range'] is defined and pillar['service_cluster_ip_range'] != "" -%} + {% set service_cluster_ip_range = "--service_cluster_ip_range=" + pillar['service_cluster_ip_range'] -%} +{% endif -%} # When we're using flannel it is responsible for cidr allocation. # This is expected to be a short-term compromise. {% if pillar.get('network_provider', '').lower() == 'flannel' %} @@ -59,7 +63,7 @@ {% set log_level = pillar['controller_manager_test_log_level'] -%} {% endif -%} -{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + terminated_pod_gc + " " + cloud_provider + " " + cloud_config + " " + service_account_key + " " + log_level + " " + root_ca_file -%} +{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + service_cluster_ip_range + " " + terminated_pod_gc + " " + cloud_provider + " " + cloud_config + " " + service_account_key + " " + log_level + " " + root_ca_file -%} # test_args has to be kept at the end, so they'll overwrite any prior configuration diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index af2239c96c3..1d6abfd488f 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -206,7 +206,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string go podInformer.Run(wait.NeverStop) nodeController := nodecontroller.NewNodeController(nil, clientset, 5*time.Minute, flowcontrol.NewFakeAlwaysRateLimiter(), flowcontrol.NewFakeAlwaysRateLimiter(), - 40*time.Second, 60*time.Second, 5*time.Second, nil, false) + 40*time.Second, 60*time.Second, 5*time.Second, nil, nil, 0, false) nodeController.Run(5 * time.Second) cadvisorInterface := new(cadvisortest.Fake) diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 6d807064f23..a1f6618f655 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -227,10 +227,11 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig // this cidr has been validated already _, clusterCIDR, _ := net.ParseCIDR(s.ClusterCIDR) + _, serviceCIDR, _ := net.ParseCIDR(s.ServiceCIDR) nodeController := nodecontroller.NewNodeController(cloud, clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "node-controller")), s.PodEvictionTimeout.Duration, flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), - s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, s.AllocateNodeCIDRs) + s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, serviceCIDR, int(s.NodeCIDRMaskSize), s.AllocateNodeCIDRs) nodeController.Run(s.NodeSyncPeriod.Duration) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 180120cd470..61b0ffc34be 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -70,6 +70,7 @@ func NewCMServer() *CMServer { NodeStartupGracePeriod: unversioned.Duration{Duration: 60 * time.Second}, NodeMonitorPeriod: unversioned.Duration{Duration: 5 * time.Second}, ClusterName: "kubernetes", + NodeCIDRMaskSize: 24, TerminatedPodGCThreshold: 12500, VolumeConfiguration: componentconfig.VolumeConfiguration{ EnableHostPathProvisioning: false, @@ -141,6 +142,8 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster") fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.") + fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster.") + fs.Int32Var(&s.NodeCIDRMaskSize, "node-cidr-mask-size", s.NodeCIDRMaskSize, "Mask size for node cidr in cluster.") fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)") fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") diff --git a/contrib/mesos/pkg/controllermanager/controllermanager.go b/contrib/mesos/pkg/controllermanager/controllermanager.go index 1babe70557e..7d843604f86 100644 --- a/contrib/mesos/pkg/controllermanager/controllermanager.go +++ b/contrib/mesos/pkg/controllermanager/controllermanager.go @@ -153,10 +153,11 @@ func (s *CMServer) Run(_ []string) error { glog.Fatalf("Cloud provider could not be initialized: %v", err) } _, clusterCIDR, _ := net.ParseCIDR(s.ClusterCIDR) + _, serviceCIDR, _ := net.ParseCIDR(s.ServiceCIDR) nodeController := nodecontroller.NewNodeController(cloud, clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "node-controller")), s.PodEvictionTimeout.Duration, flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), - s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, s.AllocateNodeCIDRs) + s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, serviceCIDR, int(s.NodeCIDRMaskSize), s.AllocateNodeCIDRs) nodeController.Run(s.NodeSyncPeriod.Duration) nodeStatusUpdaterController := node.NewStatusUpdater(clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "node-status-controller")), s.NodeMonitorPeriod.Duration, time.Now) diff --git a/docs/admin/kube-controller-manager.md b/docs/admin/kube-controller-manager.md index 28db458a13b..bd3e1fcfbf5 100644 --- a/docs/admin/kube-controller-manager.md +++ b/docs/admin/kube-controller-manager.md @@ -87,6 +87,7 @@ kube-controller-manager --master="": The address of the Kubernetes API server (overrides any value in kubeconfig) --min-resync-period=12h0m0s: The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod --namespace-sync-period=5m0s: The period for syncing namespace life-cycle updates + --node-cidr-mask-size=24: Mask size for node cidr in cluster. --node-monitor-grace-period=40s: Amount of time which we allow running Node to be unresponsive before marking it unhealty. Must be N times more than kubelet's nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet to post node status. --node-monitor-period=5s: The period for syncing NodeStatus in NodeController. --node-startup-grace-period=1m0s: Amount of time which we allow starting Node to be unresponsive before marking it unhealty. @@ -106,11 +107,12 @@ kube-controller-manager --resource-quota-sync-period=5m0s: The period for syncing quota usage status in the system --root-ca-file="": If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle. --service-account-private-key-file="": Filename containing a PEM-encoded private RSA key used to sign service account tokens. + --service-cluster-ip-range="": CIDR Range for Services in cluster. --service-sync-period=5m0s: The period for syncing services with their external load balancers --terminated-pod-gc-threshold=12500: Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled. ``` -###### Auto generated by spf13/cobra on 21-Apr-2016 +###### Auto generated by spf13/cobra on 17-May-2016 diff --git a/hack/verify-flags/exceptions.txt b/hack/verify-flags/exceptions.txt index 38d01cef568..703af66d4af 100644 --- a/hack/verify-flags/exceptions.txt +++ b/hack/verify-flags/exceptions.txt @@ -34,7 +34,7 @@ cluster/photon-controller/util.sh: node_name=${1} cluster/rackspace/util.sh: local node_ip=$(nova show --minimal ${NODE_NAMES[$i]} \ cluster/saltbase/salt/kube-admission-controls/init.sls:{% if 'LimitRanger' in pillar.get('admission_control', '') %} cluster/saltbase/salt/kube-apiserver/kube-apiserver.manifest:{% set params = address + " " + etcd_servers + " " + etcd_servers_overrides + " " + cloud_provider + " " + cloud_config + " " + runtime_config + " " + admission_control + " " + service_cluster_ip_range + " " + client_ca_file + basic_auth_file + " " + min_request_timeout -%} -cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest:{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + terminated_pod_gc + " " + cloud_provider + " " + cloud_config + " " + service_account_key + " " + log_level + " " + root_ca_file -%} +cluster/saltbase/salt/kube-controller-manager/kube-controller-manager.manifest:{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + service_cluster_ip_range + " " + terminated_pod_gc + " " + cloud_provider + " " + cloud_config + " " + service_account_key + " " + log_level + " " + root_ca_file -%} cluster/saltbase/salt/kube-proxy/kube-proxy.manifest: {% set api_servers_with_port = api_servers + ":6443" -%} cluster/saltbase/salt/kube-proxy/kube-proxy.manifest: {% set api_servers_with_port = api_servers -%} cluster/saltbase/salt/kube-proxy/kube-proxy.manifest: {% set cluster_cidr=" --cluster-cidr=" + pillar['cluster_cidr'] %} diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 5054adf6e8f..1dd97599f93 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -287,6 +287,7 @@ network-plugin network-plugin-dir no-headers no-suggestions +node-cidr-mask-size node-instance-group node-ip node-labels diff --git a/pkg/apis/componentconfig/deep_copy_generated.go b/pkg/apis/componentconfig/deep_copy_generated.go index bb85bdb016c..8e74f99f126 100644 --- a/pkg/apis/componentconfig/deep_copy_generated.go +++ b/pkg/apis/componentconfig/deep_copy_generated.go @@ -117,6 +117,8 @@ func DeepCopy_componentconfig_KubeControllerManagerConfiguration(in KubeControll out.EnableProfiling = in.EnableProfiling out.ClusterName = in.ClusterName out.ClusterCIDR = in.ClusterCIDR + out.ServiceCIDR = in.ServiceCIDR + out.NodeCIDRMaskSize = in.NodeCIDRMaskSize out.AllocateNodeCIDRs = in.AllocateNodeCIDRs out.RootCAFile = in.RootCAFile out.ContentType = in.ContentType diff --git a/pkg/apis/componentconfig/types.generated.go b/pkg/apis/componentconfig/types.generated.go index 14f452a40e6..ec9bd0e1603 100644 --- a/pkg/apis/componentconfig/types.generated.go +++ b/pkg/apis/componentconfig/types.generated.go @@ -6280,16 +6280,16 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [45]bool + var yyq2 [47]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[43] = x.Kind != "" - yyq2[44] = x.APIVersion != "" + yyq2[45] = x.Kind != "" + yyq2[46] = x.APIVersion != "" var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(45) + r.EncodeArrayStart(47) } else { - yynn2 = 43 + yynn2 = 45 for _, b := range yyq2 { if b { yynn2++ @@ -7065,17 +7065,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym133 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceCIDR)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) + r.EncodeString(codecSelferC_UTF81234, string("serviceCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym134 := z.EncBinary() _ = yym134 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceCIDR)) } } if yyr2 || yy2arr2 { @@ -7084,17 +7084,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym136 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeInt(int64(x.NodeCIDRMaskSize)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("rootCAFile")) + r.EncodeString(codecSelferC_UTF81234, string("nodeCIDRMaskSize")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym137 := z.EncBinary() _ = yym137 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeInt(int64(x.NodeCIDRMaskSize)) } } if yyr2 || yy2arr2 { @@ -7103,17 +7103,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym139 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("contentType")) + r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym140 := z.EncBinary() _ = yym140 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } if yyr2 || yy2arr2 { @@ -7122,17 +7122,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym142 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + r.EncodeString(codecSelferC_UTF81234, string("rootCAFile")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym143 := z.EncBinary() _ = yym143 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) } } if yyr2 || yy2arr2 { @@ -7140,6 +7140,44 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode yym145 := z.EncBinary() _ = yym145 if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("contentType")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym146 := z.EncBinary() + _ = yym146 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym148 := z.EncBinary() + _ = yym148 + if false { + } else { + r.EncodeFloat32(float32(x.KubeAPIQPS)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym149 := z.EncBinary() + _ = yym149 + if false { + } else { + r.EncodeFloat32(float32(x.KubeAPIQPS)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym151 := z.EncBinary() + _ = yym151 + if false { } else { r.EncodeInt(int64(x.KubeAPIBurst)) } @@ -7147,8 +7185,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("kubeAPIBurst")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym146 := z.EncBinary() - _ = yym146 + yym152 := z.EncBinary() + _ = yym152 if false { } else { r.EncodeInt(int64(x.KubeAPIBurst)) @@ -7156,58 +7194,58 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy148 := &x.LeaderElection - yy148.CodecEncodeSelf(e) + yy154 := &x.LeaderElection + yy154.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("leaderElection")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy150 := &x.LeaderElection - yy150.CodecEncodeSelf(e) + yy156 := &x.LeaderElection + yy156.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy153 := &x.VolumeConfiguration - yy153.CodecEncodeSelf(e) + yy159 := &x.VolumeConfiguration + yy159.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("volumeConfiguration")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy155 := &x.VolumeConfiguration - yy155.CodecEncodeSelf(e) + yy161 := &x.VolumeConfiguration + yy161.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy158 := &x.ControllerStartInterval - yym159 := z.EncBinary() - _ = yym159 + yy164 := &x.ControllerStartInterval + yym165 := z.EncBinary() + _ = yym165 if false { - } else if z.HasExtensions() && z.EncExt(yy158) { - } else if !yym159 && z.IsJSONHandle() { - z.EncJSONMarshal(yy158) + } else if z.HasExtensions() && z.EncExt(yy164) { + } else if !yym165 && z.IsJSONHandle() { + z.EncJSONMarshal(yy164) } else { - z.EncFallback(yy158) + z.EncFallback(yy164) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("controllerStartInterval")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy160 := &x.ControllerStartInterval - yym161 := z.EncBinary() - _ = yym161 + yy166 := &x.ControllerStartInterval + yym167 := z.EncBinary() + _ = yym167 if false { - } else if z.HasExtensions() && z.EncExt(yy160) { - } else if !yym161 && z.IsJSONHandle() { - z.EncJSONMarshal(yy160) + } else if z.HasExtensions() && z.EncExt(yy166) { + } else if !yym167 && z.IsJSONHandle() { + z.EncJSONMarshal(yy166) } else { - z.EncFallback(yy160) + z.EncFallback(yy166) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[43] { - yym163 := z.EncBinary() - _ = yym163 + if yyq2[45] { + yym169 := z.EncBinary() + _ = yym169 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -7216,12 +7254,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[43] { + if yyq2[45] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("kind")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym164 := z.EncBinary() - _ = yym164 + yym170 := z.EncBinary() + _ = yym170 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -7230,9 +7268,9 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[44] { - yym166 := z.EncBinary() - _ = yym166 + if yyq2[46] { + yym172 := z.EncBinary() + _ = yym172 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -7241,12 +7279,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[44] { + if yyq2[46] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym167 := z.EncBinary() - _ = yym167 + yym173 := z.EncBinary() + _ = yym173 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -7632,6 +7670,18 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co } else { x.ClusterCIDR = string(r.DecodeString()) } + case "serviceCIDR": + if r.TryDecodeAsNil() { + x.ServiceCIDR = "" + } else { + x.ServiceCIDR = string(r.DecodeString()) + } + case "nodeCIDRMaskSize": + if r.TryDecodeAsNil() { + x.NodeCIDRMaskSize = 0 + } else { + x.NodeCIDRMaskSize = int32(r.DecodeInt(32)) + } case "allocateNodeCIDRs": if r.TryDecodeAsNil() { x.AllocateNodeCIDRs = false @@ -7666,29 +7716,29 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv56 := &x.LeaderElection - yyv56.CodecDecodeSelf(d) + yyv58 := &x.LeaderElection + yyv58.CodecDecodeSelf(d) } case "volumeConfiguration": if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv57 := &x.VolumeConfiguration - yyv57.CodecDecodeSelf(d) + yyv59 := &x.VolumeConfiguration + yyv59.CodecDecodeSelf(d) } case "controllerStartInterval": if r.TryDecodeAsNil() { x.ControllerStartInterval = pkg1_unversioned.Duration{} } else { - yyv58 := &x.ControllerStartInterval - yym59 := z.DecBinary() - _ = yym59 + yyv60 := &x.ControllerStartInterval + yym61 := z.DecBinary() + _ = yym61 if false { - } else if z.HasExtensions() && z.DecExt(yyv58) { - } else if !yym59 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv58) + } else if z.HasExtensions() && z.DecExt(yyv60) { + } else if !yym61 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv60) } else { - z.DecFallback(yyv58, false) + z.DecFallback(yyv60, false) } } case "kind": @@ -7714,16 +7764,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj62 int - var yyb62 bool - var yyhl62 bool = l >= 0 - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + var yyj64 int + var yyb64 bool + var yyhl64 bool = l >= 0 + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7733,13 +7783,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Port = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7749,13 +7799,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Address = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7765,13 +7815,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudProvider = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7781,13 +7831,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudConfigFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7797,13 +7847,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentEndpointSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7813,13 +7863,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRSSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7829,13 +7879,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRCSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7845,13 +7895,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentResourceQuotaSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7861,13 +7911,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDeploymentSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7877,13 +7927,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDaemonSetSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7893,13 +7943,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentJobSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7909,13 +7959,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentNamespaceSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7925,13 +7975,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRC = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7941,13 +7991,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRS = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7957,13 +8007,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForDaemonSet = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7971,32 +8021,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.ServiceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv78 := &x.ServiceSyncPeriod - yym79 := z.DecBinary() - _ = yym79 - if false { - } else if z.HasExtensions() && z.DecExt(yyv78) { - } else if !yym79 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv78) - } else { - z.DecFallback(yyv78, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.NodeSyncPeriod = pkg1_unversioned.Duration{} - } else { - yyv80 := &x.NodeSyncPeriod + yyv80 := &x.ServiceSyncPeriod yym81 := z.DecBinary() _ = yym81 if false { @@ -8007,21 +8032,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv80, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} + x.NodeSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv82 := &x.ResourceQuotaSyncPeriod + yyv82 := &x.NodeSyncPeriod yym83 := z.DecBinary() _ = yym83 if false { @@ -8032,21 +8057,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv82, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} + x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv84 := &x.NamespaceSyncPeriod + yyv84 := &x.ResourceQuotaSyncPeriod yym85 := z.DecBinary() _ = yym85 if false { @@ -8057,21 +8082,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv84, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} + x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv86 := &x.PVClaimBinderSyncPeriod + yyv86 := &x.NamespaceSyncPeriod yym87 := z.DecBinary() _ = yym87 if false { @@ -8082,21 +8107,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv86, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.MinResyncPeriod = pkg1_unversioned.Duration{} + x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv88 := &x.MinResyncPeriod + yyv88 := &x.PVClaimBinderSyncPeriod yym89 := z.DecBinary() _ = yym89 if false { @@ -8107,13 +8132,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv88, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.MinResyncPeriod = pkg1_unversioned.Duration{} + } else { + yyv90 := &x.MinResyncPeriod + yym91 := z.DecBinary() + _ = yym91 + if false { + } else if z.HasExtensions() && z.DecExt(yyv90) { + } else if !yym91 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv90) + } else { + z.DecFallback(yyv90, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8123,13 +8173,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.TerminatedPodGCThreshold = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8137,32 +8187,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.HorizontalPodAutoscalerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv91 := &x.HorizontalPodAutoscalerSyncPeriod - yym92 := z.DecBinary() - _ = yym92 - if false { - } else if z.HasExtensions() && z.DecExt(yyv91) { - } else if !yym92 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv91) - } else { - z.DecFallback(yyv91, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} - } else { - yyv93 := &x.DeploymentControllerSyncPeriod + yyv93 := &x.HorizontalPodAutoscalerSyncPeriod yym94 := z.DecBinary() _ = yym94 if false { @@ -8173,21 +8198,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv93, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PodEvictionTimeout = pkg1_unversioned.Duration{} + x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv95 := &x.PodEvictionTimeout + yyv95 := &x.DeploymentControllerSyncPeriod yym96 := z.DecBinary() _ = yym96 if false { @@ -8198,13 +8223,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv95, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.PodEvictionTimeout = pkg1_unversioned.Duration{} + } else { + yyv97 := &x.PodEvictionTimeout + yym98 := z.DecBinary() + _ = yym98 + if false { + } else if z.HasExtensions() && z.DecExt(yyv97) { + } else if !yym98 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv97) + } else { + z.DecFallback(yyv97, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8214,13 +8264,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsQps = float32(r.DecodeFloat(true)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8230,13 +8280,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsBurst = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8244,24 +8294,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeMonitorGracePeriod = pkg1_unversioned.Duration{} } else { - yyv99 := &x.NodeMonitorGracePeriod - yym100 := z.DecBinary() - _ = yym100 + yyv101 := &x.NodeMonitorGracePeriod + yym102 := z.DecBinary() + _ = yym102 if false { - } else if z.HasExtensions() && z.DecExt(yyv99) { - } else if !yym100 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv99) + } else if z.HasExtensions() && z.DecExt(yyv101) { + } else if !yym102 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv101) } else { - z.DecFallback(yyv99, false) + z.DecFallback(yyv101, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8271,13 +8321,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RegisterRetryCount = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8285,32 +8335,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeStartupGracePeriod = pkg1_unversioned.Duration{} } else { - yyv102 := &x.NodeStartupGracePeriod - yym103 := z.DecBinary() - _ = yym103 - if false { - } else if z.HasExtensions() && z.DecExt(yyv102) { - } else if !yym103 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv102) - } else { - z.DecFallback(yyv102, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.NodeMonitorPeriod = pkg1_unversioned.Duration{} - } else { - yyv104 := &x.NodeMonitorPeriod + yyv104 := &x.NodeStartupGracePeriod yym105 := z.DecBinary() _ = yym105 if false { @@ -8321,13 +8346,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv104, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.NodeMonitorPeriod = pkg1_unversioned.Duration{} + } else { + yyv106 := &x.NodeMonitorPeriod + yym107 := z.DecBinary() + _ = yym107 + if false { + } else if z.HasExtensions() && z.DecExt(yyv106) { + } else if !yym107 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv106) + } else { + z.DecFallback(yyv106, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8337,13 +8387,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ServiceAccountKeyFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8353,13 +8403,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.EnableProfiling = bool(r.DecodeBool()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8369,13 +8419,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterName = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8385,13 +8435,45 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterCIDR = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ServiceCIDR = "" + } else { + x.ServiceCIDR = string(r.DecodeString()) + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.NodeCIDRMaskSize = 0 + } else { + x.NodeCIDRMaskSize = int32(r.DecodeInt(32)) + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8401,13 +8483,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.AllocateNodeCIDRs = bool(r.DecodeBool()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8417,13 +8499,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RootCAFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8433,13 +8515,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ContentType = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8449,13 +8531,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIQPS = float32(r.DecodeFloat(true)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8465,13 +8547,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIBurst = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8479,16 +8561,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv115 := &x.LeaderElection - yyv115.CodecDecodeSelf(d) + yyv119 := &x.LeaderElection + yyv119.CodecDecodeSelf(d) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8496,16 +8578,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv116 := &x.VolumeConfiguration - yyv116.CodecDecodeSelf(d) + yyv120 := &x.VolumeConfiguration + yyv120.CodecDecodeSelf(d) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8513,24 +8595,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.ControllerStartInterval = pkg1_unversioned.Duration{} } else { - yyv117 := &x.ControllerStartInterval - yym118 := z.DecBinary() - _ = yym118 + yyv121 := &x.ControllerStartInterval + yym122 := z.DecBinary() + _ = yym122 if false { - } else if z.HasExtensions() && z.DecExt(yyv117) { - } else if !yym118 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv117) + } else if z.HasExtensions() && z.DecExt(yyv121) { + } else if !yym122 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv121) } else { - z.DecFallback(yyv117, false) + z.DecFallback(yyv121, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8540,13 +8622,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Kind = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8557,17 +8639,17 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * x.APIVersion = string(r.DecodeString()) } for { - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj62-1, "") + z.DecStructFieldNotFound(yyj64-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index 0b1e060de14..3e433a45962 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -522,6 +522,10 @@ type KubeControllerManagerConfiguration struct { ClusterName string `json:"clusterName"` // clusterCIDR is CIDR Range for Pods in cluster. ClusterCIDR string `json:"clusterCIDR"` + // serviceCIDR is CIDR Range for Services in cluster. + ServiceCIDR string `json:"serviceCIDR"` + // NodeCIDRMaskSize is the mask size for node cidr in cluster. + NodeCIDRMaskSize int32 `json:"nodeCIDRMaskSize"` // allocateNodeCIDRs enables CIDRs for Pods to be allocated and set on the // cloud provider. AllocateNodeCIDRs bool `json:"allocateNodeCIDRs"` diff --git a/pkg/controller/node/cidr_allocator.go b/pkg/controller/node/cidr_allocator.go new file mode 100644 index 00000000000..4bb4a2503d9 --- /dev/null +++ b/pkg/controller/node/cidr_allocator.go @@ -0,0 +1,157 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package node + +import ( + "encoding/binary" + "errors" + "fmt" + "math/big" + "net" + "sync" +) + +var errCIDRRangeNoCIDRsRemaining = errors.New("CIDR allocation failed; there are no remaining CIDRs left to allocate in the accepted range") + +// CIDRAllocator is an interface implemented by things that know how to allocate/occupy/recycle CIDR for nodes. +type CIDRAllocator interface { + AllocateNext() (*net.IPNet, error) + Occupy(*net.IPNet) error + Release(*net.IPNet) error +} + +type rangeAllocator struct { + clusterCIDR *net.IPNet + clusterIP net.IP + clusterMaskSize int + subNetMaskSize int + maxCIDRs int + used big.Int + lock sync.Mutex +} + +// NewCIDRRangeAllocator returns a CIDRAllocator to allocate CIDR for node +// Caller must ensure subNetMaskSize is not less than cluster CIDR mask size. +func NewCIDRRangeAllocator(clusterCIDR *net.IPNet, subNetMaskSize int) CIDRAllocator { + clusterMask := clusterCIDR.Mask + clusterMaskSize, _ := clusterMask.Size() + + ra := &rangeAllocator{ + clusterCIDR: clusterCIDR, + clusterIP: clusterCIDR.IP.To4(), + clusterMaskSize: clusterMaskSize, + subNetMaskSize: subNetMaskSize, + maxCIDRs: 1 << uint32(subNetMaskSize-clusterMaskSize), + } + return ra +} + +func (r *rangeAllocator) AllocateNext() (*net.IPNet, error) { + r.lock.Lock() + defer r.lock.Unlock() + + nextUnused := -1 + for i := 0; i < r.maxCIDRs; i++ { + if r.used.Bit(i) == 0 { + nextUnused = i + break + } + } + if nextUnused == -1 { + return nil, errCIDRRangeNoCIDRsRemaining + } + + r.used.SetBit(&r.used, nextUnused, 1) + + j := uint32(nextUnused) << uint32(32-r.subNetMaskSize) + ipInt := (binary.BigEndian.Uint32(r.clusterIP)) | j + ip := make([]byte, 4) + binary.BigEndian.PutUint32(ip, ipInt) + + return &net.IPNet{ + IP: ip, + Mask: net.CIDRMask(r.subNetMaskSize, 32), + }, nil +} + +func (r *rangeAllocator) Release(cidr *net.IPNet) error { + used, err := r.getIndexForCIDR(cidr) + if err != nil { + return err + } + + r.lock.Lock() + defer r.lock.Unlock() + r.used.SetBit(&r.used, used, 0) + + return nil +} + +func (r *rangeAllocator) MaxCIDRs() int { + return r.maxCIDRs +} + +func (r *rangeAllocator) Occupy(cidr *net.IPNet) (err error) { + begin, end := 0, r.maxCIDRs + cidrMask := cidr.Mask + maskSize, _ := cidrMask.Size() + + if !r.clusterCIDR.Contains(cidr.IP.Mask(r.clusterCIDR.Mask)) && !cidr.Contains(r.clusterCIDR.IP.Mask(cidr.Mask)) { + return fmt.Errorf("cidr %v is out the range of cluster cidr %v", cidr, r.clusterCIDR) + } + + if r.clusterMaskSize < maskSize { + subNetMask := net.CIDRMask(r.subNetMaskSize, 32) + begin, err = r.getIndexForCIDR(&net.IPNet{ + IP: cidr.IP.To4().Mask(subNetMask), + Mask: subNetMask, + }) + if err != nil { + return err + } + + ip := make([]byte, 4) + ipInt := binary.BigEndian.Uint32(cidr.IP) | (^binary.BigEndian.Uint32(cidr.Mask)) + binary.BigEndian.PutUint32(ip, ipInt) + end, err = r.getIndexForCIDR(&net.IPNet{ + IP: net.IP(ip).To4().Mask(subNetMask), + Mask: subNetMask, + }) + if err != nil { + return err + } + } + + r.lock.Lock() + defer r.lock.Unlock() + + for i := begin; i <= end; i++ { + r.used.SetBit(&r.used, i, 1) + } + + return nil +} + +func (r *rangeAllocator) getIndexForCIDR(cidr *net.IPNet) (int, error) { + cidrIndex := (binary.BigEndian.Uint32(r.clusterIP) ^ binary.BigEndian.Uint32(cidr.IP.To4())) >> uint32(32-r.subNetMaskSize) + + if cidrIndex >= uint32(r.maxCIDRs) { + return 0, fmt.Errorf("CIDR: %v is out of the range of CIDR allocator", cidr) + } + + return int(cidrIndex), nil +} diff --git a/pkg/controller/node/cidr_allocator_test.go b/pkg/controller/node/cidr_allocator_test.go new file mode 100644 index 00000000000..37cfdf67bab --- /dev/null +++ b/pkg/controller/node/cidr_allocator_test.go @@ -0,0 +1,350 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package node + +import ( + "github.com/golang/glog" + "math/big" + "net" + "reflect" + "testing" +) + +func TestRangeAllocatorFullyAllocated(t *testing.T) { + _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/30") + a := NewCIDRRangeAllocator(clusterCIDR, 30) + p, err := a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if p.String() != "127.123.234.0/30" { + t.Fatalf("unexpected allocated cidr: %s", p.String()) + } + + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } + + a.Release(p) + p, err = a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if p.String() != "127.123.234.0/30" { + t.Fatalf("unexpected allocated cidr: %s", p.String()) + } + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } +} + +func TestRangeAllocator_RandomishAllocation(t *testing.T) { + _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/16") + a := NewCIDRRangeAllocator(clusterCIDR, 24) + + // allocate all the CIDRs + var err error + cidrs := make([]*net.IPNet, 256) + + for i := 0; i < 256; i++ { + cidrs[i], err = a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + } + + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } + // release them all + for i := 0; i < 256; i++ { + a.Release(cidrs[i]) + } + + // allocate the CIDRs again + rcidrs := make([]*net.IPNet, 256) + for i := 0; i < 256; i++ { + rcidrs[i], err = a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %d, %v", i, err) + } + } + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } + + if !reflect.DeepEqual(cidrs, rcidrs) { + t.Fatalf("expected re-allocated cidrs are the same collection") + } +} + +func TestRangeAllocator_AllocationOccupied(t *testing.T) { + _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/16") + a := NewCIDRRangeAllocator(clusterCIDR, 24) + + // allocate all the CIDRs + var err error + cidrs := make([]*net.IPNet, 256) + + for i := 0; i < 256; i++ { + cidrs[i], err = a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + } + + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } + // release them all + for i := 0; i < 256; i++ { + a.Release(cidrs[i]) + } + // occupy the last 128 CIDRs + for i := 128; i < 256; i++ { + a.Occupy(cidrs[i]) + } + + // allocate the first 128 CIDRs again + rcidrs := make([]*net.IPNet, 128) + for i := 0; i < 128; i++ { + rcidrs[i], err = a.AllocateNext() + if err != nil { + t.Fatalf("unexpected error: %d, %v", i, err) + } + } + _, err = a.AllocateNext() + if err == nil { + t.Fatalf("expected error because of fully-allocated range") + } + + // check Occupy() work properly + for i := 128; i < 256; i++ { + rcidrs = append(rcidrs, cidrs[i]) + } + if !reflect.DeepEqual(cidrs, rcidrs) { + t.Fatalf("expected re-allocated cidrs are the same collection") + } +} + +func TestGetBitforCIDR(t *testing.T) { + cases := []struct { + clusterCIDRStr string + subNetMaskSize int + subNetCIDRStr string + expectedBit int + expectErr bool + }{ + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.0.0.0/16", + expectedBit: 0, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.123.0.0/16", + expectedBit: 123, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.168.0.0/16", + expectedBit: 168, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.224.0.0/16", + expectedBit: 224, + expectErr: false, + }, + { + clusterCIDRStr: "192.168.0.0/16", + subNetMaskSize: 24, + subNetCIDRStr: "192.168.12.0/24", + expectedBit: 12, + expectErr: false, + }, + { + clusterCIDRStr: "192.168.0.0/16", + subNetMaskSize: 24, + subNetCIDRStr: "192.168.151.0/24", + expectedBit: 151, + expectErr: false, + }, + { + clusterCIDRStr: "192.168.0.0/16", + subNetMaskSize: 24, + subNetCIDRStr: "127.168.224.0/24", + expectErr: true, + }, + } + + for _, tc := range cases { + _, clusterCIDR, err := net.ParseCIDR(tc.clusterCIDRStr) + clusterMask := clusterCIDR.Mask + clusterMaskSize, _ := clusterMask.Size() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + ra := &rangeAllocator{ + clusterIP: clusterCIDR.IP.To4(), + clusterMaskSize: clusterMaskSize, + subNetMaskSize: tc.subNetMaskSize, + maxCIDRs: 1 << uint32(tc.subNetMaskSize-clusterMaskSize), + } + + _, subnetCIDR, err := net.ParseCIDR(tc.subNetCIDRStr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + got, err := ra.getIndexForCIDR(subnetCIDR) + if err == nil && tc.expectErr { + glog.Errorf("expected error but got null") + continue + } + + if err != nil && !tc.expectErr { + glog.Errorf("unexpected error: %v", err) + continue + } + + if got != tc.expectedBit { + glog.Errorf("expected %v, but got %v", tc.expectedBit, got) + } + } +} + +func TestOccupy(t *testing.T) { + cases := []struct { + clusterCIDRStr string + subNetMaskSize int + subNetCIDRStr string + expectedUsedBegin int + expectedUsedEnd int + expectErr bool + }{ + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.0.0.0/8", + expectedUsedBegin: 0, + expectedUsedEnd: 256, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.0.0.0/2", + expectedUsedBegin: 0, + expectedUsedEnd: 256, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 16, + subNetCIDRStr: "127.0.0.0/16", + expectedUsedBegin: 0, + expectedUsedEnd: 0, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/8", + subNetMaskSize: 32, + subNetCIDRStr: "127.0.0.0/16", + expectedUsedBegin: 0, + expectedUsedEnd: 65535, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/7", + subNetMaskSize: 16, + subNetCIDRStr: "127.0.0.0/15", + expectedUsedBegin: 256, + expectedUsedEnd: 257, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/7", + subNetMaskSize: 15, + subNetCIDRStr: "127.0.0.0/15", + expectedUsedBegin: 128, + expectedUsedEnd: 128, + expectErr: false, + }, + { + clusterCIDRStr: "127.0.0.0/7", + subNetMaskSize: 18, + subNetCIDRStr: "127.0.0.0/15", + expectedUsedBegin: 1024, + expectedUsedEnd: 1031, + expectErr: false, + }, + } + + for _, tc := range cases { + _, clusterCIDR, err := net.ParseCIDR(tc.clusterCIDRStr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + clusterMask := clusterCIDR.Mask + clusterMaskSize, _ := clusterMask.Size() + + ra := &rangeAllocator{ + clusterCIDR: clusterCIDR, + clusterIP: clusterCIDR.IP.To4(), + clusterMaskSize: clusterMaskSize, + subNetMaskSize: tc.subNetMaskSize, + maxCIDRs: 1 << uint32(tc.subNetMaskSize-clusterMaskSize), + } + + _, subnetCIDR, err := net.ParseCIDR(tc.subNetCIDRStr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + err = ra.Occupy(subnetCIDR) + if err == nil && tc.expectErr { + t.Errorf("expected error but got none") + continue + } + if err != nil && !tc.expectErr { + t.Errorf("unexpected error: %v", err) + continue + } + + expectedUsed := big.Int{} + for i := tc.expectedUsedBegin; i <= tc.expectedUsedEnd; i++ { + expectedUsed.SetBit(&expectedUsed, i, 1) + } + if expectedUsed.Cmp(&ra.used) != 0 { + t.Errorf("error") + } + } +} diff --git a/pkg/controller/node/nodecontroller.go b/pkg/controller/node/nodecontroller.go index 9f65749a42c..efbd53b0f56 100644 --- a/pkg/controller/node/nodecontroller.go +++ b/pkg/controller/node/nodecontroller.go @@ -57,6 +57,8 @@ var ( const ( // nodeStatusUpdateRetry controls the number of retries of writing NodeStatus update. nodeStatusUpdateRetry = 5 + // podCIDRUpdateRetry controls the number of retries of writing Node.Spec.PodCIDR update. + podCIDRUpdateRetry = 5 // controls how often NodeController will try to evict Pods from non-responsive Nodes. nodeEvictionPeriod = 100 * time.Millisecond ) @@ -71,6 +73,7 @@ type NodeController struct { allocateNodeCIDRs bool cloud cloudprovider.Interface clusterCIDR *net.IPNet + serviceCIDR *net.IPNet deletingPodsRateLimiter flowcontrol.RateLimiter knownNodeSet sets.String kubeClient clientset.Interface @@ -121,6 +124,8 @@ type NodeController struct { // DaemonSet framework and store daemonSetController *framework.Controller daemonSetStore cache.StoreToDaemonSetLister + // allocate/recycle CIDRs for node if allocateNodeCIDRs == true + cidrAllocator CIDRAllocator forcefullyDeletePod func(*api.Pod) error nodeExistsInCloudProvider func(string) (bool, error) @@ -142,6 +147,8 @@ func NewNodeController( nodeStartupGracePeriod time.Duration, nodeMonitorPeriod time.Duration, clusterCIDR *net.IPNet, + serviceCIDR *net.IPNet, + nodeCIDRMaskSize int, allocateNodeCIDRs bool) *NodeController { eventBroadcaster := record.NewBroadcaster() recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "controllermanager"}) @@ -157,8 +164,14 @@ func NewNodeController( metrics.RegisterMetricAndTrackRateLimiterUsage("node_controller", kubeClient.Core().GetRESTClient().GetRateLimiter()) } - if allocateNodeCIDRs && clusterCIDR == nil { - glog.Fatal("NodeController: Must specify clusterCIDR if allocateNodeCIDRs == true.") + if allocateNodeCIDRs { + if clusterCIDR == nil { + glog.Fatal("NodeController: Must specify clusterCIDR if allocateNodeCIDRs == true.") + } + mask := clusterCIDR.Mask + if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSize { + glog.Fatal("NodeController: Invalid clusterCIDR, mask size of clusterCIDR must be less than nodeCIDRMaskSize.") + } } evictorLock := sync.Mutex{} @@ -179,6 +192,7 @@ func NewNodeController( lookupIP: net.LookupIP, now: unversioned.Now, clusterCIDR: clusterCIDR, + serviceCIDR: serviceCIDR, allocateNodeCIDRs: allocateNodeCIDRs, forcefullyDeletePod: func(p *api.Pod) error { return forcefullyDeletePod(kubeClient, p) }, nodeExistsInCloudProvider: func(nodeName string) (bool, error) { return nodeExistsInCloudProvider(cloud, nodeName) }, @@ -204,6 +218,15 @@ func NewNodeController( // they'll get the benefits they expect. It will also reserve the name for future refactorings. cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, ) + + nodeEventHandlerFuncs := framework.ResourceEventHandlerFuncs{} + if nc.allocateNodeCIDRs { + nodeEventHandlerFuncs = framework.ResourceEventHandlerFuncs{ + AddFunc: nc.allocateOrOccupyCIDR, + DeleteFunc: nc.recycleCIDR, + } + } + nc.nodeStore.Store, nc.nodeController = framework.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { @@ -215,8 +238,9 @@ func NewNodeController( }, &api.Node{}, controller.NoResyncPeriodFunc(), - framework.ResourceEventHandlerFuncs{}, + nodeEventHandlerFuncs, ) + nc.daemonSetStore.Store, nc.daemonSetController = framework.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { @@ -230,11 +254,20 @@ func NewNodeController( controller.NoResyncPeriodFunc(), framework.ResourceEventHandlerFuncs{}, ) + + if allocateNodeCIDRs { + nc.cidrAllocator = NewCIDRRangeAllocator(clusterCIDR, nodeCIDRMaskSize) + } + return nc } // Run starts an asynchronous loop that monitors the status of cluster nodes. func (nc *NodeController) Run(period time.Duration) { + if nc.allocateNodeCIDRs { + nc.filterOutServiceRange() + } + go nc.nodeController.Run(wait.NeverStop) go nc.podController.Run(wait.NeverStop) go nc.daemonSetController.Run(wait.NeverStop) @@ -305,17 +338,78 @@ func (nc *NodeController) Run(period time.Duration) { go wait.Until(nc.cleanupOrphanedPods, 30*time.Second, wait.NeverStop) } -// Generates num pod CIDRs that could be assigned to nodes. -func generateCIDRs(clusterCIDR *net.IPNet, num int) sets.String { - res := sets.NewString() - cidrIP := clusterCIDR.IP.To4() - for i := 0; i < num; i++ { - // TODO: Make the CIDRs configurable. - b1 := byte(i >> 8) - b2 := byte(i % 256) - res.Insert(fmt.Sprintf("%d.%d.%d.0/24", cidrIP[0], cidrIP[1]+b1, cidrIP[2]+b2)) +func (nc *NodeController) filterOutServiceRange() { + if !nc.clusterCIDR.Contains(nc.serviceCIDR.IP.Mask(nc.clusterCIDR.Mask)) && !nc.serviceCIDR.Contains(nc.clusterCIDR.IP.Mask(nc.serviceCIDR.Mask)) { + return + } + + if err := nc.cidrAllocator.Occupy(nc.serviceCIDR); err != nil { + glog.Errorf("Error filtering out service cidr: %v", err) + } +} + +// allocateOrOccupyCIDR looks at each new observed node, assigns it a valid CIDR +// if it doesn't currently have one or mark the CIDR as used if the node already have one. +func (nc *NodeController) allocateOrOccupyCIDR(obj interface{}) { + node := obj.(*api.Node) + + if node.Spec.PodCIDR != "" { + _, podCIDR, err := net.ParseCIDR(node.Spec.PodCIDR) + if err != nil { + glog.Errorf("failed to parse node %s, CIDR %s", node.Name, node.Spec.PodCIDR) + return + } + if err := nc.cidrAllocator.Occupy(podCIDR); err != nil { + glog.Errorf("failed to mark cidr as occupied :%v", err) + return + } + return + } + + podCIDR, err := nc.cidrAllocator.AllocateNext() + if err != nil { + nc.recordNodeStatusChange(node, "CIDRNotAvailable") + return + } + + glog.V(4).Infof("Assigning node %s CIDR %s", node.Name, podCIDR) + for rep := 0; rep < podCIDRUpdateRetry; rep++ { + node.Spec.PodCIDR = podCIDR.String() + if _, err := nc.kubeClient.Core().Nodes().Update(node); err == nil { + glog.Errorf("Failed while updating Node.Spec.PodCIDR : %v", err) + break + } + node, err = nc.kubeClient.Core().Nodes().Get(node.Name) + if err != nil { + glog.Errorf("Failed while getting node %v to retry updating Node.Spec.PodCIDR: %v", node.Name, err) + break + } + } + if err != nil { + glog.Errorf("Update PodCIDR of node %v from NodeController exceeds retry count.", node.Name) + nc.recordNodeStatusChange(node, "CIDRAssignmentFailed") + glog.Errorf("CIDR assignment for node %v failed: %v", node.Name, err) + } +} + +// recycleCIDR recycles the CIDR of a removed node +func (nc *NodeController) recycleCIDR(obj interface{}) { + node := obj.(*api.Node) + + if node.Spec.PodCIDR == "" { + return + } + + _, podCIDR, err := net.ParseCIDR(node.Spec.PodCIDR) + if err != nil { + glog.Errorf("failed to parse node %s, CIDR %s", node.Name, node.Spec.PodCIDR) + return + } + + glog.V(4).Infof("recycle node %s CIDR %s", node.Name, podCIDR) + if err := nc.cidrAllocator.Release(podCIDR); err != nil { + glog.Errorf("failed to release cidr: %v", err) } - return res } // getCondition returns a condition object for the specific condition @@ -450,11 +544,6 @@ func (nc *NodeController) monitorNodeStatus() error { } } - if nc.allocateNodeCIDRs { - // TODO (cjcullen): Use pkg/controller/framework to watch nodes and - // reduce lists/decouple this from monitoring status. - nc.reconcileNodeCIDRs(nodes) - } seenReady := false for i := range nodes.Items { var gracePeriod time.Duration @@ -590,42 +679,6 @@ func (nc *NodeController) forcefullyDeleteNode(nodeName string) error { return nil } -// reconcileNodeCIDRs looks at each node and assigns it a valid CIDR -// if it doesn't currently have one. -func (nc *NodeController) reconcileNodeCIDRs(nodes *api.NodeList) { - glog.V(4).Infof("Reconciling cidrs for %d nodes", len(nodes.Items)) - // TODO(roberthbailey): This seems inefficient. Why re-calculate CIDRs - // on each sync period? - availableCIDRs := generateCIDRs(nc.clusterCIDR, len(nodes.Items)) - for _, node := range nodes.Items { - if node.Spec.PodCIDR != "" { - glog.V(4).Infof("CIDR %s is already being used by node %s", node.Spec.PodCIDR, node.Name) - availableCIDRs.Delete(node.Spec.PodCIDR) - } - } - for _, node := range nodes.Items { - if node.Spec.PodCIDR == "" { - // Re-GET node (because ours might be stale by now). - n, err := nc.kubeClient.Core().Nodes().Get(node.Name) - if err != nil { - glog.Errorf("Failed to get node %q: %v", node.Name, err) - continue - } - podCIDR, found := availableCIDRs.PopAny() - if !found { - nc.recordNodeStatusChange(n, "CIDRNotAvailable") - continue - } - glog.V(1).Infof("Assigning node %s CIDR %s", n.Name, podCIDR) - n.Spec.PodCIDR = podCIDR - if _, err := nc.kubeClient.Core().Nodes().Update(n); err != nil { - nc.recordNodeStatusChange(&node, "CIDRAssignmentFailed") - } - } - - } -} - func (nc *NodeController) recordNodeEvent(nodeName, eventtype, reason, event string) { ref := &api.ObjectReference{ Kind: "Node", diff --git a/pkg/controller/node/nodecontroller_test.go b/pkg/controller/node/nodecontroller_test.go index 07d0d436370..e386004c88e 100644 --- a/pkg/controller/node/nodecontroller_test.go +++ b/pkg/controller/node/nodecontroller_test.go @@ -660,7 +660,7 @@ func TestMonitorNodeStatusEvictPods(t *testing.T) { for _, item := range table { nodeController := NewNodeController(nil, item.fakeNodeHandler, evictionTimeout, flowcontrol.NewFakeAlwaysRateLimiter(), flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, - testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) + testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, nil, 0, false) nodeController.now = func() unversioned.Time { return fakeNow } for _, ds := range item.daemonSets { nodeController.daemonSetStore.Add(&ds) @@ -731,7 +731,7 @@ func TestCloudProviderNoRateLimit(t *testing.T) { nodeController := NewNodeController(nil, fnh, 10*time.Minute, flowcontrol.NewFakeAlwaysRateLimiter(), flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, - testNodeMonitorPeriod, nil, false) + testNodeMonitorPeriod, nil, nil, 0, false) nodeController.cloud = &fakecloud.FakeCloud{} nodeController.now = func() unversioned.Time { return unversioned.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC) } nodeController.nodeExistsInCloudProvider = func(nodeName string) (bool, error) { @@ -963,7 +963,7 @@ func TestMonitorNodeStatusUpdateStatus(t *testing.T) { for i, item := range table { nodeController := NewNodeController(nil, item.fakeNodeHandler, 5*time.Minute, flowcontrol.NewFakeAlwaysRateLimiter(), - flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) + flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, nil, 0, false) nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) @@ -1113,7 +1113,7 @@ func TestMonitorNodeStatusMarkPodsNotReady(t *testing.T) { for i, item := range table { nodeController := NewNodeController(nil, item.fakeNodeHandler, 5*time.Minute, flowcontrol.NewFakeAlwaysRateLimiter(), - flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) + flowcontrol.NewFakeAlwaysRateLimiter(), testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, nil, 0, false) nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("Case[%d] unexpected error: %v", i, err) @@ -1195,7 +1195,7 @@ func TestNodeDeletion(t *testing.T) { } nodeController := NewNodeController(nil, fakeNodeHandler, 5*time.Minute, flowcontrol.NewFakeAlwaysRateLimiter(), flowcontrol.NewFakeAlwaysRateLimiter(), - testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, false) + testNodeMonitorGracePeriod, testNodeStartupGracePeriod, testNodeMonitorPeriod, nil, nil, 0, false) nodeController.now = func() unversioned.Time { return fakeNow } if err := nodeController.monitorNodeStatus(); err != nil { t.Errorf("unexpected error: %v", err) @@ -1298,7 +1298,7 @@ func TestCheckPod(t *testing.T) { }, } - nc := NewNodeController(nil, nil, 0, nil, nil, 0, 0, 0, nil, false) + nc := NewNodeController(nil, nil, 0, nil, nil, 0, 0, 0, nil, nil, 0, false) nc.nodeStore.Store = cache.NewStore(cache.MetaNamespaceKeyFunc) nc.nodeStore.Store.Add(&api.Node{ ObjectMeta: api.ObjectMeta{ @@ -1375,7 +1375,7 @@ func TestCleanupOrphanedPods(t *testing.T) { newPod("b", "bar"), newPod("c", "gone"), } - nc := NewNodeController(nil, nil, 0, nil, nil, 0, 0, 0, nil, false) + nc := NewNodeController(nil, nil, 0, nil, nil, 0, 0, 0, nil, nil, 0, false) nc.nodeStore.Store.Add(newNode("foo")) nc.nodeStore.Store.Add(newNode("bar"))