Repository navigation
use iptables for proxying instead of userspace #3760
Description
Activity
Cool! I think we should definitely get this merged in. On a separate note, I was seeing the proxy eat ~30% of a core under heavy load, I have to believe that iptables will give us better performance than that.
We have to prioritize this - it's almost a total rewrite of kube-proxy and
all the tests thereof. It also has back-compat problems (will not work on
older kernels or older iptables binaries).On Mon, Jan 26, 2015 at 11:06 AM, Brendan Burns notifications@github.com
wrote:Cool! I think we should definitely get this merged in. On a separate note,
I was seeing the proxy eat ~30% of a core under heavy load, I have to
believe that iptables will give us better performance than that.Reply to this email directly or view it on GitHub
#3760 (comment)
.Maybe implementing it as a parallel option and slowly migrating makes sense?
On Mon, Jan 26, 2015 at 12:01 PM, Tim Hockin notifications@github.com
wrote:We have to prioritize this - it's almost a total rewrite of kube-proxy and
all the tests thereof. It also has back-compat problems (will not work on
older kernels or older iptables binaries).On Mon, Jan 26, 2015 at 11:06 AM, Brendan Burns notifications@github.com
wrote:Cool! I think we should definitely get this merged in. On a separate
note,
I was seeing the proxy eat ~30% of a core under heavy load, I have to
believe that iptables will give us better performance than that.Reply to this email directly or view it on GitHub
<
#3760 (comment).
—
Reply to this email directly or view it on GitHub
#3760 (comment)
.I'm trying to coax someone else who doesn't know this code well to learn it
and take it on. I really want to tackle it, but it would be better if
someone else learned this space (not you! :)That said, you also sent (good) email about the massive P1 list - and I
don;t think this is on that list yet.On Mon, Jan 26, 2015 at 1:06 PM, Brendan Burns notifications@github.com
wrote:Maybe implementing it as a parallel option and slowly migrating makes
sense?On Mon, Jan 26, 2015 at 12:01 PM, Tim Hockin notifications@github.com
wrote:We have to prioritize this - it's almost a total rewrite of kube-proxy
and
all the tests thereof. It also has back-compat problems (will not work
on
older kernels or older iptables binaries).On Mon, Jan 26, 2015 at 11:06 AM, Brendan Burns <
notifications@github.com>
wrote:Cool! I think we should definitely get this merged in. On a separate
note,
I was seeing the proxy eat ~30% of a core under heavy load, I have to
believe that iptables will give us better performance than that.Reply to this email directly or view it on GitHub
<.
Reply to this email directly or view it on GitHub
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment-71527216>.
Reply to this email directly or view it on GitHub
#3760 (comment)
.- addedsig/networkCategorizes an issue or PR as relevant to SIG Network.Categorizes an issue or PR as relevant to SIG Network.
on Jan 27, 2015 - addedpriority/backlogHigher priority than priority/awaiting-more-evidence.Higher priority than priority/awaiting-more-evidence.sig/scalabilityCategorizes an issue or PR as relevant to SIG Scalability.Categorizes an issue or PR as relevant to SIG Scalability.
on Jan 28, 2015 Is this a P2? Might it be worth making it a P3 for now?
I'm hoping to make it work, but we may yet demote it
On Wed, Feb 11, 2015 at 2:49 PM, Satnam Singh notifications@github.com
wrote:Is this a P2? Might it be worth making it a P3 for now?
Reply to this email directly or view it on GitHub
#3760 (comment)
.Doesn't "hope" equate to a P3 that we'll get to if we can?
From discussion with @thockin: This is a requirement in order to support service port ranges, which aren't required for 1.0, but we would like to support eventually.
- addedpriority/awaiting-more-evidenceLowest priority. Possibly useful, but not yet enough support to actually get it done.Lowest priority. Possibly useful, but not yet enough support to actually get it done.
on Feb 23, 2015 179 remaining items
Load more actionsI'm using kubernetes 1.1,
/opt/bin/kube-proxy ... --proxy-mode=iptables --masquerade-all=falseand routing cluser IP network through an host having a kube-proxy. In this setup, my services are seeing the external IP. I use a highly available network namespace who has a external IP and a route to the hosts:I0221 01:20:32.695440 1 main.go:224] <A6GSXEKN> Connection from 202.22.xxx.yyy:51954 closed.I've learned a lot reading this thread!
As an FYI this doc states that AWS ELB uses round-robin for TCP connections and least connections for http/https: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/how-elb-works.html#request-routing
I agree that focussing on getting requests only to nodes that run pods and to try to serve local pods is the best way to go about it. The nice side benefit of this is there'll be less node-to-node traffic within the cluster and I suppose a latency improvement by always service local requests from service to pod (which I guess is of even more benefit if you have nodes in multiple availability zones in the same cluster).
In terms of working with a load balancer that doesn't support weighting then you could solve this with your replication controller by trying to always keep the same number of pods on a node (if there's more than 1 per node) and then distributing evenly between them, even if this means having to move pods off of a node in certain situations and allowing only certain replica counts. e.g. for a 4 node cluster with a service connected to a load balancer the only number of acceptable pod replicas would be 1,2,3,4,6,8,9,12,16,20, etc
We're also looking to solve for traffic to route to local pods only. I'd be fine with the nodeport going away on a node at times when no pods are present locally for a service. This way a simple load balancer TCP health check would prevent requests from going to those nodes. I think if we can at least solve for the iptables\kube-proxy portion of this, then we'll find out what the load balancing implications are when the pods are not balanced across the cluster. I think there are ways to solve that on load balancers without having to set a weight for each node w/ an API call.
Load balancers already deal w/ this using other dynamic methods. Also, depending on what the service you're running is actually doing inside that container for each api call it may not be able to support 2x the traffic when there are 2 pods on a node vs one anyways. If Kubernetes Limits are set and if maximum levels of usage are being approached on a pod\node could play into this as well which adds yet another layer of complexity to trying to find the right weight setting on the external load balancer.
I'd say, stay away from that level of complexity and not try to set load balancer weight from kubernetes.
@yoshiwaan Can I suggest opening a new issue for the inter-node traffic suggestion, as this issue is now closed. Personally I think a good first step would be to ensure that if a pod is running on the local node, that we route to the local pod. I suspect that this will be sufficient, because you can then scale your RC so that there are pods on every node.
@justinsb +1, also we're running into a problem now where we need to see client IPs and it's basically impossible with the current setup.
This could be way too naive, yet I was wondering what's the difference between userspace mode and iptables? I cannot really tell from the user doc.
Userland mode means kube-proxy handles the connections itself by receiving the connection request from the client and opening a socket to the server, which (1) consume much more CPU and memory and (2) is limited to the number of ports a single can open (<65k). The iptables mode works at a lower level, in the kernel, and uses connection tracking instead, so it's much lighter and handles a lot more connections*.
(edit) (*) As long as you don't SNAT packets going through, which in turn requires a setup where you are sure packets will cross the connection tracking rules associated with them. For instance, using a routed access design allows you to avoid SNAT, which means the endpoint of the service will see the real client's IP.
Reacted by Simei He@MikaelCluseau
meaning kube-proxy is only responsible for setting up and maintaining iptables rules and we no longer get a random local port for each service in iptables mode, right?On 04/19/2016 10:51 PM, Emma He wrote:
meaning kube-proxy is only responsible for setting up and maintaining
iptables and we no longer get a random local port for each service in
iptables mode, right?Yes.
Sorry but I absolutely missed this earlier.
(edit) (*) As long as you don't SNAT packets going through, which in turn requires a setup where you are sure packets will cross the connection tracking rules associated with them. For instance, using a routed access design allows you to avoid SNAT, which means the endpoint of the service will see the real client's IP.
@MikaelCluseau I was thinking iptables adopts SNAT and DNAT, which is not the case according to you. Could you please clarify this for me?
On 04/20/2016 01:59 PM, Emma He wrote:
@MikaelCluseau https://github.com/MikaelCluseau I was thinking
iptables adopts SNAT and DNAT, which is not the case according to you.
Could you please clarify this for me?It's the tricky part.
(1) Using service/external IPs requires DNAT.
(2) If you are sure reply packets will go through the same conntrack
rule (ie, the same network stack or a replicated conntrack table), you
can skip the SNAT part (ie, MASQUERADE rules).The condition of (2) is usually ok in routed access network designs
(which is the simplest design I can think of).For instance, given
- a client 1.0.1.1,
- a service 1.0.2.1,
- a pod implementing the service 1.0.3.1.
Then,
- Your router/firewall/loadbalancer/host/whatever receives a packet
for the service so it sees a packet "1.0.1.1 -> 1.0.2.1"; - It DNATs it to the endpoint (pod) so the packet will be "1.0.1.1 ->
1.0.3.1" in the cluster network; - The pod replies with a packet "1.0.3.1 -> 1.0.1.1";
- The packet goes through a router/firewall/loadbalancer/host/whatever
having the conntrack rule, the conntrack system rewrite the packet
to "1.0.2.1 -> 1.0.1.1" before sending it back to the client.
If the condition of (2) cannot be met, you have to use SNAT/MASQUERADING
to be sure that the packet will go back through the
router/firewall/loadbalancer/host/whatever's conntrack.Reacted by Jason Stangroome@MikaelCluseau - drop me an email at my github name at google.com - I have
something for youOn Tue, Apr 19, 2016 at 8:20 PM, Mikaël Cluseau notifications@github.com
wrote:On 04/20/2016 01:59 PM, Emma He wrote:
@MikaelCluseau https://github.com/MikaelCluseau I was thinking
iptables adopts SNAT and DNAT, which is not the case according to you.
Could you please clarify this for me?It's the tricky part.
(1) Using service/external IPs requires DNAT.
(2) If you are sure reply packets will go through the same conntrack
rule (ie, the same network stack or a replicated conntrack table), you
can skip the SNAT part (ie, MASQUERADE rules).The condition of (2) is usually ok in routed access network designs
(which is the simplest design I can think of).For instance, given
- a client 1.0.1.1,
- a service 1.0.2.1,
- a pod implementing the service 1.0.3.1.
Then,
- Your router/firewall/loadbalancer/host/whatever receives a packet
for the service so it sees a packet "1.0.1.1 -> 1.0.2.1"; - It DNATs it to the endpoint (pod) so the packet will be "1.0.1.1 ->
1.0.3.1" in the cluster network; - The pod replies with a packet "1.0.3.1 -> 1.0.1.1";
- The packet goes through a router/firewall/loadbalancer/host/whatever
having the conntrack rule, the conntrack system rewrite the packet
to "1.0.2.1 -> 1.0.1.1" before sending it back to the client.
If the condition of (2) cannot be met, you have to use SNAT/MASQUERADING
to be sure that the packet will go back through the
router/firewall/loadbalancer/host/whatever's conntrack.—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#3760 (comment)@justinsb @yoshiwaan did anyone ever create an issue for this? My search fu is failing me, and I have a similar need.
Can I suggest opening a new issue for the inter-node traffic suggestion, as this issue is now closed. Personally I think a good first step would be to ensure that if a pod is running on the local node, that we route to the local pod. I suspect that this will be sufficient, because you can then scale your RC so that there are pods on every node.
I didn't raise it myself
Ahhhhh, I think I found it, this appears to be the feature/fix: kubernetes/enhancements#27
Seems to be beta as of 1.5.x.
I was playing with iptables yesterday, and I protoyped (well, copied from Google hits and mutated) a set of iptables rules that essentially do all the proxying for us without help from userspace. It's not urgent, but I want to file my notes before I lose them.
This has the additional nice side-effect (as far as I can tell) of preserving the source IP and being a large net simplification. Now kube-proxy would just need to sync Services -> iptables. This has the downside of not being compatible with older iptables and kernels. We had a problem with this before - at some point we need to decide just how far back in time we care about.
This can probably be optimized further, but in basic testing, I see sticky sessions working and if I comment that part out I see ~equal probability of hitting each backend. I was not able to get deterministic round-robin working properly (with --nth instead of --probability) but we could come back to that if we want.
This sets up a service portal with the backends listed below