Skalierung & Betreiber
Wo du Hoppla self-hosted betreibst, von welchem Werte-Profil du startest und wie du auf mehrere Probe-Standorte wächst.
Profil wählen
| Profil | Skala | Datenschicht | Form |
|---|---|---|---|
values.self-hosted-small.yaml | ≤ ~1k Monitors | im Cluster | ein Node, je 1 Replica von allem |
values.self-hosted-medium.yaml | ~1k–10k | im Cluster, hochgezogen | 3+ Nodes, HPA auf der Check-Pipeline, PDBs |
values.self-hosted-large.yaml | > 10k | extern (deine) | autoskaliertes Serving + Workers, keine DB-/Redis-Pods |
values.self-hosted-probe.yaml | Add-on | keine (nutzt zentrale) | nur Worker, sekundäre Region |
Alle Profile überlagern die Chart-Defaults -- halte pro Cluster genau eine Kopie unter Versionskontrolle und übergib sie immer mit -f (nie --reuse-values).
Die TimescaleDB-Einschränkung (zuerst lesen)
Hoppla speichert Check-Ergebnisse in einer TimescaleDB-Hypertable. AWS RDS und GCP Cloud SQL unterstützen die TimescaleDB-Erweiterung nicht -- richtest du Hoppla auf eine dieser Datenbanken aus, scheitert es bei der Migration. Deine Optionen, geordnet nach betrieblicher Einfachheit:
- PostgreSQL im Cluster (Chart-Default, Small-/Medium-Profil) auf schnellem Block-Storage -- das ist der unterstützte Weg in der gemanagten Cloud bis ~10k Monitors. Behandle das PVC + deine
pg_dumps als Kronjuwelen. - Timescale Cloud -- gemanagtes TimescaleDB, funktioniert mit dem Large-Profil.
- Selbst betriebene Postgres-VM mit der TimescaleDB-Erweiterung.
- Azure Database for PostgreSQL Flexible Server -- das eine große gemanagte Angebot, das
timescaledbauf die Allowlist setzt.
Redis hat diese Einschränkung nicht: ElastiCache, Memorystore oder jedes Redis 7 funktioniert mit dem Large-Profil.
Provider-Hinweise
Generisches k8s / k3s / On-Prem (Referenzplattform)
Das Release ist auf reinem k8s und k3s validiert. ingress-nginx + cert-manager (HTTP-01), Default-Storage-Class, fertig. Single-Node-k3s mit dem Small-Profil ist bei kleiner Skala ein völlig brauchbares Produktiv-Setup.
Amazon EKS
- Storage: Installiere den EBS-CSI-Treiber; setze
postgresql.persistence.storageClass: gp3(undredis.persistence, wenn du Redis im Cluster lässt). - Ingress: ingress-nginx hinter einem NLB ist der Weg des geringsten Widerstands (die Annotations des Charts zielen auf nginx,
ingress.className: nginx). Der AWS Load Balancer Controller (ALB) funktioniert auch, aber dann übersetzt du die Annotations selbst, und der Custom-Domain-Provisioner erstellt nurIngress-/Certificate-Objekte -- paare ALB mitcustomDomains.provisioner: manual, außer du weißt, dass dein Controller damit umgeht. - TLS: cert-manager mit HTTP-01 durch den NLB, oder DNS-01 via Route 53 (nötig für Wildcard-Portal-Domains -- siehe White-Label & Reseller).
- DNS (lies das -- EKS unterscheidet sich von GKE/k3s): Ein NLB hat keine statische IP, nur einen DNS-Hostnamen (
...elb.<region>.amazonaws.com). Der Ingress-Service zeigt ihn unter.status.loadBalancer.ingress[0].hostname(NICHT.ip). Also:- Setze deine Einträge mit einem CNAME auf den NLB-Hostnamen, nicht mit einem A-Record auf eine IP -- die „A-Record → Ingress-IP"-Zeilen in der DNS-Tabelle unten gelten für IP-basierte LBs.
- Ein Apex
domains.app(z. B.example.com) kann kein CNAME sein -- nutze einen Route 53 Alias-Record auf den NLB oder eine Subdomain.external-dnsautomatisiert beides.
- Datenbank: RDS ist KEINE Option (siehe oben). gp3-gestütztes Postgres im Cluster oder Timescale Cloud.
- Hoppla selbst braucht keine IAM-Rollen -- es braucht nur ausgehendes Internet (Checks), SMTP und seine eigenen Datenspeicher.
Google GKE
- Storage:
premium-rwo(pd-ssd) für Postgres;standard-rworeicht für Redis. - Ingress: ingress-nginx (
ingress.className: nginx) hinter einem TCP-LB ist der validierte Weg; die eingebaute GCE-Ingress-Klasse von GKE hat andere Annotation-Semantik -- gleiche Einschränkung wie bei ALB oben. - TLS: cert-manager HTTP-01, oder DNS-01 via Cloud DNS für Wildcards.
- Datenbank: Cloud SQL ist KEINE Option (siehe oben).
- GKE Autopilot: funktioniert, aber Autopilot schreibt Resource-Requests um -- prüfe die HPA-Targets der Check-Pipeline nach dem ersten Tag mit echtem Traffic.
Azure AKS
managed-csi-premium-Storage für Postgres, ingress-nginx, cert-manager -- gleiche Form wie EKS/GKE.- Azure ist die eine Cloud, in der eine gemanagte Datenbank funktioniert: Flexible Server mit aktivierter
timescaledb-Erweiterung + Large-Profil.
DNS-Einträge, die du brauchst
Zeige alles auf die externe Adresse deines Ingress-Controllers (der Voraussetzungs-Schritt in der Installation gibt sie aus). Auf IP-basierten Load Balancern (GKE, k3s/MetalLB, Bare Metal) ist das ein A-Record auf die Ingress-IP -- du kannst mehr als einen listen (einen pro Node) für Redundanz. Auf hostnamenbasierten Load Balancern (AWS NLB/ELB) gibt es keine IP: Verwende stattdessen ein CNAME auf den LB-Hostnamen (Apex-Domains → Route 53 Alias / external-dns) und lies die „A → Ingress-IP"-Zeilen der Tabelle als „CNAME → Ingress-Hostname".
| Eintrag | Typ | Wert | Wann |
|---|---|---|---|
domains.app (z. B. monitoring.example.com) | A | Ingress-IP | immer |
*.<domains.statusRoot> (z. B. *.status.example.com) | A | Ingress-IP | wenn du Status Pages auf einer Status-Subdomain veröffentlichst |
*.<domains.portalRoot> (z. B. *.portal.example.com) | A | Ingress-IP | wenn du White-Label-Reseller-Portale betreibst |
cname.<domains.statusRoot> | A | Ingress-IP | das CNAME-Ziel, auf das Kunden ihre eigene Status-Domain zeigen (von der *.status-Wildcard oben abgedeckt) |
eine eigene Domain eines Kunden (status.client.com) | CNAME | cname.<domains.statusRoot> | vom Kunden hinzugefügt, dann im Dashboard verifiziert |
*.status und *.portal sind zweistufige Wildcards. Plain HTTP-01 kann für sie keine Zertifikate ausstellen -- nutze einen DNS-01-Issuer (siehe Konfiguration) oder Per-Host-Zertifikate. Die App-Domain allein reicht für eine einfache Single-Tenant-Installation.
Multi-Probe-Standorte
False-Positive-Pages sind der Feind: Hoppla alarmiert niemals von einem einzigen Vantage Point aus. Ein fehlgeschlagener Uptime-Check wird auf uptime-verify neu eingereiht und muss auch vom sekundären Probe fehlschlagen, bevor ein Incident geöffnet wird. Auf einem einzelnen Cluster sind beide Labels ehrlich-aber-identisch (hoppla:doctor warnt). Eine echte zweite Region sieht so aus:
ZENTRALER Cluster (eu) PROBE-Cluster (us)
┌───────────────────────────┐ ┌──────────────────────┐
│ api · scheduler · reverb │ │ worker: uptime-verify│
│ dashboard · alerts · ... │ privates │ (optional: uptime, │
│ workers: uptime, dns, ssl │◄──Netzwerk─►│ dns, ssl Pools) │
│ PostgreSQL ─ Redis │ Peering │ keine API, kein │
└───────────────────────────┘ │ Scheduler, keine DB, │
│ kein Redis │
└──────────────────────┘- Deploye das Probe-Profil in der zweiten Region:
helm install hoppla-probe <chart> -n hoppla -f values.self-hosted-probe.yamlmitconfig.DB_HOST/config.REDIS_HOST, die auf die zentralen Endpunkte zeigen, undPROBE_LOCATIONauf ein ehrliches Label gesetzt (us-east, …). - Konnektivität: Der Probe-Cluster braucht zentrales Redis (6379) und Postgres (5432). Nutze VPC-Peering, WireGuard oder Tailscale -- niemals das öffentliche Internet.
DB_SSLMODE: requireist im Profil voreingestellt. - Verschiebe den Verify-Pool: Deaktiviere auf dem ZENTRALEN Cluster seinen lokalen
uptime-verify-Pool (workers.uptime-verify.enabled: false), damit die zweite Meinung immer aus der entfernten Region kommt. Setze das zentralePROBE_SECONDARY-Env auf das Label des Probe, damit die Ergebnisse korrekt gelesen werden. - Halte Singletons zentral: genau ein Scheduler (das Profil deaktiviert ihn) und ein Alerts-Pool (ebenso) über ALLE Cluster hinweg -- ein zweiter Scheduler führt jeden Check doppelt aus; ein zweiter Alerts-Pool pagt Leute doppelt.
- Verifizieren: zentrales
hoppla:doctor(Probe-Labels nicht mehr identisch) und ein bewusster Fehler: Blockiere das Ziel eines Monitors nur aus der zentralen Region -- es sollte kein Alarm feuern, und seine Ergebnisse zeigen beide Standort-Labels.
Latenz-Toleranz: Workers bündeln ihre Schreibvorgänge; transatlantische Round-Trips zu Postgres/Redis sind für Verifikations-Workloads in Ordnung. Wenn du auch PRIMÄRE Check-Pools verschiebst (workers.uptime.enabled: true auf dem Probe), halte die Queue-Latenz unter ~100 ms, sonst sinkt der Durchsatz spürbar.
Skalierungs-Stellschrauben (in der Reihenfolge, in der du sie anfasst)
workers.uptime.replicaCount/ dessen HPA -- der Durchsatz der Check-Pipeline.UPTIME_BATCH_SIZE(Per-Worker-Env) -- mehr Checks pro Batch-Job, mehr Speicher pro Prozess.redis.maxmemory-- die Queues leben hier. INVARIANTE:resources.limits.memory >= 2 × maxmemory + 64Mi(BGSAVE-Fork-Reserve; das Chart verweigert das Rendern von Verstößen).- PostgreSQL-Ressourcen + Storage-IOPS -- Check-Result-Schreibvorgänge sind die Hauptlast der DB; bevorzuge schnellere Disks über mehr CPU.
api.replicaCount/ HPA -- nur, wenn Dashboard-/API-Latenz, nicht der Check-Durchsatz, der Flaschenhals ist.- Niemals den
schedulerskalieren (ein einziger Dispatcher per Design) und denalerts-Pool nie in mehr als einem Cluster laufen lassen.