diff --git a/docs/user-guide.md b/docs/user-guide.md index 8d352c7b8a..a0b3492b3d 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -40,6 +40,7 @@ Usage of kube-router: --advertise-external-ip Add External IP of service to the RIB so that it gets advertised to the BGP peers. --advertise-loadbalancer-ip Add LoadbBalancer IP of service status as set by the LB provider to the RIB so that it gets advertised to the BGP peers. --advertise-pod-cidr Add Node's POD cidr to the RIB so that it gets advertised to the BGP peers. (default true) + --advertise-service-cluster-ip-range string Add Cluster IP range of the service to the rib so that it advertises the IP range to BGP peers. (make sure that the "advertise-cluster-ip=true" flag is also set.) --bgp-graceful-restart Enables the BGP Graceful Restart capability so that routes are preserved on unexpected restarts --bgp-graceful-restart-deferral-time duration BGP Graceful restart deferral time according to RFC4724 4.1, maximum 18h. (default 6m0s) --bgp-port uint16 The port open for incoming BGP connections and to use for connecting with other BGP peers. (default 179) @@ -151,6 +152,8 @@ It does this by: To set the default for all services use the `--advertise-cluster-ip`, `--advertise-external-ip` and `--advertise-loadbalancer-ip` flags. +If you want to advertise the Cluster IP range of the service to BGP peers to reduce the number of routes on the network devices, you can try to set the flags of `advertise-cluster-ip=true` and `advertise-service-cluster-ip-range=ip_range_cidr` at the same time. When this flags is set, Kube-router will add the service cluster IP range set by this parameter to the RIB, and send the routing advertisement of the service cluster IP range to the BGP peer. The purpose of this parameter is to reduce the number of service route entries sent by the Kube-router to the uplink network device. See large-networks03 documentation for details. + To selectively enable or disable this feature per-service use the `kube-router.io/service.advertise.clusterip`, `kube-router.io/service.advertise.externalip` and `kube-router.io/service.advertise.loadbalancerip` annotations. diff --git a/pkg/controllers/routing/bgp_policies.go b/pkg/controllers/routing/bgp_policies.go index c4e4b5d168..70da5ac24d 100644 --- a/pkg/controllers/routing/bgp_policies.go +++ b/pkg/controllers/routing/bgp_policies.go @@ -45,9 +45,17 @@ func (nrc *NetworkRoutingController) AddPolicies() error { // creates prefix set to represent all the advertisable IP associated with the services advIPPrefixList := make([]config.Prefix, 0) advIps, _, _ := nrc.getAllVIPs() - for _, ip := range advIps { - advIPPrefixList = append(advIPPrefixList, config.Prefix{IpPrefix: ip + "/32"}) + + //If the value of advertise-service-cluster-ip-range parameter is not empty, then the value of advertise-service-cluster-ip-range parameter is put into RIB, otherwise it will be done according to the original rules. + if len(nrc.advertiseServiceClusterIpRange) != 0 { + advIPPrefixList = append(advIPPrefixList, config.Prefix{IpPrefix: nrc.advertiseServiceClusterIpRange}) + } else { + for _, ip := range advIps { + //housj add + advIPPrefixList = append(advIPPrefixList, config.Prefix{IpPrefix: ip + "/32"}) + } } + clusterIPPrefixSet, err := table.NewPrefixSet(config.PrefixSet{ PrefixSetName: "clusteripprefixset", PrefixList: advIPPrefixList, diff --git a/pkg/controllers/routing/ecmp_vip.go b/pkg/controllers/routing/ecmp_vip.go index 552a1bd803..a8c45b437a 100644 --- a/pkg/controllers/routing/ecmp_vip.go +++ b/pkg/controllers/routing/ecmp_vip.go @@ -23,22 +23,34 @@ func (nrc *NetworkRoutingController) bgpAdvertiseVIP(vip string) error { bgp.NewPathAttributeNextHop(nrc.nodeIP.String()), } - glog.V(2).Infof("Advertising route: '%s/%s via %s' to peers", vip, strconv.Itoa(32), nrc.nodeIP.String()) - - _, err := nrc.bgpServer.AddPath("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(uint8(32), - vip), false, attrs, time.Now(), false)}) + //If the value of advertise-service-cluster-ip-range parameter is not empty, then the value of advertise-service-cluster-ip-range parameter is put into RIB, otherwise it will be done according to the original rules. + var svcSubnet = vip + var svcCidrLen = 32 + if len(nrc.advertiseServiceClusterIpRange) != 0 { + svcCidrStr := strings.Split(nrc.advertiseServiceClusterIpRange, "/") + svcSubnet = svcCidrStr[0] + svcCidrLen, _ = strconv.Atoi(svcCidrStr[1]) + } + glog.V(2).Infof("Advertising route: '%s/%s via %s' to peers", svcSubnet, strconv.Itoa(svcCidrLen), nrc.nodeIP.String()) + _, err := nrc.bgpServer.AddPath("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(uint8(svcCidrLen), + svcSubnet), false, attrs, time.Now(), false)}) return err } // bgpWithdrawVIP unadvertises the service vip func (nrc *NetworkRoutingController) bgpWithdrawVIP(vip string) error { - glog.V(2).Infof("Withdrawing route: '%s/%s via %s' to peers", vip, strconv.Itoa(32), nrc.nodeIP.String()) - - pathList := []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(uint8(32), - vip), true, nil, time.Now(), false)} - err := nrc.bgpServer.DeletePath([]byte(nil), 0, "", pathList) + //If the value of the advertise-service-cluster-ip-range parameter is not empty, no operation will be performed, otherwise the original rules will be followed. + var err error + if len(nrc.advertiseServiceClusterIpRange) == 0 { + glog.V(2).Infof("Withdrawing route: '%s/%s via %s' to peers", vip, strconv.Itoa(32), nrc.nodeIP.String()) + pathList := []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(uint8(32), + vip), true, nil, time.Now(), false)} + err = nrc.bgpServer.DeletePath([]byte(nil), 0, "", pathList) + } else { + err = nil + } return err } diff --git a/pkg/controllers/routing/network_routes_controller.go b/pkg/controllers/routing/network_routes_controller.go index 07bec13d60..3b185eda04 100644 --- a/pkg/controllers/routing/network_routes_controller.go +++ b/pkg/controllers/routing/network_routes_controller.go @@ -78,6 +78,7 @@ type NetworkRoutingController struct { enablePodEgress bool hostnameOverride string advertiseClusterIP bool + advertiseServiceClusterIpRange string advertiseExternalIP bool advertiseLoadBalancerIP bool advertisePodCidr bool @@ -885,6 +886,7 @@ func NewNetworkRoutingController(clientset kubernetes.Interface, nrc.bgpServerStarted = false nrc.disableSrcDstCheck = kubeRouterConfig.DisableSrcDstCheck nrc.initSrcDstCheckDone = false + nrc.advertiseServiceClusterIpRange = kubeRouterConfig.AdvertiseServiceClusterIpRange nrc.hostnameOverride = kubeRouterConfig.HostnameOverride node, err := utils.GetNodeObject(clientset, nrc.hostnameOverride) diff --git a/pkg/options/options.go b/pkg/options/options.go index d468873a33..c4d5d358a1 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -13,6 +13,7 @@ const DEFAULT_BGP_PORT = 179 type KubeRouterConfig struct { AdvertiseClusterIp bool + AdvertiseServiceClusterIpRange string AdvertiseExternalIp bool AdvertiseNodePodCidr bool AdvertiseLoadBalancerIp bool @@ -118,6 +119,8 @@ func (s *KubeRouterConfig) AddFlags(fs *pflag.FlagSet) { "The delay between route updates and advertisements (e.g. '5s', '1m', '2h22m'). Must be greater than 0.") fs.BoolVar(&s.AdvertiseClusterIp, "advertise-cluster-ip", false, "Add Cluster IP of the service to the RIB so that it gets advertises to the BGP peers.") + fs.StringVar(&s.AdvertiseServiceClusterIpRange, "advertise-service-cluster-ip-range", s.AdvertiseServiceClusterIpRange, + "Add Cluster IP range of the service to the rib so that it advertises the IP range to BGP peers. (make sure that the \"advertise-cluster-ip=true\" flag is also set.)") fs.BoolVar(&s.AdvertiseExternalIp, "advertise-external-ip", false, "Add External IP of service to the RIB so that it gets advertised to the BGP peers.") fs.BoolVar(&s.AdvertiseLoadBalancerIp, "advertise-loadbalancer-ip", false,