# `Cluster.Strategy.Kubernetes.DNS`
[🔗](https://github.com/bitwalker/libcluster/blob/3.6.0/lib/strategy/kubernetes_dns.ex#L1)

This clustering strategy works by fetching IP addresses with the help of a headless service in
current Kubernetes namespace.

> This strategy requires exposing pods by a headless service.
> If you want to avoid that, you could use `Cluster.Strategy.Kubernetes`.

It assumes that all Erlang nodes are using longnames - `<basename>@<ip>`:

+ all nodes are using the same `<basename>`
+ all nodes are using unique `<ip>`

In `<basename>@<ip>`:

+ `<basename>` would be the value configured by `:application_name` option.
+ `<ip>` would be the value which is controlled by following options:
   - `:service`
   - `:resolver`

## Getting `<basename>`

As said above, the basename is configured by `:application_name` option.

The basename of each peer's running node must match `:application_name`. The Mix release name is
only the default basename in the examples below; an explicit `RELEASE_NODE` can override it.
See [Kubernetes node naming](readme.html#kubernetes-node-naming) for runtime release configuration
and troubleshooting long names, peer identities and connectivity.

## Getting `<ip>`

It will fetch IP addresses of all pods under a headless service and attempt to connect.

## Setup

Getting this strategy to work requires:

1. exposing pod IP from Kubernetes to the Erlang node.
2. setting a headless service for the pods
3. setting the name of Erlang node according to the exposed information

First, expose required information from Kubernetes as environment variables of Erlang node:

    # deployment.yaml
    env:
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP

Second, set a headless service for the pods:

    # deployment.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-headless
    spec:
      selector:
        app: myapp
      type: ClusterIP
      clusterIP: None

Then, set the name of Erlang node by using the exposed environment variables. If you use mix releases, you
can configure the required options in `rel/env.sh.eex`:

    # rel/env.sh.eex
    export RELEASE_DISTRIBUTION=name
    export RELEASE_NODE="<%= @release.name %>@${POD_IP}"

## Polling Interval

The default interval to sync topologies is `5000`
(5 seconds). You can configure it with `:polling_interval` option.

## An example configuration

    config :libcluster,
      topologies: [
        erlang_nodes_in_k8s: [
          strategy: Elixir.Cluster.Strategy.Kubernetes.DNS,
          config: [
            service: "myapp-headless",
            application_name: "myapp",
            polling_interval: 10_000
          ]
        ]
      ]

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
