@@ -99,6 +99,7 @@ type serviceInfo struct {
9999 directServerReturnMethod string
100100 hairpin bool
101101 externalIPs []string
102+ local bool
102103}
103104
104105// map of all services, with unique service id(namespace name, service name, port) as key
@@ -422,7 +423,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
422423 Weight : 1 ,
423424 }
424425
425- err := ipvsAddServer (ipvsClusterVipSvc , & dst )
426+ err := ipvsAddServer (ipvsClusterVipSvc , & dst , false , nsc . podCidr )
426427 if err != nil {
427428 glog .Errorf (err .Error ())
428429 }
@@ -432,7 +433,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
432433
433434 if svc .nodePort != 0 {
434435 for i := 0 ; i < len (ipvsNodeportSvcs ); i ++ {
435- err := ipvsAddServer (ipvsNodeportSvcs [i ], & dst )
436+ err := ipvsAddServer (ipvsNodeportSvcs [i ], & dst , svc . local , nsc . podCidr )
436437 if err != nil {
437438 glog .Errorf (err .Error ())
438439 }
@@ -449,7 +450,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
449450 }
450451
451452 // add server to IPVS service
452- err := ipvsAddServer (externalIpService .ipvsSvc , & dst )
453+ err := ipvsAddServer (externalIpService .ipvsSvc , & dst , svc . local , nsc . podCidr )
453454 if err != nil {
454455 glog .Errorf (err .Error ())
455456 }
@@ -784,6 +785,7 @@ func buildServicesInfo() serviceInfoMap {
784785 name : svc .ObjectMeta .Name ,
785786 namespace : svc .ObjectMeta .Namespace ,
786787 externalIPs : make ([]string , len (svc .Spec .ExternalIPs )),
788+ local : false ,
787789 }
788790 dsrMethod , ok := svc .ObjectMeta .Annotations ["kube-router.io/service.dsr" ]
789791 if ok {
@@ -806,6 +808,7 @@ func buildServicesInfo() serviceInfoMap {
806808 copy (svcInfo .externalIPs , svc .Spec .ExternalIPs )
807809 svcInfo .sessionAffinity = (svc .Spec .SessionAffinity == "ClientIP" )
808810 _ , svcInfo .hairpin = svc .ObjectMeta .Annotations ["kube-router.io/service.hairpin" ]
811+ _ , svcInfo .local = svc .ObjectMeta .Annotations ["kube-router.io/service.local" ]
809812
810813 svcId := generateServiceId (svc .Namespace , svc .Name , port .Name )
811814 serviceMap [svcId ] = & svcInfo
@@ -856,8 +859,9 @@ func ensureMasqueradeIptablesRule(masqueradeAll bool, podCidr string) error {
856859 }
857860 }
858861 if len (podCidr ) > 0 {
862+ //TODO: ipset should be used for destination podCidr(s) match after multiple podCidr(s) per node get supported
859863 args = []string {"-m" , "ipvs" , "--ipvs" , "--vdir" , "ORIGINAL" , "--vmethod" , "MASQ" , "-m" , "comment" , "--comment" , "" ,
860- "!" , "-s" , podCidr , "-j" , "MASQUERADE" }
864+ "!" , "-s" , podCidr , "!" , "-d" , podCidr , " -j" , "MASQUERADE" }
861865 err = iptablesCmdHandler .AppendUnique ("nat" , "POSTROUTING" , args ... )
862866 if err != nil {
863867 return errors .New ("Failed to run iptables command" + err .Error ())
@@ -1257,7 +1261,19 @@ func ipvsAddFWMarkService(vip net.IP, protocol, port uint16, persistent bool, sc
12571261 return & svc , nil
12581262}
12591263
1260- func ipvsAddServer (service * ipvs.Service , dest * ipvs.Destination ) error {
1264+ func ipvsAddServer (service * ipvs.Service , dest * ipvs.Destination , local bool , podCidr string ) error {
1265+ //for service.local enabled svc, only forward traffic to the pod on local node
1266+ if local {
1267+ _ , ipnet , err := net .ParseCIDR (podCidr )
1268+ if err != nil {
1269+ glog .Infof ("Failed to ParseCIDR %s for adding destination %s to the service %s" ,
1270+ podCidr , ipvsDestinationString (dest ), ipvsServiceString (service ))
1271+ return nil
1272+ }
1273+ if ! ipnet .Contains (dest .Address ) {
1274+ return nil
1275+ }
1276+ }
12611277
12621278 err := h .NewDestination (service , dest )
12631279 if err == nil {
0 commit comments