lcuster

caf2803 · gmorell · 2026-05-21 22:55

8 files +56 -32

Files changed

modified config/runtime.exs
+1 −1
@@ -124,7 +124,7 @@ if System.get_env("CLUSTER_STRATEGY") == "kubernetes" do
124 124 oh_my_ex_oh: [
125 125 strategy: Cluster.Strategy.Kubernetes,
126 126 config: [
127 − mode: :hostname,
127 + mode: :ip,
128 128 kubernetes_node_basename: System.get_env("CLUSTER_K8S_APP_NAME", "ircd"),
129 129 kubernetes_selector:
130 130 System.get_env("CLUSTER_K8S_SELECTOR", "app=ircd"),
modified deploy/argo/neiam-ircd/app.yml
+19 −31
@@ -31,7 +31,6 @@ spec:
31 31 ports:
32 32 - { name: http, containerPort: 4000 }
33 33 - { name: irc, containerPort: 6667 }
34 − - { name: ircs, containerPort: 6697 }
35 34 - { name: epmd, containerPort: 4369 }
36 35 - { name: dist, containerPort: 9100 }
37 36 env:
@@ -49,14 +48,9 @@ spec:
49 48 # - { name: IRC_ALLOW_ANONYMOUS, value: "false" }
50 49 # - { name: REGISTRATION_MODE, value: "open" }
51 50
52 − # TLS — cert files come from the cert-manager Secret below.
53 − - { name: IRC_TLS_ENABLED, value: "true" }
54 − - { name: IRC_TLS_PORT, value: "6697" }
55 − - { name: IRC_TLS_CERT_PATH, value: "/etc/tls/tls.crt" }
56 − - { name: IRC_TLS_KEY_PATH, value: "/etc/tls/tls.key" }
57 − # PROXY v2 from Traefik — required so we see the real client IP
58 − # instead of Traefik's pod IP. Matched by the IngressRouteTCP
59 − # service `proxyProtocol.version: 2` setting below.
51 + # TLS terminates at Traefik now (see the IngressRouteTCP at
52 + # the bottom). Backend speaks plain IRC on 6667 only; we
53 + # still get real client IPs via PROXY v2.
60 54 - { name: IRC_PROXY_PROTOCOL, value: "true" }
61 55
62 56 # BEAM cluster
@@ -86,9 +80,6 @@ spec:
86 80 - name: RELEASE_COOKIE
87 81 valueFrom: { secretKeyRef: { name: ircd-secrets, key: RELEASE_COOKIE } }
88 82
89 − volumeMounts:
90 − - { name: tls, mountPath: /etc/tls, readOnly: true }
91 −
92 83 readinessProbe:
93 84 httpGet: { path: /, port: http }
94 85 initialDelaySeconds: 10
@@ -107,10 +98,6 @@ spec:
107 98
108 99 imagePullSecrets:
109 100 - name: gitlabgmp
110 − volumes:
111 − - name: tls
112 − secret:
113 − secretName: ircd-tls
114 101 ---
115 102 # Headless Service for libcluster pod discovery.
116 103 apiVersion: v1
@@ -150,8 +137,9 @@ spec:
150 137 selector:
151 138 app: ircd
152 139 ports:
153 − - { name: irc, port: 6667, targetPort: 6667 }
154 − - { name: ircs, port: 6697, targetPort: 6697 }
140 + # Single backend port — Traefik terminates TLS for the ircds
141 + # entryPoint and forwards plain + PROXY v2 here.
142 + - { name: irc, port: 6667, targetPort: 6667 }
155 143 ---
156 144 # HTTPS Ingress for the Phoenix LiveView / web UI.
157 145 apiVersion: networking.k8s.io/v1
@@ -199,12 +187,11 @@ spec:
199 187 proxyProtocol:
200 188 version: 2
201 189 ---
202 −# Traefik TLS-passthrough for IRC-over-TLS. Termination happens inside
203 −# the IRC pod using the cert-manager-issued cert. Add to Traefik:
204 −#
205 −# entryPoints:
206 −# ircs:
207 −# address: ":6697"
190 +# Traefik terminates TLS for the ircds entryPoint using the
191 +# cert-manager-issued Secret, then forwards plain TCP + a PROXY v2
192 +# header to the same `ircd-irc:6667` backend the plain entryPoint uses.
193 +# Real client IPs survive end-to-end without the in-pod `:ssl` needing
194 +# to deal with PROXY (which it can't).
208 195 apiVersion: traefik.io/v1alpha1
209 196 kind: IngressRouteTCP
210 197 metadata:
@@ -215,12 +202,13 @@ spec:
215 202 routes:
216 203 - match: HostSNI(`*`)
217 204 services:
205 + # TLS terminates at Traefik; backend speaks plain IRC on 6667
206 + # with a PROXY v2 header so we still see the real client IP.
218 207 - name: ircd-irc
219 − port: 6697
220 − # No proxyProtocol here — when Traefik does TLS passthrough,
221 − # the PROXY v2 header would land before the ClientHello and
222 − # confuse :ssl in the pod. TLS users currently appear as
223 − # Traefik's IP; switching to TLS-termination-at-Traefik with
224 − # PROXY would fix it but loses per-handshake cert refresh.
208 + port: 6667
209 + proxyProtocol:
210 + version: 2
225 211 tls:
226 − passthrough: true
212 + # Cert-manager's `ircd-tls` Secret — same one the web Ingress uses.
213 + # Traefik reloads it automatically on rotation.
214 + secretName: ircd-tls
added rel/env.sh.eex
+36 −0
@@ -0,0 +1,36 @@
1 +#!/bin/sh
2 +# Sourced by every `bin/oh_my_ex_oh_ircd <command>` invocation. We always set
3 +# `RELEASE_NODE` when `POD_IP` is available because *every* subcommand
4 +# needs to know the running release's node name:
5 +#
6 +# - `start` / `daemon` register the running server under this name.
7 +# - `remote` / `eval` / `rpc` pass it to `-remsh` (or RPC dial) to
8 +# attach to the running server. The temporary BEAM those commands
9 +# spawn picks its OWN unique short name (`rem-<rand>@<host>`),
10 +# so setting RELEASE_NODE here does not cause an epmd collision —
11 +# it only tells the temporary BEAM which target to talk to.
12 +#
13 +# Only `start` / `daemon` get the dist port pinned, since the
14 +# temporary BEAMs for remote/eval/rpc only make outbound connections
15 +# and don't need their own listener at a known port.
16 +#
17 +# POD_IP comes from the deployment's downward API. RELEASE_COOKIE
18 +# comes from the ircd-secrets Secret so every replica agrees on the
19 +# Erlang cookie.
20 +
21 +if [ -n "${POD_IP:-}" ]; then
22 + export RELEASE_DISTRIBUTION=name
23 + export RELEASE_NODE="ircd@${POD_IP}"
24 +else
25 + echo "[env.sh] POD_IP is empty — falling back to default short-name distribution" >&2
26 +fi
27 +
28 +case ${RELEASE_COMMAND:-} in
29 + start*|daemon*)
30 + echo "[env.sh] starting with name distribution as ${RELEASE_NODE:-(unset)}" >&2
31 + # Pin the inet_dist listener so the port is predictable from peers
32 + # and matches the headless service / any future NetworkPolicy.
33 + # Without this BEAM picks a random ephemeral port each boot.
34 + export ELIXIR_ERL_OPTIONS="${ELIXIR_ERL_OPTIONS:-} -kernel inet_dist_listen_min 9100 inet_dist_listen_max 9100"
35 + ;;
36 +esac

Parents: ddb8532