目标:本地连接到远程 repl(例如通过lein repl :connect
)。
在本地,这很容易:
- 运行服务器(它在端口 8081 上启动一个嵌入式 nrepl 服务器)
- 运行
lein repl :connect 8081
,瞧!repl 已连接
当 repl 在未打开的端口上运行时,我也通过使用 SSH 隧道连接到远程服务器上的 repl:
- 在 some.host 上,运行服务器(它在端口 8081 上启动嵌入式 nrepl 服务器)
- SSH 隧道
ssh -N -T -L 8081:localhost:8081 [email protected]
- 本地,
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,但没有任何改变。
问题:
- 上面的 SSH 隧道方法是否存在明显的错误?
- 我如何确定在哪里连接正在断开?
- 还有其他建议吗?
谢谢!
答案1
而且……事实证明隧道没有任何问题。
问题是,在 docker 容器内启动嵌入式 nrepl 服务器需要显式绑定到“0.0.0.0”。如果没有这个,nrepl 服务器默认绑定到“localhost”,这使得它无法从 docker 容器外部访问,尽管有端口映射,因为 docker 端口映射使用 0.0.0.0:。一旦 nrepl 服务器正确绑定,端口映射就会处理其余的事情。
答案2
作为一个有用的链接,请看一下 -Docker SSH. 非常简化的管理 Docker SSH 的方法。