5

I have two Linux machines connected using a LAN cable. Each machine is able to ping the other. Machine A has IP: 192.168.137.1 on its Ethernet eth0. Machine B has IP: 192.168.137.2 on its Ethernet eth0.

On Machine A's terminal:

ping 192.168.137.2

returns replies, and Wireshark on B is able to capture the incoming pings.

On Machine B's terminal:

ping 192.168.137.1

returns replies, and Wireshark on A is able to capture the incoming pings.

So, we have full connectivity between A and B.

Now, how can I have two Erlang shells, one running on A and the other running on B, be able to ping/ talk to each other? It would be great if someone could help me achieve this by giving detailed steps. I have been searching forums and browsing documentation but so far, I haven't got it to work. All the work I could find was for communicating between two nodes on the same host machine.

aeon
  • 83
  • 6

3 Answers3

5

A running Erlang VM instance is called a node. If you start an Erlang shell you are going to end up with a node that has distribution disabled. You can check this by calling the is_alive/0 function.

$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.3  (abort with ^G)
1> is_alive().
false

All nodes have a name – even those that don't have distribution enabled:

2> node().
nonode@nohost

...and because distribution is disabled, there are no nodes in the cluster (for now):

3> nodes().
[]
4> q().
ok

With distribution enabled, there are a couple of ways to communicate: we can call the various functions within the shell, let the Erlang VM handle it automatically at startup, etc.

$ erl -sname earth
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.3  (abort with ^G)
(earth@uplink)1> is_alive().
true
(earth@uplink)2> node().
earth@uplink
(earth@uplink)3> nodes().
[]

NOTE: uplink is the name of my machine. The full node name is always name@host. You can also see that the prompt is a little different than from the one at very first time/example.

...but still, nobody is connected! Start another node in your other machine and name it pluto this time.

$ erl -sname pluto
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.3  (abort with ^G)
(pluto@uplink)1> is_alive().
true
(pluto@uplink)2> node().    
pluto@uplink
(pluto@uplink)3> nodes().
[]
(pluto@uplink)4> net_adm:ping(earth@uplink).
pong
(pluto@uplink)5> nodes().
[earth@uplink]

You have your Erlang cluster up and running now. There are some other ways to do this. I would recommend you to read Learn You Some Erlang for Great Good!...very good one.

IMPORTANT: If you don't have the same "cookie" in both machines you might get a hard time trying to communicate the nodes. Instead you can start the node(s) and set the cookie at the same time: $ erl -sname your_node_name -setcookie 'acookietorulethemall'.

x80486
  • 6,627
  • 5
  • 52
  • 111
  • Hi, thanks for your instructions. But this method works for two Erlang VM nodes on the same physical host machine. How do I get it to work for communication between 'earth@uplink' on Machine A and 'pluto@machineB' ? Uplink and Machine B are connected using a LAN cable, and are able to ping each other from their respective system terminals. – aeon Apr 14 '18 at 22:59
  • @aeon, can you tell what's the error you are getting while doing that? – x80486 Apr 15 '18 at 15:58
  • 1
    Erlang and @x80480 both assume certain things about the configuration of your network, seemingly unaware that on most modern systems these assumptions don't hold. What I'm talking about is the lack of correspondence on most systems between a UNIX hostname and a name that resolves to an IP address in any way. Most people don't run their own DNS server (other than the broken one that Systemd provides), and the art of using /etc/hosts to get name resolution without a name server is mostly forgotten. To make things worse, the only error you'll get from Erlang is `pang.` – Throw Away Account Oct 26 '19 at 10:08
  • Even with same cookies it does not work: ``** Connection attempt from disallowed node 'wsl@m004-temp-02' **`` - they have connection and the pinged node issues this warning. – BitTickler Feb 08 '20 at 01:52
2

I was facing the same situation as you, because I needed to deploy Erlang on different host in the network, so let me share here how I proceed to fix it.

I have 02 VM:

  • First VirtualMachine:

    ip: 10.57.63.165

  • Second VirtualMachine:

    ip: 10.57.63.163

As you can see below, they can ping each other:

enter image description here

As we already know, 02 Erlang Node need to share the same Erlang Cookie.

For this solution, I will skip the .erlang.cookie file; I will set erlang cookie manually, just for temporary purpose (-setcookie):

enter image description here

As you can see:

We got a Pang.

  • client@sgsn (10.57.63.165) is attempting to connect to serveur@ggsn (10.57.63.163).

The connection is not allowed because I mistake my erlang cookie (should be the same).

Let's try again (with the right cookie value):

enter image description here

Hurray, we got a Pong.

The 02 Erlang clusters are up.

And you can see that when I'm running nodes(), it returns client@sgsn on serveur@ggsn node, and vice-versa.

What is the trick:

Unfortunately, we cannot do everything only with Erlang.

I needed to edit /etc/hosts files as below:

(I assume that if we are using a DNS in the topology, there will be no need to edit /etc/hosts at all).

enter image description here

Hope it helps.

Lova Andrian
  • 123
  • 5
1

I think Throw Away Account's comment hits the nail in the head: this is mostly a networking problem, and there are plenty of duplicates of this question (here on Stackoverflow, and on other sites) that seem prove this (as most of them are unanswered):

Based on these links, it seems that things only seem to work out of the box when the networking setup is trivial (machines are in the same subnet, and they are running the same network stack). Otherwise I would assume that DNS needs to be set up properly, SSH tunnels need to be used, etc., but not sure how yet.


Posted this as a community wiki, because (1) it is not really an answer, and (2) hopefully someone, with more knowledge, will provide some pointers. (Or just give a standalone answer, whatever.)

toraritte
  • 6,300
  • 3
  • 46
  • 67