Code change:
"-A", string(kubeServicesChain), "-m", "comment", "--comment", proxier.ipsetList[kubeClusterIPSet].getComment(), "-m", "set", "--match-set", kubeClusterIPSet, <del> "dst,dst", </del> ) if proxier.masqueradeAll { <del> writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) </del> <ins> writeLine(proxier.natRules, append(args, "dst,dst", "-j", string(KubeMarkMasqChain))...) </ins> } else if len(proxier.clusterCIDR) > 0 { // This masquerades off-cluster traffic to a service VIP.  The idea // is that you can establish a static route for your Service range, // routing to any node, and that node will bridge into the Service // for you.  Since that might bounce off-node, we masquerade here. // If/when we support "Local" policy for VIPs, we should update this. <del> writeLine(proxier.natRules, append(args, "! -s", proxier.clusterCIDR, "-j", string(KubeMarkMasqChain))...) </del> <ins> writeLine(proxier.natRules, append(args, "dst,dst", "! -s", proxier.clusterCIDR, "-j", string(KubeMarkMasqChain))...) } else { // Masquerade all OUTPUT traffic coming from a service ip. // The kube dummy interface has all service VIPs assigned which // results in the service VIP being picked as the source IP to reach // a VIP. This leads to a connection from VIP:<random port> to // VIP:<service port>. // Always masquerading OUTPUT (node-originating) traffic with a VIP // source ip and service port destination fixes the outgoing connections. writeLine(proxier.natRules, append(args, "src,dst", "-j", string(KubeMarkMasqChain))...) </ins> } }

Related discussion:
text: Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: When using IPVS and not natting (no cluster-cidr specified) requests from the host to service IPs are send with the service ip as the source ip. Let be the kubernetes API IP. Kubeproxy will set up with . This means that traffic from the host (which sees the ) will originate from (best matching ip/network). What you expected to happen: The source ip should be natted to the host ip. How to reproduce it (as minimally and precisely as possible): a ipvs based cluster any cluster-cidr from kube-proxy traffic to a service ip (e.g. http to the kubernetes api server) from the node / host network pod the outgoing interface looking for the service ip () Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration: baremetal OS (e.g. from /etc/os-release): Kernel (e.g. ): (based on the Ubuntu 18.04 kernel) Install tools: custom repackaging of kubernetes release tarballs Others: /sig network
We have a similar issue in kube-router FWIW resolution is included in the issue
Ah nice, I reproduced the source IP selection on my local Ubuntu 18.04 without any kubernetes installed (use ip link add / ip addr add and then ping the new dummy IP / tcpdump lo). Might be related to the kernel version (4.15) as you couldn't reproduce it.... Changing the routing table would avoid an extra NAT rule. That sounds interesting but not doable without changing the kubernetes sources Murali Reddy < am Fr., 27. Apr. 2018, 14:06:
let me try with to reproduce. but its no brainer, this issue must be fixed.
getting closer... -CLUSTER-IP is only populated if masquerade-all or cluster-cidr is used: is no OUTPUT masquerading for service IPs if cluster-cidr is not specified (no branch matches): With cluster-cidr enabled I've saved the ipset.... I've disabled cluster-cidr and rebooted (to reset all iptables/ipset/...).