-
Notifications
You must be signed in to change notification settings - Fork 9.8k
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
Replace Cmux #15510
Replace Cmux #15510
Conversation
/assign @serathius @fuweid |
This PR seems to not pass newly added cmux tests #15479
Results
Also server fails to terminate correctly so I needed to change
to
|
Still it would be great if this works and we don't need to introduce a breaking change to stop running grpc server under http. |
half way done by the comments, will try to come back to this tomorrow and run the failing tests |
Great to see this PR, which I wanted to do but do not get time to do. If this PR eventually works and is accepted, then we don't need to add separate flag (e.g EDIT: I was thinking to update github.com/soheilhy/cmux to resolve the original issue just as I mentioned in #15451 (comment)? I feel like it makes more sense to delegate such generic function to a separate repository, e.g either cmux or other repository or put it under We may also create a new repo under etcd-io, such as |
that is the goal, I understand well the logic in the multiplexer, but I have trouble to understand the logic in etcd, I need some help to understand which request should be sent to which backends
Putting the mux in a public repo means you may offer some guarantees to users and trying to generalize it can go against the supportability of etcd , there are too many protocols out there 😄 |
f81285f
to
df48868
Compare
tests are passing now |
graceful shutdown was broken, next push with the fix |
78d19ad
to
30a0749
Compare
The HTTP endpoints in the right bottom side isn't a full list, please read the section "Background" in #15402 (comment) to get a full list. |
c455eec
to
ca61d2e
Compare
server/etcdmain/grpc_proxy.go
Outdated
@@ -233,7 +233,7 @@ func startGRPCProxy(cmd *cobra.Command, args []string) { | |||
} | |||
httpClient := mustNewHTTPClient(lg) | |||
|
|||
srvhttp, httpl := mustHTTPListener(lg, m, tlsInfo, client, proxyClient) | |||
srvhttp, httpl := mustHTTPListener(lg, m, client, proxyClient) | |||
|
|||
if err := http2.ConfigureServer(srvhttp, &http2.Server{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have doubts if I have to use the h2c handler here too, like in the server
ok, I think I got the logic right now, and it can be done anything from the same multiplexer |
c1402ef
to
765a973
Compare
We should not proceed #15510 (comment) , this was fun to code but not meant to be used in production |
The cmux usage in etcd should be removed too based on this conversation, since is not adding much once the grpc and http servers are split, is it? |
Question remains, how we make the intended production configuration a default without a breaking change? Was hoping that this PR can be validated and made default in v3.6. Without this we will need to revert to previous design :( |
can we serve redirects https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections from the grpc server to forward them to the new url? |
let me reopen, I was with the idea that we want only passive, but if we write the ack setting to the connection then we can be 100% is a grpc connection. |
ok, I got it now, the trickies part is to support http2 with TLS, because grpc uses http2 but shows an interesting behavior, the clients block until they receive a settings frame. However, if we send the setting frame and is not grpc, the h2c handler logic considers it a protocol error and tear down the connection |
Introduce a new socket connection multiplexer that multiplexes the same ip:port to an http and a grpc backends. The multiplexer is able to terminate TLS and forward the request to the corresponding grpc or http backends Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
it was just adding one element in the path when it can be used directly, as it is configured as a passthrough. Signed-off-by: Antonio Ojea <aojea@google.com>
sockproxy allows to listen in the same listener both in http and grpc with or without TLS enabled, allowing to remove the duplicate logic for secure and insecure, and to remove the http2 handler for splitting the grpc and http traffic. Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
The only reliable method to detect a GRPC connection seems to be parsing the content-type header. We need to be able to establish the HTTP2 connection so the client sends us the headers. Signed-off-by: Antonio Ojea <aojea@google.com>
grpc clients block waiting for the settings frame. http2 fails if we write the settings frame we have to detect that the client didn't send more than 33 bytes: 24 preface + 9 settings (this seems to be optional) to write the settings frame. Signed-off-by: Antonio Ojea <aojea@google.com>
Signed-off-by: Antonio Ojea <aojea@google.com>
This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions. |
The cmux project last commit is from Mar 2021 https://github.com/soheilhy/cmux
It also targets a more generic way of multiplexing connections offering different matches and doesn't offer the possibility of use the same cmux to differentiate between TLS and non-TLS.
etcd doesn't need the cmux flexibility, since the backends are always controlled by the project, and will benefit if it can support to discriminate between TLS and non-TLS.
This PR introduces a replacement from cmux targeted specifically for the etcd use case.
It uses the same method of detecting the connection, looking ahead on the connection to try to determine if is an HTTP or GRPC request.
The heuristic here are more simple, since HTTP connections are easy to identify (it always start with HTTP1/1 , see exception explanation below), and apply the following logic "if is not HTTP it has to be GRPC". In the corner case that the connection is forwarded and is not GRPC, the server will reject the connection anyway.
NOTE:
I'm not familiar with the etcd code so I did a grep for cmux, but I'm not completely sure I made a 1to1 replacement, the first commit introduces the new cmux for etcd, so I appreciate some guidance and feedback