Erste Schritte auf Kubernetes (Helm)
Das Helm-Chart unter deploy/helm/olivares stellt die Control
Plane mit denselben sicheren Standardwerten bereit wie jeder andere Pfad: ein
Core-StatefulSet (non-root, schreibgeschütztes Root-Dateisystem, alle
Capabilities entfernt), TLS aktiv, loopback-äquivalente Exposition (ein
ClusterIP-Service — nichts öffentlich, bis Sie es entscheiden) und keine
Standard-Anmeldedaten. Von dort aus aktivieren Sie optional Postgres,
Active-Passive-HA, geplante verschlüsselte DR-Backups und das
Collectors-DaemonSet für verteilten Ingest.
Alles unten wurde gegen das Chart in diesem Repository gerendert und geprüft
(helm lint + helm template, einschließlich der HA- und Backup-Konfigurationen
sowie der eigenen Schutzmechanismen des Charts). Das Chart erfordert
Kubernetes ≥ 1.25.
1. Die Standardinstallation (Single Node, SQLite)
Abschnitt betitelt „1. Die Standardinstallation (Single Node, SQLite)“-
Aus dem Checkout installieren:
Terminal-Fenster helm install olivares deploy/helm/olivaresDies rendert genau drei Workload-Objekte — ein
StatefulSet(1 Replica, SQLite auf einem persistenten 8-Gi-PVC), einenClusterIP-Service(8443 HTTPS, 8444 gRPC) und einenServiceAccountohne Kubernetes-API-Rechte. Probes treffen/readyz(Readiness — entleert, wenn der Store ausfällt oder die Replica nicht Leader ist) und/livez(Liveness — nur der Prozess, nie eine Abhängigkeit, sodass ein Store-Ausfall niemals eine Restart-Schleife verursachen kann). -
Lesen Sie das einmalige Setup-Token aus dem Pod-Log (es wird nur nach stdout ausgegeben — in Kubernetes ist das das Container-Log):
Terminal-Fenster kubectl logs -l app.kubernetes.io/component=core | sed -n '/FIRST-BOOT SETUP/,/========================/p' -
Port-Forward einrichten und das First-Run-Setup abschließen (derselbe Ablauf wie überall):
Terminal-Fenster # The Service is named <release>-olivares-core:kubectl port-forward svc/olivares-core 8443:8443curl -ksf -X POST https://127.0.0.1:8443/v1/setup \-H 'Content-Type: application/json' \-d '{"token":"<olst_ token>","email":"you@example.com","password":"<strong-password>"}'
Alternativ liefert das Repository ganz ohne Helm ein flaches Manifest mit denselben sicheren Single-Node-Standardwerten, von der CI aus dem Chart neu generiert:
kubectl apply -f deploy/manifests/install.yamlFür Argo CD / Flux / Kustomize (kustomize build --enable-helm) siehe
deploy/gitops/ — deklarative Wrapper über demselben Chart.
2. Postgres (mandantenfähig)
Abschnitt betitelt „2. Postgres (mandantenfähig)“Die Engine erfordert eine least-privilege-Datenbankrolle: LOGIN, kein
Superuser, kein BYPASSRLS — Row-Level Security ist der Mandanten-Backstop,
und die Engine verweigert den Start gegen eine privilegierte Rolle. Provisionieren
Sie die Rolle mit dem kanonischen deploy/postgres/01-app-role.sql (das Chart
kann es als Pre-Install-Job für Sie ausführen), legen Sie die DSN in ein Secret
und verweisen Sie das Chart darauf:
kubectl create secret generic olivares-pg \ --from-literal=dsn='postgres://olivares_app:***@db:5432/olivares?sslmode=verify-full' \ --from-literal=admin-dsn='postgres://olivares_admin:***@db:5432/olivares?sslmode=verify-full'
helm install olivares deploy/helm/olivares \ --set core.engine=postgres \ --set postgres.dsnSecret=olivares-pg \ --set postgres.adminDsnKey=admin-dsnDer admin-dsn-Schlüssel enthält eine dedizierte
NOSUPERUSER BYPASSRLS-Rolle. Er ist nur dann optional, wenn Sie niemals
Backups aktivieren: Er ist es, der die mandantenübergreifenden Systemlesevorgänge
vollständig macht (die Org-Liste, die mandantenübergreifende Abdeckung), und die
Aktivierung von backup erfordert ihn — siehe
§4. Ihn jetzt anzulegen bedeutet, dass der
spätere Backup-Schritt eine Änderung von einer einzigen Zeile ist.
3. Active-Passive-HA
Abschnitt betitelt „3. Active-Passive-HA“Mit Postgres als gemeinsamem Store betreiben Sie mehrere Replicas. Eine wird zum
Leader gewählt (ein Postgres Advisory Lock); Standbys beantworten /readyz mit
503 {"status":"standby"}, sodass der Service nur an den Leader routet, und ein
Standby übernimmt automatisch, wenn der Leader ausfällt.
Zwei Dinge sind strukturell erforderlich, und das Chart erzwingt beide (wir haben verifiziert, dass die Guards als harte Fehler rendern, nicht als Warnungen):
| Anforderung | Warum | Chart-Guard, falls fehlend |
|---|---|---|
| core.engine=postgres | Die SQLite-Datei ist lokal an einen Pod gebunden — sie kann kein gemeinsamer Store sein. | core.replicaCount > 1 requires core.engine=postgres … |
| core.auditSigningKeySecret | Jede Replica muss das Audit-Ledger mit dem gleichen Ed25519-Schlüssel signieren, sonst spaltet sich die Hash-Chain beim Failover. | core.replicaCount > 1 requires core.auditSigningKeySecret … |
kubectl create secret generic olivares-audit-key \ --from-file=audit-signing.key=<base64-ed25519-private-key-file>
helm install olivares deploy/helm/olivares \ --set core.engine=postgres \ --set postgres.dsnSecret=olivares-pg \ --set core.replicaCount=3 \ --set core.auditSigningKeySecret=olivares-audit-keyDie kanonischen HA-Größen sind 3 oder 5 Replicas, Active-Passive. Dieses Single-Writer-Design ist beabsichtigt (es entspricht dem Konsistenzmodell des Produkts); die Production-Readiness-Kennzahlen dokumentieren die unterstützten Verfügbarkeitsstufen.
4. Geplante verschlüsselte Backups
Abschnitt betitelt „4. Geplante verschlüsselte Backups“Das Chart liefert einen CronJob, der olivares dr backup ausführt — ein
verschlüsseltes, ledger-kontinuitätssicheres Bundle (Store-Snapshot +
Signaturschlüssel, versiegelt unter Ihrem KEK + Per-Tenant-Chain-Tip-Manifest):
kubectl create secret generic dr-kek --from-literal=passphrase='<strong passphrase>'
helm upgrade olivares deploy/helm/olivares --reuse-values \ --set backup.enabled=true \ --set backup.kekSecret=dr-kek \ --set postgres.adminDsnKey=admin-dsn # unter Postgres mit Backups PFLICHTUnter Postgres verweigert das Chart das Rendern, wenn postgres.adminDsnKey
fehlt, und das ist Absicht: Das pg_dump des Backups hält row_security=off und
bricht als Anwendungsrolle ab, sobald es Tabellen mit FORCE ROW LEVEL SECURITY erreicht. Ein CronJob, der nur an die App-DSN verdrahtet wäre, würde
also bei jedem Lauf fehlschlagen und Sie ohne Backup zurücklassen — der
harte Guard beim Rendern ist dem stillen, dauerhaft leeren Backup-Ziel vorzuziehen.
Standardwerte: alle 6 Stunden (backup.schedule legt Ihren RPO fest), 14 Tage
lokale Aufbewahrung, ein dediziertes Ziel-PVC. Spiegeln Sie das Ziel an einen
externen Standort und bewahren Sie den KEK getrennt von den Bundles auf — ein
Backup im selben Cluster ist kein Disaster Recovery. Üben Sie Restores mit
olivares dr verify; das vollständige Verfahren steht in
Backup & Restore.
5. Collectors-DaemonSet (verteilter Ingest)
Abschnitt betitelt „5. Collectors-DaemonSet (verteilter Ingest)“Für die verteilte Topologie betreibt ein Collectors-DaemonSet
Source-Connectors auf jedem Node und pusht Beobachtungen über gRPC an den
Core — Collectors haben keinen eingehenden Listener. Das Chart erfordert ein
Ingest-Token und akzeptiert optionales mTLS-Material:
helm upgrade olivares deploy/helm/olivares --reuse-values \ --set collectors.enabled=true \ --set collectors.ingestTokenSecret=olivares-ingest-token # ingest:write bearer tokenGeben Sie den Collectors ihre Sources über collectors.sourcesConfig (dasselbe
Sources-JSON wie überall), und aktivieren Sie
mTLS mit verifiziertem Client-Zertifikat für den Collector→Core-Kanal mit
tls.grpcClientCaSecret — siehe Hardening.
Monitoring
Abschnitt betitelt „Monitoring“Aktivieren Sie serviceMonitor, wenn Sie den Prometheus-Operator betreiben; in
jedem Fall stellt die Engine /metrics unauthentifiziert bereit (sie trägt keine
Mandantendaten) und das Repository liefert fertige Alert-Regeln. Siehe
Monitoring mit Prometheus.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Sources verdrahten: Eine Source verbinden und die Connector-Anleitungen.
- Fehler-Drills: Troubleshooting — Failover-Verhalten, Backpressure, Ledger-Verifizierung.
- Air-gapped-Cluster? Erste Schritte an einem Air-gapped-Standort.