mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 10:13:58 +00:00
feat(k3s): add pg.prole.org as CNPG postgres endpoint with split-horizon DNS
- knoe-db.yaml: switch to CNPG-managed TLS cert with serverAltDNSNames (pg.prole.org + knoe-db-rw cluster service) — removes static serverTLSSecret/serverCASecret - dns.yml: add pg.prole.org A record to prole_k3s_dns_records (10.0.0.3, 10.0.0.6) for Ansible-managed split-horizon DNS via Samba AD DC - k3s.cfg: align KNOE_HOME paths to ~/dev/prole, add PROLE_KDC_* vars, remove hardcoded KUBECTL_CONTEXT (kubeconfig current-context is authoritative) - prod.cfg: add PROLE_KDC_STORAGE_CLASS = prole-iscsi - onepassword.py: skip vault check gracefully when no 1Password session active (non-TTY) - CLAUDE.md: document production postgres connection string and DNS/CA cert ops Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f34d10908a
commit
e014fd5b71
33
CLAUDE.md
33
CLAUDE.md
@ -206,3 +206,36 @@ Quick reference. Each entry links to the master index where context, owner, and
|
|||||||
**Closed in 2026-04-29 stabilization session:** Garage on DB cluster removed; cluster pods migrated to `cnpg-backup-sa` via CNPG v1.29.0 `spec.serviceAccountName`; both operators restarted clean.
|
**Closed in 2026-04-29 stabilization session:** Garage on DB cluster removed; cluster pods migrated to `cnpg-backup-sa` via CNPG v1.29.0 `spec.serviceAccountName`; both operators restarted clean.
|
||||||
|
|
||||||
**Closed 2026-05-01:** R4 — installer env-contamination guard now live in `deploy.sh` (strict) + `install.sh` (informational notice). Helper at [`etc/preflight_kubecontext.sh`](etc/preflight_kubecontext.sh).
|
**Closed 2026-05-01:** R4 — installer env-contamination guard now live in `deploy.sh` (strict) + `install.sh` (informational notice). Helper at [`etc/preflight_kubecontext.sh`](etc/preflight_kubecontext.sh).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## k3s CNPG database (production)
|
||||||
|
|
||||||
|
The prole.org k3s CNPG cluster is this project's **production** PostgreSQL database.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql "host=pg.prole.org port=5432 user=chrisfu dbname=postgres sslmode=verify-full sslrootcert=$HOME/.knoe/knoe-db-ca.crt"
|
||||||
|
```
|
||||||
|
|
||||||
|
| Detail | Value |
|
||||||
|
|---|---|
|
||||||
|
| External hostname | `pg.prole.org:5432` |
|
||||||
|
| Internal service | `knoe-db-rw.knoe-db.svc.cluster.local:5432` |
|
||||||
|
| kubectl context | `prole-service-cluster` |
|
||||||
|
| Namespace | `knoe-db` |
|
||||||
|
| CA cert | `~/.knoe/knoe-db-ca.crt` |
|
||||||
|
| sslmode | `verify-full` |
|
||||||
|
|
||||||
|
**DNS**: `pg.prole.org` resolves internally via split-horizon DNS on `myrddin.prole.org` (Samba AD DC) to the k3s ServiceLB node IPs (`10.0.0.3`, `10.0.0.6`). External DNS resolves to the public IP — do not access from outside the LAN without a VPN.
|
||||||
|
|
||||||
|
**CA cert refresh** (after CNPG cert rotation):
|
||||||
|
```bash
|
||||||
|
kubectl --context=prole-service-cluster -n knoe-db \
|
||||||
|
get secret knoe-db-ca -o jsonpath='{.data.ca\.crt}' | base64 -d > ~/.knoe/knoe-db-ca.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
**Node mobility**: to move the postgres LoadBalancer to a different node, update the Samba DNS A records:
|
||||||
|
```bash
|
||||||
|
ssh myrddin.prole.org "sudo samba-tool dns delete myrddin.prole.org prole.org pg A <OLD_IP> -U Administrator"
|
||||||
|
ssh myrddin.prole.org "sudo samba-tool dns add myrddin.prole.org prole.org pg A <NEW_IP> -U Administrator"
|
||||||
|
```
|
||||||
|
|||||||
19
conf/k3s.cfg
19
conf/k3s.cfg
@ -154,13 +154,17 @@ OP_KDC_GUEST_PASSWORD_REF =
|
|||||||
K3S_SERVER = https://myrddin.prole.org:6443
|
K3S_SERVER = https://myrddin.prole.org:6443
|
||||||
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
||||||
KNOE_DB_USER = root
|
KNOE_DB_USER = root
|
||||||
KNOE_HOME = $HOME/dev/knoe
|
KNOE_HOME = $HOME/dev/prole
|
||||||
KNOE_IMAGE_REGISTRY = registry.prole.org
|
KNOE_IMAGE_REGISTRY = registry.prole.org
|
||||||
|
PROLE_ENABLE_LOCAL_REGISTRY = true
|
||||||
MONITORING_STORAGE_CLASS = merlin-local-iscsi-prometheus
|
MONITORING_STORAGE_CLASS = merlin-local-iscsi-prometheus
|
||||||
OPENTOFU_URL = http://127.0.0.1:8080
|
OPENTOFU_URL = http://127.0.0.1:8080
|
||||||
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
|
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
|
||||||
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
|
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
|
||||||
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
||||||
|
PROLE_KDC_TRUST_REALM = PROLE.ORG
|
||||||
|
PROLE_KDC_TRUST_ADMIN = administrator@PROLE.ORG
|
||||||
|
PROLE_KDC_STORAGE_CLASS = prole-iscsi
|
||||||
PROTECTED_DB_HOSTS = db.prole.org
|
PROTECTED_DB_HOSTS = db.prole.org
|
||||||
PROTECTED_GIT_HOSTS = git.prole.org
|
PROTECTED_GIT_HOSTS = git.prole.org
|
||||||
REDIS_HOST = redis-master.knoe-system.svc.cluster.local
|
REDIS_HOST = redis-master.knoe-system.svc.cluster.local
|
||||||
@ -203,11 +207,11 @@ PORT_FORWARD_K3S_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/promethe
|
|||||||
PORT_FORWARD_K3S_MAPPING_9 = id=gitea-http;namespace=gitea;target=svc/gitea-http;address=0.0.0.0;hostPort=13000;servicePort=3000;protocol=TCP;description=Gitea Web
|
PORT_FORWARD_K3S_MAPPING_9 = id=gitea-http;namespace=gitea;target=svc/gitea-http;address=0.0.0.0;hostPort=13000;servicePort=3000;protocol=TCP;description=Gitea Web
|
||||||
|
|
||||||
[System Environment]
|
[System Environment]
|
||||||
KNOE_CONF = $HOME/dev/knoe/conf
|
KNOE_CONF = $HOME/dev/prole/conf
|
||||||
KNOE_HOME = $HOME/dev/knoe
|
KNOE_HOME = $HOME/dev/prole
|
||||||
KNOE_SERVICE = $HOME/dev/knoe/etc
|
KNOE_SERVICE = $HOME/dev/prole/etc
|
||||||
PROLE_DATA = $HOME/dev/knoe/data
|
PROLE_DATA = $HOME/dev/prole/data
|
||||||
PROLE_LOGS = $HOME/dev/knoe/logs
|
PROLE_LOGS = $HOME/dev/prole/logs
|
||||||
|
|
||||||
[Monitoring]
|
[Monitoring]
|
||||||
MONITORING_STORAGE_CLASS = merlin-local-iscsi-prometheus
|
MONITORING_STORAGE_CLASS = merlin-local-iscsi-prometheus
|
||||||
@ -249,7 +253,8 @@ CLUSTER_ENV = knoe-service-cluster
|
|||||||
DISPLAY_NAME = knoe-service-cluster
|
DISPLAY_NAME = knoe-service-cluster
|
||||||
K3S_SERVER_URL = https://myrddin.prole.org:6443
|
K3S_SERVER_URL = https://myrddin.prole.org:6443
|
||||||
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
|
||||||
KUBECTL_CONTEXT = prole-service-cluster
|
; k3s kubeconfig current-context is authoritative — do not set KUBECTL_CONTEXT here
|
||||||
|
; KUBECTL_CONTEXT = prole-service-cluster
|
||||||
MODE = k3s
|
MODE = k3s
|
||||||
PIPELINE_URL = http://127.0.0.1:8080
|
PIPELINE_URL = http://127.0.0.1:8080
|
||||||
|
|
||||||
|
|||||||
@ -128,6 +128,8 @@ GOOGLE_CLIENT_ID =
|
|||||||
GOOGLE_CLIENT_SECRET =
|
GOOGLE_CLIENT_SECRET =
|
||||||
PROLE_KDC_TRUST_REALM = PROLE.ORG
|
PROLE_KDC_TRUST_REALM = PROLE.ORG
|
||||||
PROLE_KDC_TRUST_ADMIN = administrator@PROLE.ORG
|
PROLE_KDC_TRUST_ADMIN = administrator@PROLE.ORG
|
||||||
|
; k3s has no default StorageClass; use the static prole-iscsi SC (backed by /synology/d001/kdc)
|
||||||
|
PROLE_KDC_STORAGE_CLASS = prole-iscsi
|
||||||
SERVICE_INGRESS_TLS_ENABLED = 1
|
SERVICE_INGRESS_TLS_ENABLED = 1
|
||||||
MONITORING_RELEASE = prometheus
|
MONITORING_RELEASE = prometheus
|
||||||
|
|
||||||
@ -157,11 +159,11 @@ PORT_FORWARD_K3D_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/kps-graf
|
|||||||
PORT_FORWARD_K3D_MAPPING_9 = id=supabase-kong;namespace=supabase;target=svc/kong;address=0.0.0.0;hostPort=8000;servicePort=8000;protocol=TCP;description=Supabase API (Kong)
|
PORT_FORWARD_K3D_MAPPING_9 = id=supabase-kong;namespace=supabase;target=svc/kong;address=0.0.0.0;hostPort=8000;servicePort=8000;protocol=TCP;description=Supabase API (Kong)
|
||||||
|
|
||||||
[System Environment]
|
[System Environment]
|
||||||
KNOE_CONF = /Users/chrisfu/dev/knoe/conf
|
KNOE_CONF = /home/chrisfu/dev/prole/conf
|
||||||
PROLE_DATA = /Users/chrisfu/dev/knoe/data
|
PROLE_DATA = /home/chrisfu/dev/prole/data
|
||||||
KNOE_HOME = /Users/chrisfu/dev/knoe
|
KNOE_HOME = /home/chrisfu/dev/prole
|
||||||
PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
|
PROLE_LOGS = /home/chrisfu/dev/prole/logs
|
||||||
KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
|
KNOE_SERVICE = /home/chrisfu/dev/prole/etc
|
||||||
|
|
||||||
[Monitoring]
|
[Monitoring]
|
||||||
; No configuration values captured yet for this section.
|
; No configuration values captured yet for this section.
|
||||||
|
|||||||
@ -206,6 +206,9 @@ prole_k3s_dns_records:
|
|||||||
ipv4s: [10.0.0.3, 10.0.0.6]
|
ipv4s: [10.0.0.3, 10.0.0.6]
|
||||||
- fqdn: supabase.internal.prole.org
|
- fqdn: supabase.internal.prole.org
|
||||||
ipv4s: [10.0.0.3, 10.0.0.6]
|
ipv4s: [10.0.0.3, 10.0.0.6]
|
||||||
|
# Direct postgres access (bypasses Traefik — port 5432 via CNPG ServiceLB)
|
||||||
|
- fqdn: pg.prole.org
|
||||||
|
ipv4s: [10.0.0.3, 10.0.0.6]
|
||||||
|
|
||||||
prole_k3s_cname_records:
|
prole_k3s_cname_records:
|
||||||
- fqdn: registry.prole.org
|
- fqdn: registry.prole.org
|
||||||
|
|||||||
@ -92,8 +92,9 @@ spec:
|
|||||||
- GRANT anon TO authenticator;
|
- GRANT anon TO authenticator;
|
||||||
|
|
||||||
certificates:
|
certificates:
|
||||||
serverTLSSecret: knoe-db-tls
|
serverAltDNSNames:
|
||||||
serverCASecret: knoe-db-ca
|
- pg.prole.org
|
||||||
|
- knoe-db-rw.knoe-db.svc.cluster.local
|
||||||
|
|
||||||
enableSuperuserAccess: true
|
enableSuperuserAccess: true
|
||||||
env:
|
env:
|
||||||
|
|||||||
@ -68,8 +68,23 @@ def ensure_op_signed_in() -> None:
|
|||||||
subprocess.run(["op", "signin"], check=True)
|
subprocess.run(["op", "signin"], check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _op_session_active() -> bool:
|
||||||
|
"""Return True if op has an active session."""
|
||||||
|
r = subprocess.run(["op", "whoami"], capture_output=True, text=True)
|
||||||
|
return r.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
def ensure_knoey_vault() -> None:
|
def ensure_knoey_vault() -> None:
|
||||||
"""Create the 'knoey' vault if it does not already exist."""
|
"""Create the 'knoey' vault if it does not already exist.
|
||||||
|
|
||||||
|
Skips silently when running non-interactively without an op session.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if not _op_session_active():
|
||||||
|
if not sys.stdin.isatty():
|
||||||
|
print("[WARN] No active 1Password session — skipping vault check.", flush=True)
|
||||||
|
return
|
||||||
result = _op("vault", "list", "--format", "json", check=True)
|
result = _op("vault", "list", "--format", "json", check=True)
|
||||||
try:
|
try:
|
||||||
vaults = json.loads(result.stdout or "[]")
|
vaults = json.loads(result.stdout or "[]")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user