Cluster.Strategy.Consul behaviour (libcluster_consul v1.1.1) View Source

This clustering strategy is specific to the Consul service networking solution. It works by querying the platform's metadata API for containers belonging to a given service name and attempts to connect them (see: https://www.consul.io/api/catalog.html).

There is also the option to require connecting to nodes from different datacenters, or you can stick to a single datacenter.

It assumes that all nodes share a base name and are using longnames of the form <basename>@<ip> where the <ip> is unique for each node.

The Consul service registration isn't part of this module as there are many different ways to accomplish that, so it is assumed you'll do that from another part of your application.

An example configuration is below:

config :libcluster,
  topologies: [
    consul_example: [
      strategy: Elixir.Cluster.Strategy.Consul,
      config: [
        # The base agent URL.
        base_url: "http://consul.service.dc1.consul:8500",

        # If authentication is needed, set the access token here.
        access_token: "036c943f00594d9f97c10dec7e48ff19",

        # Nodes list will be refreshed using Consul on each interval.
        polling_interval: 10_000,

        # The Consul endpoints used to fetch service nodes.
        list_using: [
          # If you want to use the Agent HTTP API as specified in
          # https://www.consul.io/api/agent.html
          Cluster.Strategy.Consul.Agent

          # If you want to use the Health HTTP Endpoint as specified in
          # https://www.consul.io/api/health.html
          {Cluster.Strategy.Consul.Health, [passing: true]},

          # If you want to use the Catalog HTTP API as specified in
          # https://www.consul.io/api/catalog.html
          Cluster.Strategy.Consul.Catalog,

          # If you want to join nodes from multiple datacenters, do:
          {Cluster.Strategy.Consul.Multisite, [
            datacenters: ["dc1", "dc2", "dc3", ...],
            endpoints: [
              ... further endpoints ...
            ]
          ]},

          # You can also list all datacenters:
          {Cluster.Strategy.Consul.Multisite, [
            datacenters: :all,
            endpoints: [
              ... further endpoints ...
            ]
          ]},
        ]

        # All configurations below are defined as default for all
        # children endpoints.

        # Datacenter parameter while querying.
        dc: "dc1",

        # The default service for children endpoints specifications.
        service: [name: "service_name"],

        # NOTE:
        # Alternatively one could specify id for the service using
        # service: [id: "service_id"]
        # The keyword list should contain only one of them, either id or name.

        # This is the node basename, the Name (first) part of an Erlang
        # node name (before the @ part. If not specified, it will assume
        # the same name as the current running node.
        # The final node name will be "node_basename@<host_or_ip>"
        node_basename: "app_name",

        # Block when starting the cluster supervisor until after the initial
        # attempt to join the cluster, or join the cluster asynchronously.
        async_initial_connection?: true
      ]]]

The generic response of the Consul endpoints includes respective service's hostname of the node as well as it's IP. It is possible to establish connection using hostname exclusively by using following configuration. To retrieve only passing services :passing can be set to true which might be ignored if the API endpoint does not support health status.

{Cluster.Strategy.Consul.Agent, [expected: :host, passing: true]}

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor.

Callback implementation for Cluster.Strategy.start_link/1.

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

node_name(host_or_ip, config)

View Source

Callback implementation for Cluster.Strategy.start_link/1.

Link to this section Callbacks

Link to this callback

get_nodes(%Cluster.Strategy.State{})

View Source

Specs

get_nodes(%Cluster.Strategy.State{
  config: term(),
  connect: term(),
  disconnect: term(),
  list_nodes: term(),
  meta: term(),
  topology: term()
}) :: [atom()]