neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
lcuster
caf2803 · gmorell · 2026-05-21 22:55
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