-
Notifications
You must be signed in to change notification settings - Fork 294
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
Fix: docker exec hangs indefinitely when reading from stdin #7896
base: main
Are you sure you want to change the base?
Conversation
8330069
to
f4d9c09
Compare
72b8d1c
to
139becb
Compare
@Nino-K I had missed the changes to a file in the commit. I just updated the PR with it. It should build now. Regarding the linter, I fixed all the issues except one. Honestly, I cannot figure out exactly what response body is complaining about in that line. |
I just have seen that this one may be indirectly fixing #3239 |
Hi @matejkramny, Your diagram is correct, at least as far as I understand it. Initially, a couple of months ago, I tried to run kind on Rancher Desktop and it failed. Looking into it, I discovered that the problem was the kind tool passing configuration on Windows via stdin, and the docker commands would get stuck.
When you run this, "ok" is echoed back to the terminal, but the command gets stuck instead of exiting and returning the correct exit code. I started troubleshooting that part. The first problem was that the Windows named pipe was not signaling the EOF of the data received via stdin. As a result, the Docker CLI was stuck, always listening for more data. The data was echoed back, but that was it. Initially, I thought I had found the solution with this line in server_windows.go:
Everything seemed to work—the "ok" was echoed back, and the program was no longer stuck. However, kind still did not work. So I continued troubleshooting and found that the http.ReverseProxy used in
The problem then is that the command's output is truncated. The command ends but it does not echo back everything. The reason is that for the short period of time that the connection to the hvsock remains open traffic flows in all directions, and as soon as it is closed, the stdout/stderr data cannot flow to the client anymore. That is the reason why at first just with that like in server_windows.go the command Then the problem was the proxy. I initially built a very simple L4-level proxy that just piped both connections properly. But the current solution needed to leverage the capabilities of hooks in http.ReverseProxy to modify requests and responses (mungers). A transparent proxy wouldn't suffice, so an L7 proxy was needed that could make proper use of CloseWrite to half-close connections. In this PR, I wrote a minimalistic HTTP reverse proxy that can handle both half-closes and the "mungers". With that, the solution to my problem was finished, and I submitted this PR a couple of days ago. Yesterday, I saw #3239 related to WSL. Testing it with this PR applied, it looks like the issue is solved. This is most likely because the |
This commit fixes the improper handling of half-closed connection behavior when attaching stdin to a container. The proper approach requires: - The docker client receives a half-close of the connection from client to daemon (stdin) - The connection from daemon to client (stdout, stderr) remains open until no more data is to be received The first part of the issue is resolved by enabling MessageMode on Windows named pipes. This ensures that when stdin ends, an EOF is received on the reader, allowing proper half-closing of the connection. The previous implementation used stdlib's httputil.DockerProxy to proxy from Windows named pipe to WSL hvsock. This proxy does not use CloseWrite on hijacked connections, preventing proper handling of this use case. By using Close() instead of CloseWrite(), both connection directions are closed simultaneously, causing the client to miss pending stdout/stderr content after stdin EOF. This commit introduces a simpler custom `util.ReverseProxy` to replace httputil.DockerProxy, implementing proper handling of half-closed connections with explicit support for: - HTTP protocol upgrades - Half-close TCP connection management - Precise stream handling for Docker API interactions Closes rancher-sandbox#2094 Signed-off-by: Carlos Barcenilla <[email protected]>
139becb
to
7e98ebf
Compare
@bcxpro that's great, thank you for explaining!
I think our solutions diverge here, at L4 I read ahead and match the request to For interest, go maintainers don't seem to have plans to fix the ReverseProxy |
Not sure this is true; that issue was just closed as a duplicate of golang/go#35892, which is still open, but doesn't seem to have any recent action on it either. |
It wasn't explicitly mentioned but it's an open bug from 2019
…---- On Wed, 11 Dec 2024 18:39:32 +0000 ***@***.*** wrote ----
For interest, go maintainers don't seem to have plans to fix the ReverseProxy
Not sure this is true; that issue was just closed as a duplicate of golang/go#35892, which is still open, but doesn't seem to have any recent action on it either.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.
|
This PR fixes the improper handling of half-closed connection behavior when attaching stdin to a container. The proper approach requires:
The first part of the issue is resolved by enabling MessageMode on Windows named pipes. This ensures that when stdin ends, an EOF is received on the reader, allowing proper half-closing of the connection.
The previous implementation used stdlib's httputil.DockerProxy to proxy from Windows named pipe to WSL hvsock. This proxy does not use CloseWrite on hijacked connections, preventing proper handling of this use case. By using Close() instead of CloseWrite(), both connection directions are closed simultaneously, causing the client to miss pending stdout/stderr content after stdin EOF.
This commit introduces a simpler custom
util.ReverseProxy
to replace httputil.DockerProxy, implementing proper handling of half-closed connections with explicit support for:Closes #2094