Globally distributed Elixir over Tailscale · Richard Taylor
I’ve been enjoying with deploying an Elixir Phoenix software to completely different clouds not too long ago and began wanting into easy options to cluster the nodes collectively.
I dabbled with Docker overlay networks to make nodes throughout completely different machines on the identical personal community seen to one another and used libcluster DNSPoll Strategy to auto-discover them through DNS which labored nice!
However what if you wish to cluster your machines throughout a number of completely different clouds, and even wherever on this planet on any machine?
Going International
Tailscale is a VPN service that makes the units and purposes you personal accessible wherever on this planet, securely and effortlessly. Observe the directions to download Tailscale to your system and begin the tailscaled
daemon.
When mentioning your node you have to specify the hostname, which we’ll use as a service identify for the cluster so make sure that it’s constant on all servers. There’s an assumption right here you’re mentioning one occasion of the service on one host, we’ll cowl docker containers in a later publish that may permit a number of variations of the service on a single host.
For instance, in case your app is known as hey
then we’d carry up tailscale like this:
tailscale up --authkey=${TAILSCALE_AUTHKEY} --hostname=hey
Be aware: you will get your Auth key out of your Tailscale settings. Select a Reusable
, Ephemeral
key when you’ve got any automation in place.
If succesful it’s best to see your machine within the Tailscale Dashboard.
Be aware: you would possibly see your machine identify as hello-1
, hello-2
and so on. when you’ve got a number of providers operating with the identical hostname, which is ok.
Now, if we repeat the identical directions on a second machine (this might be your growth machine), we’ll find yourself with two units related to the identical tailnet
on Tailscale. Let’s assume the second machine will get the Tailscale IP tackle of 100.1.1.2
, we are able to now join two Elixir nodes over the tailnet
like this:
iex --name hey@100.1.1.1 --cookie ${SECURE_COOKIE} -S combine
iex(hey@100.1.1.1.2)> Node.listing()
[]
iex(hey@100.1.1.1.2)> Node.join(:"hey@100.1.1.1")
true
iex(hey@100.1.1.1.2)> Node.listing()
[:"hello@100.1.1.1"]
That is nice! we are able to now join our Elixir nodes collectively from wherever over the safe Tailscale community. However this may be a bit tedious to deal with manually in manufacturing deployments so let’s discover a method to automate it.
Computerized discovery
The group go-to for Elixir clustering is libcluster. It handles loads of methods out of the field and supplies a versatile framework for including different methods.
I couldn’t discover something current locally to help service discovery and node connection so I wrote libcluster_tailscale which supplies a technique for libcluster that makes use of the Tailscale API to lookup hosts with matching hostnames after which routinely join them collectively.
Utilizing the instance above we would supply the next configration for libcluster
:
config :libcluster,
debug: true,
topologies: [
tailscale: [
strategy: Cluster.Strategy.Tailscale,
config: [
authkey: "tskey-api-xxx-yyy",
tailnet: "example.com",
hostname: "hello",
appname: "hello"
]
]
]
-
authkey
is your Tailscale API key you will get from Tailscale settings. -
tailnet
is the identify of your distinctive tailnet you will get from Tailscale settings (it’s listed beneathGroup
). -
hostname
is the identify you supplied Tailscale when bringing it up in your machine with--hostname
. This acts like a service identify that permits us to establish all of the nodes belonging to a particular service. In manufacturing you may also use the model of the service within the hostname to make sure solely nodes operating the identical model join with one another, for instance when deploying a brand new model alongside an current one. -
appname
is the identify a part of the Elixir node identify you supplied with--name
eg.hey
inhey@100.1.1.1.1
Be aware: the hostname
and appname
are the identical on this situation, however they’d probably be completely different in actuality.
Now after we begin our Elixir node, as a result of we enabled debug
we’ll see output like this:
[info] [libcluster:tailscale] related to :"hey@100.1.1.1.2"
[info] [libcluster:tailscale] related to :"hey@100.1.1.1.3"
This now permits us to deploy our Elixir software wherever on this planet, on any cloud or naked metallic server and have all of them routinely uncover and join to one another over Tailscale.
I’m going to cowl a full instance Phoenix software deployed utilizing Docker and this Tailscale setup in my subsequent weblog publish.
Let me know when you’ve got any feedback on Twitter or HN.