您想要实现的目标绝对可行。
预赛
Erlang 的分发地址分为两部分:节点名和主机名。它们由@ 符号分隔。
主机名可以是数字 IPv4 地址。它们也可以是域名。有两种不同的模式,主机名很短(单个单词,例如vm1)和主机名很长(几个单词,例如vm1.domain.com)。 IP 地址是长名称。以一种模式(短或长)启动的节点只能与以相同模式启动的节点通信。节点也受 cookie 保护:节点将只接受带有匹配 cookie 的传入连接。最简单的方法是使用相同的 cookie 启动给定集群的所有节点。
当一个 Erlang 节点试图连接到另一个 Erlang 节点时,它需要找到远端节点的 IP 地址。如果它与自身相同,它将简单地尝试在本地主机上连接。如果不同,它会尝试将此主机名解析为 IP 地址。
然后它将连接到此主机上的epmd 守护进程,以获知 Erlang 正在运行的端口。 epmd 以及 Erlang 节点侦听所有接口(默认情况下)。
解决方案和示例
基于此机制,您可以使用短名称或长名称,但要利用解析机制。在 Unix 上最简单的方法是在您的机器(尤其是两个虚拟机上)的每台 /etc/hosts 上配置不同的 IP,这样它们将通过它们的私有地址相互连接,同时通过它们的公共地址访问。
假设虚拟机 A (VM A) 的私有 IP 地址为 10.0.0.2,公共 IP 地址为 123.4.5.2,VM B 的私有 IP 地址为 10.0.0.3,公共 IP 地址为 123.4.5.3。假设您决定使用简称。
您可以在 VM A 上添加 /etc/hosts 中的此条目:
10.0.0.3 vmb
您可以将匹配的条目放在 VM B 的 /etc/hosts:
10.0.0.2 vma
在所有外部客户端上,您可以输入:
123.4.5.2 vma
123.4.5.3 vmb
您将按如下方式启动您的节点:
# Node foo on VM A:
erl -sname foo@vma -cookie RANDOMCOOKIE
# Node foo on VM B:
erl -sname foo@vmb -cookie RANDOMCOOKIE
# Client nodes:
erl -sname client -cookie RANDOMCOOKIE
如果您有域名(例如yourdomain.com),您可以避免在客户端节点上编辑/etc/hosts,并且您可以让vma.yourdomain.com 解析为123.4.5.2。您也可以使用特定的Erlang Inet configuration file。
安全
Erlang 分发机制并不意味着面向公众。此外,所有通信都将不加密。我强烈建议在每台主机上配置防火墙,只允许来自其他集群服务器的连接并使用 SSL 分发。
对于防火墙:Erlang 分发使用端口 4369 来表示 epmd 以及每个节点的随机端口。您可以通过使用 Erlang 内核应用程序环境设置 inet_dist_listen_min 和 inet_dist_listen_max 来限制这些随机端口的范围。您需要允许这些端口上的传入 TCP 连接,但只能来自集群的其他主机。
SSL 分发的设置相当复杂,但well documented。您的情况的主要缺点是所有连接都应通过 SSL,包括其专用网络上的两个虚拟机之间的连接,以及打开远程 shell 的本地连接。