Skip to content

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 ​

ProfilSkalaDatenschichtForm
values.self-hosted-small.yaml≤ ~1k Monitorsim Clusterein Node, je 1 Replica von allem
values.self-hosted-medium.yaml~1k–10kim Cluster, hochgezogen3+ Nodes, HPA auf der Check-Pipeline, PDBs
values.self-hosted-large.yaml> 10kextern (deine)autoskaliertes Serving + Workers, keine DB-/Redis-Pods
values.self-hosted-probe.yamlAdd-onkeine (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:

  1. 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.
  2. Timescale Cloud -- gemanagtes TimescaleDB, funktioniert mit dem Large-Profil.
  3. Selbst betriebene Postgres-VM mit der TimescaleDB-Erweiterung.
  4. Azure Database for PostgreSQL Flexible Server -- das eine große gemanagte Angebot, das timescaledb auf 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 (und redis.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 nur Ingress-/Certificate-Objekte -- paare ALB mit customDomains.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-dns automatisiert 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-rwo reicht 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".

EintragTypWertWann
domains.app (z. B. monitoring.example.com)AIngress-IPimmer
*.<domains.statusRoot> (z. B. *.status.example.com)AIngress-IPwenn du Status Pages auf einer Status-Subdomain veröffentlichst
*.<domains.portalRoot> (z. B. *.portal.example.com)AIngress-IPwenn du White-Label-Reseller-Portale betreibst
cname.<domains.statusRoot>AIngress-IPdas CNAME-Ziel, auf das Kunden ihre eigene Status-Domain zeigen (von der *.status-Wildcard oben abgedeckt)
eine eigene Domain eines Kunden (status.client.com)CNAMEcname.<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           │
                                            └──────────────────────┘
  1. Deploye das Probe-Profil in der zweiten Region: helm install hoppla-probe <chart> -n hoppla -f values.self-hosted-probe.yaml mit config.DB_HOST / config.REDIS_HOST, die auf die zentralen Endpunkte zeigen, und PROBE_LOCATION auf ein ehrliches Label gesetzt (us-east, …).
  2. Konnektivität: Der Probe-Cluster braucht zentrales Redis (6379) und Postgres (5432). Nutze VPC-Peering, WireGuard oder Tailscale -- niemals das öffentliche Internet. DB_SSLMODE: require ist im Profil voreingestellt.
  3. 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 zentrale PROBE_SECONDARY-Env auf das Label des Probe, damit die Ergebnisse korrekt gelesen werden.
  4. 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.
  5. 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) ​

  1. workers.uptime.replicaCount / dessen HPA -- der Durchsatz der Check-Pipeline.
  2. UPTIME_BATCH_SIZE (Per-Worker-Env) -- mehr Checks pro Batch-Job, mehr Speicher pro Prozess.
  3. redis.maxmemory -- die Queues leben hier. INVARIANTE: resources.limits.memory >= 2 × maxmemory + 64Mi (BGSAVE-Fork-Reserve; das Chart verweigert das Rendern von Verstößen).
  4. PostgreSQL-Ressourcen + Storage-IOPS -- Check-Result-Schreibvorgänge sind die Hauptlast der DB; bevorzuge schnellere Disks über mehr CPU.
  5. api.replicaCount / HPA -- nur, wenn Dashboard-/API-Latenz, nicht der Check-Durchsatz, der Flaschenhals ist.
  6. Niemals den scheduler skalieren (ein einziger Dispatcher per Design) und den alerts-Pool nie in mehr als einem Cluster laufen lassen.