Naming Nodes
Learn how to use and implement naming nodes in Elixir.
We'll cover the following
There’s nothing mysterious about a node. It is simply a running Erlang VM. Throughout this course, we’ve been running our code on a node.
The Erlang VM, called Beam, is more than a simple interpreter. It’s like its own little operating system running on top of our host operating system. It handles its own events, process scheduling, memory, naming services, and interprocess communication. In addition to all that, a node can connect to other nodes in the same computer, across a LAN, or across the Internet, and provide many of the same services across these connections that it provides to the processes it hosts locally.
Implementation
So far, we didn’t name our node because we’ve had only one. If we ask Elixir what the current node is called, it’ll give us a made-up name:
iex> Node.self
:nonode@nohost
We can set the name of a node when we start it. With IEx, we use the --name
or --sname
option. The former sets a fully qualified name. To run the command below, we exit from the iex
session using “Ctrl+C” twice.
$ iex --name wibble@educative.local
iex(wibble@educative.local)> Node.self
:"wibble@educative.local"
The --sname
option sets a short name:
$ iex --sname wobble
iex(wobble@educative)> Node.self
:"wobble@educative"
The name that’s returned is an atom. It’s in quotes because it contains characters not allowed in a literal atom.
Note: In both cases, the IEx prompt contains the node’s name along with the machine’s name (
educative
).
Now, let’s create an anonymous function that outputs the current node name.
iex(node_one@educative)> func = fn -> IO.inspect Node.self end
#Function<erl_eval.20.82930912>
We can run this with the spawn
function.
iex(node_one@educative)> spawn(func)
#PID<0.59.0>
node_one@educative
But spawn
also lets us specify a node name. The process will be spawned on that node.
iex(node_one@educative)> Node.spawn(:"node_one@educative", func)
#PID<0.57.0>
node_one@educative
We’re running on node one. When we tell spawn
to run on node_one@educative
, we see two lines of output. The first is the PID spawn
returns, and the second is the value of Node.self
that the function writes.
Nodes, cookies, and security
Although this is cool, it might also ring some alarm bells. If we can run arbitrary code on any node, then anyone with a publicly accessible node has just handed over their machine to any random hacker. But that’s not the case.
Before a node lets another connect, it checks that the remote node has permission. It does that by comparing that node’s cookie with its own cookie. A cookie is just an arbitrary string, ideally fairly long and very random. As an administrator of a distributed Elixir system, we need to create a cookie and then make sure all nodes use it.
If we’re running the iex
or elixir
commands, we can pass in the cookie using the --cookie
option.
$ iex --sname one --cookie chocolate-chip
iex(one@educative)> Node.get_cookie
:"chocolate-chip"
$ iex --sname node_one --cookie cookie-one
iex(node_one@educative)> Node.connect :"node_two@educative"
false
The node that attempts to connect receives false
, indicating the connection wasn’t made.
Run the above commands in the terminal below:
Get hands-on with 1400+ tech skills courses.