bitwalker/libcluster

Help with configuring/using Kubernetes strategy

mauricionr opened this issue · 8 comments

I'm trying to understand why my topology config ain't working and i guess this line is a little bit confusing.

app_name looks like it's the application name and not the kubernetes_node_basename

app_name = Keyword.fetch!(config, :kubernetes_node_basename)

i will be grateful if i can find an example using the strategy Elixir.Cluster.Strategy.Kubernetes with full configuration.

Thanks 😄

The node base name is the <basename> portion of <basename>@<fqdn_or_ip> that your Elixir release/application is configured with. By default this will be the name of the release (if using releases), if just using Mix, it will have been set by either --sname <basename> or --name <basename>@fqdn_or_ip.

The module documentation here shows how that config should be set for an app that was started with the name myapp@<fqdn_or_ip>, e.g. myapp@127.0.0.1 or myapp@my_namespace.cluster.local, where the pods are labeled with app=myapp.

Does that help?

The node base name is the <basename> portion of <basename>@<fqdn_or_ip> that your Elixir release/application is configured with. By default this will be the name of the release (if using releases), if just using Mix, it will have been set by either --sname <basename> or --name <basename>@fqdn_or_ip.

The module documentation here shows how that config should be set for an app that was started with the name myapp@<fqdn_or_ip>, e.g. myapp@127.0.0.1 or myapp@my_namespace.cluster.local, where the pods are labeled with app=myapp.

Does that help?

i'm using a normal service and not a headless one.
in the kubernetes_ip_lookup_mode i'm using :pods, is the same config?

Thanks in advance!

Yes, the node base name is the same regardless of what method is used to find other pods/instances, since ultimately we connect to the other nodes using the Erlang node name, the strategy is primarily a means of finding the <fqdn_or_ip> portion of the name, but the node base name has to be provided manually, since that is typically static and not based on dynamic configuration (though there isn't any reason why it can't be, it is just not really necessary, and therefore rare).

so i must put the --name or --sname when starting my app with iex mix...? and map them in the kubernetes_node_basename?

Yes, the node base name is the same regardless of what method is used to find other pods/instances, since ultimately we connect to the other nodes using the Erlang node name, the strategy is primarily a means of finding the <fqdn_or_ip> portion of the name, but the node base name has to be provided manually, since that is typically static and not based on dynamic configuration (though there isn't any reason why it can't be, it is just not really necessary, and therefore rare).

i put them manually and got an warn saying unable to connect to :xpto@x.x.x.x not part of network 🤔

Are you deploying an OTP release (i.e. with Distillery or the new Elixir 1.9 release tools), or without? If not using releases, then yes, you need to pass --name to mix run or whatever command you use to start the app. You must make sure that the <fqdn_or_ip> part of xpto@<fqdn_or_ip> is routable from other pods though, so you can't use an arbitrary IP or host name. This is usually done by exporting an env var (e.g. HOSTNAME) in the pod that contains that pods IP address (or fully-qualfied hostname), and then setting the name (via --name for example) as myapp@${HOSTNAME}. The "unable to connect" error indicates that the name you chose is either not routable (i.e. the x.x.x.x part), or the node you are trying to reach is not configured to use that name.

I did what you say, i've tried both strategies, but, i guess that my issue is because i'm using an service type LoadBalancer and therefore i can't use the clusterIP: None 🤔

it's possible connect the elixir nodes with this kubernetes settings?

You may need to use one of the alternative clustering strategies, e.g. Cluster.Strategy.Kubernetes.DNS or Cluster.Strategy.Kubernetes.DNSSRV (just added in 3.1.1). These methods do not rely on an IP and instead use DNS records to look up the correct IP address and connect that way.

It is necessary of course that traffic on the Erlang distribution ports is allowed between the nodes, so make sure that is the case.