diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 50d13c57308..7184dcb5048 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -1128,24 +1128,22 @@ func (proxier *Proxier) syncProxyRules() { ) destChain := svcXlbChain - // We have to SNAT packets to external IPs if externalTrafficPolicy is cluster. + // We have to SNAT packets to external IPs if externalTrafficPolicy is cluster + // and the traffic is NOT Local. Local traffic coming from Pods and Nodes will + // be always forwarded to the corresponding Service, so no need to SNAT + // If we can't differentiate the local traffic we always SNAT. if !svcInfo.OnlyNodeLocalEndpoints() { destChain = svcChain - writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) + // This masquerades off-cluster traffic to a External IP. + if proxier.localDetector.IsImplemented() { + writeLine(proxier.natRules, proxier.localDetector.JumpIfNotLocal(args, string(KubeMarkMasqChain))...) + } else { + writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) + } } + // Sent traffic bound for external IPs to the service chain. + writeLine(proxier.natRules, append(args, "-j", string(destChain))...) - // Allow traffic for external IPs that does not come from a bridge (i.e. not from a container) - // nor from a local process to be forwarded to the service. - // This rule roughly translates to "all traffic from off-machine". - // This is imperfect in the face of network plugins that might not use a bridge, but we can revisit that later. - externalTrafficOnlyArgs := append(args, - "-m", "physdev", "!", "--physdev-is-in", - "-m", "addrtype", "!", "--src-type", "LOCAL") - writeLine(proxier.natRules, append(externalTrafficOnlyArgs, "-j", string(destChain))...) - dstLocalOnlyArgs := append(args, "-m", "addrtype", "--dst-type", "LOCAL") - // Allow traffic bound for external IPs that happen to be recognized as local IPs to stay local. - // This covers cases like GCE load-balancers which get added to the local routing table. - writeLine(proxier.natRules, append(dstLocalOnlyArgs, "-j", string(destChain))...) } else { // No endpoints. writeLine(proxier.filterRules,