6.5 KiB · text History 0aa3d5d
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ircd
  namespace: neiam-ircd
  labels:
    name: ircd
    keel.sh/policy: force
    keel.sh/trigger: poll
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ircd
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  template:
    metadata:
      labels:
        app: ircd
    spec:
      serviceAccountName: ircd
      terminationGracePeriodSeconds: 30
      containers:
        - name: ircd
          image: r.g.gmp.io/neiam/ohmyxo:kubernetes-master
          imagePullPolicy: Always
          ports:
            - { name: http, containerPort: 4000 }
            - { name: irc,  containerPort: 6667 }
            - { name: epmd, containerPort: 4369 }
            - { name: dist, containerPort: 9100 }
          env:
            # Phoenix bring-up
            - { name: PHX_SERVER, value: "true" }
            - { name: PHX_HOST,   value: "irc.skyjeep.club" }
            - { name: PORT,       value: "4000" }

            # IRC config
            - { name: IRC_PORT,            value: "6667" }
            - { name: IRC_SERVER_NAME,     value: "irc.skyjeep.club" }
            - { name: IRC_NETWORK_NAME,    value: "SkyjeepIRC" }
            # Defaults in runtime.exs: anonymous IRC ON, web registration
            # invite-only, /webirc OFF. Uncomment to override:
            # - { name: IRC_ALLOW_ANONYMOUS, value: "false" }
            # - { name: REGISTRATION_MODE,   value: "open" }
            # - { name: WEBIRC_ENABLED,      value: "true" }

            # TLS terminates at Traefik now (see the IngressRouteTCP at
            # the bottom). Backend speaks plain IRC on 6667 only; we
            # still get real client IPs via PROXY v2.
            - { name: IRC_PROXY_PROTOCOL, value: "true" }

            # BEAM cluster
            - { name: CLUSTER_STRATEGY,      value: "kubernetes" }
            - { name: CLUSTER_K8S_NAMESPACE, value: "neiam-ircd" }
            - { name: CLUSTER_K8S_SERVICE,   value: "ircd-headless" }
            - { name: CLUSTER_K8S_APP_NAME,  value: "ircd" }
            - { name: CLUSTER_K8S_SELECTOR,  value: "app=ircd" }
            - name: POD_IP
              valueFrom: { fieldRef: { fieldPath: status.podIP } }

            # StackGres-generated DB credentials
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef: { name: postgres-ircd, key: superuser-username }
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef: { name: postgres-ircd, key: superuser-password }
            - { name: POSTGRES_HOST, value: "postgres-ircd" }
            - { name: POSTGRES_PORT, value: "5432" }
            - name: DATABASE_URL
              value: ecto://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):$(POSTGRES_PORT)/ircd

            # App secrets
            - name: SECRET_KEY_BASE
              valueFrom: { secretKeyRef: { name: ircd-secrets, key: SECRET_KEY_BASE } }
            - name: RELEASE_COOKIE
              valueFrom: { secretKeyRef: { name: ircd-secrets, key: RELEASE_COOKIE } }

          readinessProbe:
            httpGet: { path: /, port: http }
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            # Use the HTTP port — same BEAM serves it, no PROXY required.
            # A bare TCP connect to 6667 would now fail because the
            # listener expects a PROXY header on every connection.
            httpGet: { path: /, port: http }
            initialDelaySeconds: 30
            periodSeconds: 15

          resources:
            requests: { cpu: 100m, memory: 256Mi }
            limits:   { cpu: 1,    memory: 1Gi }

      imagePullSecrets:
        - name: gitlabgmp
---
# Headless Service for libcluster pod discovery.
apiVersion: v1
kind: Service
metadata:
  name: ircd-headless
  namespace: neiam-ircd
spec:
  clusterIP: None
  publishNotReadyAddresses: true
  selector:
    app: ircd
  ports:
    - { name: epmd, port: 4369, targetPort: 4369 }
    - { name: dist, port: 9100, targetPort: 9100 }
---
# Web UI service, fronted by Traefik via the Ingress below.
apiVersion: v1
kind: Service
metadata:
  name: ircd-web
  namespace: neiam-ircd
spec:
  selector:
    app: ircd
  ports:
    - { name: http, port: 80, targetPort: 4000 }
---
# Plain + TLS IRC service. Traefik routes TCP from public entryPoints
# to these ports via the IngressRouteTCPs below.
apiVersion: v1
kind: Service
metadata:
  name: ircd-irc
  namespace: neiam-ircd
spec:
  selector:
    app: ircd
  ports:
    # Single backend port — Traefik terminates TLS for the ircds
    # entryPoint and forwards plain + PROXY v2 here.
    - { name: irc, port: 6667, targetPort: 6667 }
---
# HTTPS Ingress for the Phoenix LiveView / web UI.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ircd-web
  namespace: neiam-ircd
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/ingress.class: traefik
spec:
  tls:
    - hosts: [irc.skyjeep.club]
      secretName: ircd-tls
  rules:
    - host: irc.skyjeep.club
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ircd-web
                port: { number: 80 }
---
# Traefik raw-TCP routing for the IRC plain port. Assumes a Traefik
# entryPoint named `irc` listening on 6667 — add to your Traefik
# static config:
#
#   entryPoints:
#     irc:
#       address: ":6667"
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: ircd-irc
  namespace: neiam-ircd
spec:
  entryPoints: [ircd]
  routes:
    - match: HostSNI(`*`)
      services:
        - name: ircd-irc
          port: 6667
          proxyProtocol:
            version: 2
---
# Traefik terminates TLS for the ircds entryPoint using the
# cert-manager-issued Secret, then forwards plain TCP + a PROXY v2
# header to the same `ircd-irc:6667` backend the plain entryPoint uses.
# Real client IPs survive end-to-end without the in-pod `:ssl` needing
# to deal with PROXY (which it can't).
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: ircd-ircs
  namespace: neiam-ircd
spec:
  entryPoints: [ircds]
  routes:
    - match: HostSNI(`*`)
      services:
        # TLS terminates at Traefik; backend speaks plain IRC on 6667
        # with a PROXY v2 header so we still see the real client IP.
        - name: ircd-irc
          port: 6667
          proxyProtocol:
            version: 2
  tls:
    # Cert-manager's `ircd-tls` Secret — same one the web Ingress uses.
    # Traefik reloads it automatically on rotation.
    secretName: ircd-tls