From da42d6449448d7e1936f9d938a44268f258704a2 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Fri, 2 Jan 2026 15:29:02 -0600 Subject: [PATCH] cluster --- config/runtime.exs | 13 +++++++++++++ k8s/deployment.yaml | 20 ++++++++++++++++++++ k8s/kustomization.yaml | 1 + k8s/service-headless.yaml | 17 +++++++++++++++++ lib/towerops/application.ex | 3 +++ mix.exs | 1 + mix.lock | 1 + 7 files changed, 56 insertions(+) create mode 100644 k8s/service-headless.yaml diff --git a/config/runtime.exs b/config/runtime.exs index 36e82781..1aced7a9 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -46,6 +46,19 @@ if config_env() == :prod do host = System.get_env("PHX_HOST") || "example.com" + config :libcluster, + topologies: [ + k8s: [ + strategy: Cluster.Strategy.Kubernetes.DNS, + config: [ + service: "towerops-headless", + application_name: "towerops", + namespace: "towerops", + polling_interval: 10_000 + ] + ] + ] + config :towerops, Towerops.Repo, # ssl: true, url: database_url, diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index 96ac0bd8..45eb8a98 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -23,7 +23,27 @@ spec: ports: - containerPort: 4000 name: http + - containerPort: 4369 + name: epmd + - containerPort: 9000 + name: dist env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: RELEASE_DISTRIBUTION + value: "name" + - name: RELEASE_NODE + value: "towerops@$(POD_IP)" - name: PORT value: "4000" - name: PHX_HOST diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml index 00a392e4..37dff34c 100644 --- a/k8s/kustomization.yaml +++ b/k8s/kustomization.yaml @@ -5,5 +5,6 @@ resources: - namespace.yaml - deployment.yaml - service.yaml + - service-headless.yaml - certificate.yaml - ingressroute.yaml diff --git a/k8s/service-headless.yaml b/k8s/service-headless.yaml new file mode 100644 index 00000000..b9cd2349 --- /dev/null +++ b/k8s/service-headless.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: towerops-headless + namespace: towerops +spec: + clusterIP: None + selector: + app: towerops + ports: + - name: epmd + port: 4369 + targetPort: 4369 + - name: dist + port: 9000 + targetPort: 9000 diff --git a/lib/towerops/application.ex b/lib/towerops/application.ex index 3a961c48..78d680d9 100644 --- a/lib/towerops/application.ex +++ b/lib/towerops/application.ex @@ -7,7 +7,10 @@ defmodule Towerops.Application do @impl true def start(_type, _args) do + topologies = Application.get_env(:libcluster, :topologies, []) + children = [ + {Cluster.Supervisor, [topologies, [name: Towerops.ClusterSupervisor]]}, ToweropsWeb.Telemetry, Towerops.Repo, {DNSCluster, query: Application.get_env(:towerops, :dns_cluster_query) || :ignore}, diff --git a/mix.exs b/mix.exs index 985a8726..5633ad3a 100644 --- a/mix.exs +++ b/mix.exs @@ -61,6 +61,7 @@ defmodule Towerops.MixProject do {:gettext, "~> 1.0"}, {:jason, "~> 1.2"}, {:dns_cluster, "~> 0.2.0"}, + {:libcluster, "~> 3.4"}, {:bandit, "~> 1.5"}, {:styler, "~> 1.10", only: [:dev, :test], runtime: false} ] diff --git a/mix.lock b/mix.lock index d792cf37..463d8e0b 100644 --- a/mix.lock +++ b/mix.lock @@ -20,6 +20,7 @@ "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "lazy_html": {:hex, :lazy_html, "0.1.8", "677a8642e644eef8de98f3040e2520d42d0f0f8bd6c5cd49db36504e34dffe91", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.9.0", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}], "hexpm", "0d8167d930b704feb94b41414ca7f5779dff9bca7fcf619fcef18de138f08736"}, + "libcluster": {:hex, :libcluster, "3.5.0", "5ee4cfde4bdf32b2fef271e33ce3241e89509f4344f6c6a8d4069937484866ba", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebf6561fcedd765a4cd43b4b8c04b1c87f4177b5fb3cbdfe40a780499d72f743"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},