mirror of
https://gitlab.kube.huskypup.net/Scooby/Homelabv4.git
synced 2026-08-21 05:26:49 +00:00
Root cause of the 'PostgreSQL connection failed, retrying... (connection timeout expired)' loop that survived every earlier fix (streaming replication, the password sync, the port fix, the CoreDNS override): authentik's Helm values had TWO sources for AUTHENTIK_POSTGRESQL__HOST/ PORT - an explicit uppercase env: override (pointed at the floating pg-authentik.ha.huskypup.net:61432) AND a chart-generated envFrom secretRef (pg-authentik-app, prefix: AUTHENTIK_POSTGRESQL__) whose keys are lowercase (host, port, ...), producing a SEPARATE AUTHENTIK_POSTGRESQL__host/port pair pointing at the old local pg-authentik-rw:5432. Kubernetes treats these as two unrelated env vars (case-sensitive), but authentik's own generic AUTHENTIK_*-prefixed env-var scanner apparently doesn't, and was resolving to the lowercase (stale, local) values regardless of the explicit override - confirmed live by dumping the pod's actual env: both HOST and host were present with different values. Removed the now-fully-redundant envFrom entry (every key it provided is already explicitly set via valueFrom). Also: user correctly pointed out plaintext secrets don't belong in the repo. Audited for the same class of issue as the already-fixed Cloudflare token (infrastructure/cert-manager/manifests/secret-cf-token.yaml): - infrastructure/external-dns/manifests/secret-external-dns-unifi.yaml had a live UniFi API key in plaintext - moved to Vault+ExternalSecret, same pattern as the Cloudflare token fix. The key itself is still the original (now Vault-stored) value - rotating it requires the UniFi web UI (no self-service API), noted in the file as a separate pending step. - infrastructure/vps-eso/manifests/clustersecretstore.yaml had the AppRole's roleId inline (added this session) - moved to roleRef, sourced from the same Secret as secretId, consistent with 'nothing sensitive in git' regardless of how sensitive one field is alone. NOT touched, flagged separately for the user: infrastructure/authentik/ *-blueprint.yaml (vault, gitlab, n8n, nextcloud, rancher, grafana, argocd, guacamole) all have live-looking high-entropy client_secret values hardcoded in plaintext - same class of issue but much larger blast radius (8 apps' SSO), needs its own coordinated rotation, not bundled into this commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
129 lines
4.6 KiB
YAML
129 lines
4.6 KiB
YAML
# Authentik warm standby on the VPS - Phase 2, later extended into the
|
|
# multi-site active failover pilot (see
|
|
# /home/scooby/.claude/plans/jiggly-snacking-iverson.md). The CNPG cluster
|
|
# (manifests/cnpg-cluster.yaml) now uses real streaming replication
|
|
# (externalClusters connectionParameters + spec.replica.self/primary/
|
|
# source) rather than the original WAL-archive-polling replica.enabled
|
|
# mode - that flag is gone from cnpg-cluster.yaml now, it's mutually
|
|
# exclusive with the primary/self fields. The app itself DOES run
|
|
# continuously (replicas: 1, reachable at auth.vps.huskypup.net - see
|
|
# manifests/ingress.yaml) so the replicated data is browsable/verifiable
|
|
# at all times, even though the underlying DB is a read-only replica until
|
|
# promoted. Promotion (automatic via the failover-watcher, or manually):
|
|
# patch cnpg-cluster.yaml's spec.replica to self/primary/source: vps.
|
|
#
|
|
# The `authentik:` block below (secret_key/postgresql "env://" indirection)
|
|
# is copied VERBATIM from infrastructure/authentik/values.yaml on purpose -
|
|
# the authentik chart deterministically renders its own generated Secret
|
|
# from these literal values.yaml strings (not randomly), so keeping this
|
|
# block byte-identical between home and VPS means both clusters
|
|
# independently arrive at the same AUTHENTIK_SECRET_KEY without needing to
|
|
# manually copy it - required for promotion to work, since that key
|
|
# decrypts things (stored provider secrets, cert private keys) that live
|
|
# encrypted in the DB being replicated.
|
|
authentik:
|
|
secret_key: env://AUTHENTIK_SECRET_KEY
|
|
postgresql:
|
|
host: env://AUTHENTIK_POSTGRESQL__HOST
|
|
port: 5432
|
|
name: env://AUTHENTIK_POSTGRESQL__NAME
|
|
user: env://AUTHENTIK_POSTGRESQL__USER
|
|
password: env://AUTHENTIK_POSTGRESQL__PASSWORD
|
|
|
|
global:
|
|
envFrom:
|
|
- secretRef:
|
|
name: authentik
|
|
# The pg-authentik-app secretRef that used to live here is GONE - see
|
|
# the matching comment in infrastructure/authentik/values.yaml (home's
|
|
# copy of this same block) for why: its lowercase-suffixed env vars
|
|
# (AUTHENTIK_POSTGRESQL__host etc.) were silently winning over the
|
|
# explicit uppercase HOST/PORT overrides below, connecting straight to
|
|
# the local CNPG service the whole time regardless of what was set.
|
|
env:
|
|
- name: AUTHENTIK_URL
|
|
value: "https://auth.vps.huskypup.net"
|
|
# HOST/PORT point at the floating pg-authentik.ha.huskypup.net record
|
|
# instead of the local secret's host/port - see the matching comment
|
|
# in infrastructure/authentik/values.yaml (home's copy of this same
|
|
# block) for the full explanation, including why pg-authentik-app's
|
|
# password had to be manually synced between the two sites first.
|
|
- name: AUTHENTIK_POSTGRESQL__HOST
|
|
value: "pg-authentik.ha.huskypup.net"
|
|
- name: AUTHENTIK_POSTGRESQL__NAME
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: pg-authentik-app
|
|
key: dbname
|
|
- name: AUTHENTIK_POSTGRESQL__USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: pg-authentik-app
|
|
key: username
|
|
- name: AUTHENTIK_POSTGRESQL__PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: pg-authentik-app
|
|
key: password
|
|
- name: AUTHENTIK_POSTGRESQL__PORT
|
|
value: "61432"
|
|
|
|
server:
|
|
replicas: 1
|
|
# Default failureThreshold: 3 (40s runway) is too strict running against
|
|
# a read-only CNPG replica - the worker constantly retries a scheduled-
|
|
# task query that needs a write lock (harmless, expected, logged as
|
|
# 'cannot execute SELECT FOR UPDATE in a read-only transaction'), and
|
|
# any transient DB hiccup during that trips the server's health check
|
|
# and gets it killed (confirmed live: CrashLoopBackOff, 'connection
|
|
# refused' during a brief blip). Widened so brief hiccups don't kill it.
|
|
livenessProbe:
|
|
failureThreshold: 10
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
readinessProbe:
|
|
failureThreshold: 10
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
containerSecurityContext:
|
|
runAsNonRoot: true
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 512Mi
|
|
limits:
|
|
memory: 1Gi
|
|
metrics:
|
|
enabled: false
|
|
|
|
worker:
|
|
replicas: 1
|
|
containerSecurityContext:
|
|
runAsNonRoot: true
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 512Mi
|
|
limits:
|
|
memory: 1Gi
|
|
metrics:
|
|
enabled: false
|
|
|
|
# Disable bundled Postgres - using the CNPG replica cluster instead
|
|
postgresql:
|
|
enabled: false
|