Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for UDPRoute API #641

Closed
arkodg opened this issue Oct 21, 2022 · 22 comments
Closed

Add support for UDPRoute API #641

arkodg opened this issue Oct 21, 2022 · 22 comments
Assignees
Labels
documentation Improvements or additions to documentation kind/enhancement New feature or request priority/medium Label used to express the "medium" priority level release-note Indicates a required release note
Milestone

Comments

@arkodg
Copy link
Contributor

arkodg commented Oct 21, 2022

Description:
Add Support for the UDP Route API defined here

Related #47

@arkodg arkodg added the kind/enhancement New feature or request label Oct 21, 2022
@arkodg
Copy link
Contributor Author

arkodg commented Oct 21, 2022

we should wait on #413 which will refactor the provider before starting this issue

@arkodg arkodg added this to the 0.3.0-rc.1 milestone Oct 21, 2022
@zhaohuabing
Copy link
Member

zhaohuabing commented Oct 25, 2022

@arkodg May I take this one? It would be a relatively easy start for me to dig into the core mechanism of EG since I can refer to the implementation of the current HTTRoute. If this one goes well, I would like to take #642 as well.

@arkodg
Copy link
Contributor Author

arkodg commented Oct 25, 2022

go for it @zhaohuabing, suggest raising incremental PRs in the below order to increase PR review speeds and reduce merge conflicts :)

zhaohuabing added a commit to zhaohuabing/gateway that referenced this issue Oct 26, 2022
zhaohuabing added a commit to zhaohuabing/gateway that referenced this issue Oct 26, 2022
@youngnick
Copy link
Contributor

I'd like to see some work done on how the UDP flows will actually work. It's pretty straightforward to set up a UDP listener for Envoy, but it's very difficult to preserve the client address at the same time.

Basically, you have two options:

  • Use Envoy in non-transparent proxy mode, which means that the client address will be seen at the backend pods as Envoy's address. As I said, most UDP protocols don't like this.
  • Use Envoy in transparent proxy mode, which means that packets will be forwarded to the backend pods without changing the client IP, but the server IP will also not be updated to Envoy's, which means that the return path from the backend back to the client will both not go via Envoy, and will be from a different IP address than what the packet was sent to (since it will be the backend's address). Most firewalls will drop UDP traffic like this, that both doesn't come from and address traffic is already heading to, and (most likely) comes from an RFC1918 address.

In particular, on Contour, we've been asked to have Contour handle SIP traffic, and SIP in particular is a very bad fit for this sort of proxying, as the RTP used for the actual data streams (as opposed to the control traffic) is very dynamic and difficult to proxy correctly.

I'm not opposed to doing UDPRoute in Envoy Gateway, but I would like to see significantly more design around how to make it available in a way that meets user expectations. Just adding support for the existing UDP modes in Envoy does not match up to what users will expect when you add UDP forwarding.

@zhaohuabing
Copy link
Member

zhaohuabing commented Oct 27, 2022

I think transparent proxy mode can be benifical for both TCP and UDP since in some use cases, the server behind the EG would like to know the original addreess of the client. To get this done, we'll need to set the route inside a cluster to get the return traffic route back to the EG, and then EG can send the traffic right back to the client.

@arkodg
Copy link
Contributor Author

arkodg commented Oct 27, 2022

@youngnick the https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/udp_filters/udp_proxy docs states that envoy operates as a non transparent proxy.
The xds implementation does not seem too complex, if you prefer, either @zhaohuabing or I could
PoC with Envoy proxying UDP traffic to a pod running a TFTP server or UDP Ping server and share those details on this issue.
If some UDP protocols dont like non transparent mode , we will have have add those limitations to the EG docs for now.

@zhaohuabing
Copy link
Member

zhaohuabing commented Oct 27, 2022

non-transparent proxy should work, I'll test that after the translators implemention is done. transparent proxy mode is also helpful, maybe we could discuss how to support it if there're more requests asking for it from the clients. It looks like we need to introduce new components if we want to addd transparent mode, we will need a CNI to set up the route. Besides, we should also consider the transparent mode for TCP listeners together.

@arkodg
Copy link
Contributor Author

arkodg commented Oct 27, 2022

Reread the envoy docs which states that envoy also support transparent mode but needs added privileges ( not given to the envoy deployment today )
@youngnick do you have any info handy on which protocols support non transparent mode and which dont ?

@youngnick
Copy link
Contributor

It's tricky, but in general UDP protocols expect the client address to be the actual one. DNS, and syslog are the ones I can think of from the top of my head. I'm not sure about other ones - I know that lots of gaming applications use UDP as well. It's going to be on a per-protocol basis though - and lots of people roll their own protocol.

If we really want to do it, it will be extremely important to call out the no-client-address limitations of proxied mode, definitely.

For transparent proxying, changing the routing seems like it needs pretty deep integration with the CNI or kube-proxy - I don't feel like us building that into Envoy Gateway is a very good idea without doing a pretty detailed design first.

@danehans danehans changed the title Add support for UDP Route API Add support for UDPRoute API Oct 31, 2022
@danehans
Copy link
Contributor

xref #646 for adding UDPRoute to IR.

@danehans
Copy link
Contributor

Use Envoy in non-transparent proxy mode, which means that the client address will be seen at the backend pods as Envoy's address. As I said, most UDP protocols don't like this.

Although most UDP protocols don't like this, non-transparent proxy mode could be considered "initial" UDPRoute support. We can document these details while we work on a long-term UDPRoute solution that covers the other UDP protocols.

@mattklein123 PTAL at this issue and #643. Let us know if you have any input on adding L4 support.

@danehans
Copy link
Contributor

For transparent proxying, changing the routing seems like it needs pretty deep integration with the CNI or kube-proxy

Maybe a solution similar to kube-proxy's internalTrafficPolicy: Local can help workaround this issue?

@arkodg
Copy link
Contributor Author

arkodg commented Oct 31, 2022

cc @moderation

@youngnick
Copy link
Contributor

For transparent proxying, changing the routing seems like it needs pretty deep integration with the CNI or kube-proxy

Maybe a solution similar to kube-proxy's internalTrafficPolicy: Local can help workaround this issue?

Sadly, it's not about the inbound traffic, transparent mode will get the packets to the backend properly. It's about the return path from the backend back to the client - because Envoy doesn't do any address translation, the packets will be sent straight from the backend to the client, without going back through Envoy. To change that behavior, you'd need to mess with the routing tables for the pod, basically making Envoy the default gateway for all IP traffic in the pod (this is how traditional load balancers like F5 work, they're almost always the default gateway for the segment where the backends reside).

@moderation
Copy link

moderation commented Nov 1, 2022

@youngnick a couple of questions:

  1. NGINX in theory supports UDP ingress today irrespective of Envoy Gateway - do they have a feature or implementation that differs from Envoy that enables them to provide this UDP ingress solution?
  2. Ambassador Labs Emissary Ingress which is based on Envoy supports HTTP/3 - https://blog.getambassador.io/how-to-implement-http3-support-with-ambassador-edge-stack-c57bae385a88. HTTP/3 rides on QUIC which is UDP based. What are they doing that is out of reach for Envoy Gateway supporting UDP?
  3. Should the documentation of the Kubernetes Gateway API specification modify their documentation to indicate that of the reverse proxies (NGINX, HAProxy, Traefik, Caddy etc.), Envoy is unable to support UDPRoute?

@youngnick
Copy link
Contributor

@youngnick a couple of questions:

  1. NGINX in theory supports UDP ingress today irrespective of Envoy Gateway - do they have a feature or implementation that differs from Envoy that enables them to provide this UDP ingress solution

No, from what I can see, their UDP implementation will have the same client address limitation. I seem to recall looking at a version of their documentation that called this out, but I can't see it in their current one.

In addition, the fact that their Service Mesh product uses eBPF to inject PROXY protocol headers in order to make this work tends to bear this out, for me.

  1. Ambassador Labs Emissary Ingress which is based on Envoy supports HTTP/3. HTTP/3 rides on QUIC which is UDP based. What are they doing that is out of reach for Envoy Gateway supporting UDP?

QUIC is different, because QUIC uses UDP as a transport, but has higher-layer constructs to allow the backend to rebuild the actual client address (like X-Forwarded-For in HTTP/1 and HTTP/2). So it doesn't matter in those cases if the actual client IP is lost along the way.

Most other UDP protocols don't have this, sadly.

  1. Should the documentation of the Kubernetes Gateway API specification modify their documentation to indicate that of the reverse proxies, Envoy is unable to support UDPRoute?

It's not really a matter for Gateway API - Gateway API defines what a UDPRoute is - the fact that Envoy running as an in-cluster proxy can't do it isn't really relevant there.

I would love to have a way to make this work the way we all want it to, but trying to proxy UDP with cluster networking really is the worst-case scenario, sadly.

arkodg added a commit to arkodg/gateway that referenced this issue Nov 1, 2022
@zhaohuabing
Copy link
Member

zhaohuabing commented Nov 2, 2022

It seems like we don't have a workable solution for trasparent proxying for both UDP and TCP in the short term. So I'll go with the non-trasparent mode and add some documentation on that to make it clear to the users. Does this sound good?

BTY, if people really relies on the real source address in an application protocol based on UDP and want to deploy their applications in cloud infrastructure, they may need to switch to an application-level solution to get the source address because there're good chances that there're other non-transparent hops between the client and the server.

@arkodg arkodg added the priority/medium Label used to express the "medium" priority level label Nov 3, 2022
arkodg pushed a commit that referenced this issue Nov 7, 2022
* add ir for udp route #641

Signed-off-by: zhaohuabing <[email protected]>
@github-actions
Copy link

github-actions bot commented Dec 4, 2022

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Dec 4, 2022
@github-actions
Copy link

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted" or "no stalebot". Thank you for your contributions.

@arkodg
Copy link
Contributor Author

arkodg commented Dec 23, 2022

lets keep this issue open until end to end functionality is shown in the docs

@arkodg arkodg reopened this Dec 23, 2022
@arkodg arkodg added the documentation Improvements or additions to documentation label Jan 5, 2023
@danehans danehans added the release-note Indicates a required release note label Jan 10, 2023
@danehans danehans modified the milestones: 0.3.0-rc.1, 0.3.0 Jan 10, 2023
@danehans
Copy link
Contributor

@zhaohuabing do you mind adding a user doc to close out this issue?

@zhaohuabing
Copy link
Member

@danehans Sorry for the delay. My hands were tide for the last few weeks. I'll add the doc this week and close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation kind/enhancement New feature or request priority/medium Label used to express the "medium" priority level release-note Indicates a required release note
Projects
None yet
Development

No branches or pull requests

5 participants