SSH 隧道到 Docker 容器

SSH 隧道到 Docker 容器

目标:本地连接到远程 repl(例如通过lein repl :connect)。

在本地,这很容易:

  1. 运行服务器(它在端口 8081 上启动一个嵌入式 nrepl 服务器)
  2. 运行lein repl :connect 8081,瞧!repl 已连接

当 repl 在未打开的端口上运行时,我也通过使用 SSH 隧道连接到远程服务器上的 repl:

  1. 在 some.host 上,运行服务器(它在端口 8081 上启动嵌入式 nrepl 服务器)
  2. SSH 隧道ssh -N -T -L 8081:localhost:8081 [email protected]
  3. 本地,lein repl :connect 8081瞧!repl 已连接

但是,我当前的设置是“服务器”在 Docker 容器中运行,它映射端口 8081。因此,为了连接到 nrepl 服务器,它必须转到本地 -> some.host -> docker-container -> nrepl。

我可以看到我的docker容器已经映射了8081端口:

$ sudo docker port container-id 8081
0.0.0.0:8081

并且,在托管 Docker 容器的服务器上,我可以看到端口 8081 正在监听:

$ netstat -anl | sed -n '2p;/8081/p'
Proto    Recv-Q    Send-Q    Local Address   Foreign Address     State  
tcp      0         0         :::8081         :::*                LISTEN

而且它似乎就像我可以为端口 8081 打开一个 SSH 隧道;例如运行时没有错误/警告:

ssh -N -T -L *:8081:localhost:8081 [email protected]

这让我认为我有正确的 SSH 隧道,但每当我尝试连接到正在运行的 repl 服务器时,它都会立即失败,如下所示:

$ lein repl :connect 8081
Connecting to nREPL at 127.0.0.1:8081
SocketException The transport's socket appears to have lost its connection to the nREPL server

值得注意的是,错误是连接丢失,因为运行没有SSH 隧道打开后,相同的命令会失败Connection refused。这让我认为 SSH 隧道没有问题,问题出在服务器转发到 docker 容器上,这就是为什么这个标题是一个关于从 打开隧道的一般性问题client -> server -> docker container

我认为这可能与 SSH GatewayPorts 有关,因此我尝试启用 GatewayPorts,但没有任何改变。

问题:

  1. 上面的 SSH 隧道方法是否存在明显的错误?
  2. 我如何确定在哪里连接正在断开?
  3. 还有其他建议吗?

谢谢!

答案1

而且……事实证明隧道没有任何问题。

问题是,在 docker 容器内启动嵌入式 nrepl 服务器需要显式绑定到“0.0.0.0”。如果没有这个,nrepl 服务器默认绑定到“localhost”,这使得它无法从 docker 容器外部访问,尽管有端口映射,因为 docker 端口映射使用 0.0.0.0:。一旦 nrepl 服务器正确绑定,端口映射就会处理其余的事情。

答案2

作为一个有用的链接,请看一下 -Docker SSH. 非常简化的管理 Docker SSH 的方法。

相关内容