使用 ssh 端口转发运行 Erlang Observer

Posted

技术标签:

【中文标题】使用 ssh 端口转发运行 Erlang Observer【英文标题】:Run Erlang Observer with ssh port forwarding 【发布时间】:2014-12-02 15:31:17 【问题描述】:

我有一个远程 Erlang 节点和本地开发人员的 PC。我想启动本地节点debug@127.0.0.1,启动观察者,调用c:nl/1和其他调试动作。我是这样写的:

   #!/bin/sh
   export ERL_EPMD_PORT=43690
   PORT=`ssh -l user target -p 5022 "/usr/bin/epmd -names" | awk '$2 == "target-node" print $5'`
   pkill -f ssh.*-fxN.*target
   ssh -fxNL 43690:`hostname`:4369 target -p 5022 -l user
   ssh -fxNL $PORT:`hostname`:$PORT target -p 5022 -l user
   ssh -fxNR 9001:`hostname`:9001 target -p 5022 -l user
   erl -name dev@127.0.0.1 -setcookie ABCDEFFJKGSK \
   -kernel inet_dist_listen_min 9001 inet_dist_listen_max 9001 \
   -eval "net_adm:ping('nodename@target')."
   pkill -f ssh.*-fxN.*target

但是当我运行这个脚本时,我会收到如下消息:

bind: 地址已在使用 错误的本地转发规范 ':debian:' Erlang/OTP 17 [erts-6.1] [来源] [64 位] [smp:4:4] [异步线程:10] [内核轮询:假]

Eshell V6.1(使用 ^G 中止)(dev@127.0.0.1)1>

如何在本地机器上运行观察者并将它们连接到远程节点?

【问题讨论】:

【参考方案1】:

至少有三件事:

没有正确关闭 TCP 连接 节点名称 隧道错误

如果您关闭与kill 保持 TCP 连接的进程,它可以在几分钟内进入TIME_WAIT 状态:read more

ssh -L port:host:hostport 中,您有 2 个组件:

第一个是port,这表示,在我的本地机器上使用这个端口 host:hostport 意思是:“从远程机器连接到这个主机和端口”,你可以想象,你已经在远程机器上,你想连接到第三台

您在内部使用hostname,它在您的本地计算机上进行评估并返回debian,这没有意义,因为debian 可能在您的远程计算机上没有任何意义。尝试使用:

ssh -fxNR 9001:localhost:9001 target -p 5022 -l user

这应该可以按预期工作,没有关于规范的错误。

Erlang 分布式使用节点名称来定位机器。在您正在调用的本地节点上:

net_adm:ping('nodename@target').

它试图直接联系目标上的 4369 端口而不进行端口转发。

Erlang 分布式设计用于本地可信网络。使用端口转发来设置它真的很困难。 您可以在远程机器上启动调试节点并连接到您的系统——这应该很容易。如果远程系统有X服务器,你甚至可以转发观察者窗口(@98​​7654332@)。

【讨论】:

【参考方案2】:

首先找到远程端口:

   $ ssh remote-host "epmd -names"
    epmd: up and running on port 4369 with data:
    name some_node at port 58769

请注意 epmd 本身的运行端口以及您有兴趣调试的节点的端口。使用转发的这些端口重新连接到远程主机:

$ ssh -L 4369:localhost:4369 -L 58769:localhost:58769 remote-host

在您的机器上,启动一个隐藏的 Erlang 节点,运行观察者应用程序:

$ erl -name debug@127.0.0.1 -setcookie if-server-has-one -hidden -run observer

注意:如果服务器使用 -sname,您也需要使用 -sname,因为 Erlang™。出于同样的原因,您还需要更改系统的主机名以匹配目标主机。

在观察者中,转到节点 - 连接节点并输入some_node@127.0.0.1

你也可以得到一个远程shell:

$ erl -name debug@127.0.0.1 -setcookie if-server-has-one -remsh some_node@127.0.0.1

【讨论】:

【参考方案3】:

我尝试自动化相同的 ssh 端口转发方法并来到这个项目:https://github.com/virtan/ccl

添加 sys.config 与 ccl, [ slaves, [ "ef1", "ef1.somehost.net", use ] ] 并启动 ccl 应用程序以建立到 ef1.somehost.net 的隧道,并启动并连接远程节点。

【讨论】:

【参考方案4】:

@tkowal 的回答最好地解释了这里的问题,但我想分享我是如何处理这个问题的。我经常喜欢将epmd -names 列出的端口转发到本地主机,这样我就可以轻松地使用本地 GUI 工具检查远程节点上的状态。我写了一个shell script automatically forward the ports for me,所以我不必记住一堆命令。它易于使用:

$ ./epmd_port_forwarder --server=remote-erlang-server.net
epmd: Cannot connect to local epmd
Killed local epmd
epmd: up and running on port 4369 with data:
name remote_erlang_node at port 46259
Forwarding ports
+ ssh -N -L 4369:localhost:4369 -L 46259:localhost:46259 remote-erlang-server.net

启动脚本后,您可以使用epmd -names 列出正在转发的远程节点。

【讨论】:

以上是关于使用 ssh 端口转发运行 Erlang Observer的主要内容,如果未能解决你的问题,请参考以下文章

Erlang节点通信——端口转发

使用 sshtunnel 包进行两步 SSH 本地端口转发

SSH.NET > 用于端口转发的 SSH 客户端

~/.ssh/config 文件中的 SSH 端口转发? [关闭]

Python 中的 SSH 动态端口转发('ssh -D')

如何使用 Ruby 进行动态端口转发