Alle Artikel
Ein Prometheus für alle: zentrales Monitoring mit vCluster
Ein einziger Prometheus- und Grafana-Stack für viele isolierte Tenant-Cluster: So zentralisieren Sie Metriken in mandantenfähigem Kubernetes mit vCluster.
·
Dominik Heilbock

Hinweis: Dieser Beitrag wurde aus dem Englischen übersetzt. Fachbegriffe, Code und Befehle wurden bewusst im Original belassen.
Warum Mandantenfähigkeit nötig ist
Als Platform Engineers bauen wir gemeinsam genutzte Plattformen für mehrere Teams. Eine zentrale Entscheidung ist die Trennung der Mandanten, die häufig auf eine Aufteilung nach Namespaces mit eingeschränktem RBAC hinausläuft. Dieses Muster ist einfach umzusetzen und verursacht wenig administrativen und infrastrukturellen Aufwand. Der Preis dafür ist eine schwache Isolation und ein gemeinsamer Blast Radius, da sich alle Mandanten denselben API-Server teilen. Die Nachteile eines gemeinsamen API-Servers treten besonders deutlich zutage, wenn Teams auf Kubernetes-Operatoren wie den Prometheus Operator oder Logging-Operatoren setzen. In einem Modell mit gemeinsamem API-Server lassen sich Operatoren nur schwer isolieren, da sie typischerweise cluster-weite Ressourcen wie CRDs installieren und die Hoheit über bestimmte APIs beanspruchen. Verschiedene Teams können daher Operator-Versionen nicht unabhängig voneinander wählen. Benötigt etwa Team A den Prometheus Operator v4, während Team B auf v5 umsteigen möchte, erzwingt der gemeinsame API-Server eine einheitliche Version für alle Mandanten. Diese enge Kopplung schränkt die Autonomie der Teams ein und erschwert unabhängige Upgrade-Zyklen – ein weiteres Beispiel für die Grenzen namespace-basierter Mandantenfähigkeit. Diesen Nachteilen ließe sich begegnen, indem man jedem Mandanten einen eigenen Cluster gibt, was jedoch zu erheblichem Verwaltungsaufwand und häufig zu ungenutzten Ressourcen führt. Plattformteams wünschen sich wenig administrativen Aufwand und geringe Komplexität, Nutzer hingegen eine starke Trennung mit isolierten Quotas und Policies. Daraus entsteht meist der Zielkonflikt, dass wir ein Modell wollen, das sich für den Mandanten wie ein Cluster anfühlt und für das Plattformteam so handhabbar bleibt wie Namespaces.
Die Lücke mit vCluster schließen
vCluster stellt virtuelle Kubernetes-Cluster bereit, die innerhalb eines Host-Clusters betrieben werden und jeweils über eine eigene virtuelle Control Plane verfügen. Das bietet mehr Autonomie und Isolation als eine namespace-basierte Trennung und erfordert zugleich weniger Aufwand, als jedem Mandanten einen vollständigen Cluster zu widmen. In diesem Artikel betrachten wir zwei vCluster-Modelle: einen regulären vCluster, der Worker Nodes mit anderen Mandanten und dem Host-Cluster teilt, sowie vCluster Private Nodes, die über dedizierte Worker Nodes die Mandanten auch auf Infrastrukturebene isolieren.
Warum zentrale Metriken nötig sind
In einer mandantenfähigen Umgebung wird die Erfassung von Metriken zur Aufgabe der Plattform. Für jeden Mandanten einen eigenen Stack auszurollen, erhöht die Komplexität schnell bei geringem Nutzen, und denselben Metrik-Stack je Mandant zu betreiben, ist ressourcenintensiv. Wird dieser Stack im Host-Cluster zentralisiert, bleibt es einfach, der Ressourcenverbrauch sinkt und die Metrikerfassung wächst nicht mit der Zahl der Mandanten. Auch Debugging und Upgrades werden einfacher, da es einen einzigen zentralen Kontrollpunkt gibt. Deshalb ist dieses Muster für Plattformteams oft die erste Wahl. vCluster fügt sich hier natürlich ein: Während Mandanten ihre eigenen virtuellen Cluster betreiben, laufen die Workloads letztlich auf einem gemeinsamen Satz von Nodes im Host-Cluster.
Ziel dieses Artikels ist es, mögliche Umsetzungen für die zentrale Metrikerfassung mit vCluster aufzuzeigen.
Regulärer vCluster
Wie eingangs erläutert, bauen wir das Setup sowohl für reguläre vClusters als auch für Private Nodes auf. Beginnen wir mit den regulären. Den Code zum Nachvollziehen finden Sie in diesem GitHub-Repository unter vcluster_commands.md. Bei regulären vClusters kann der Cluster-Administrator alle Pods des vCluster im Host-Cluster sehen – ergänzt um das Suffix -<vcluster_name>. Wird also beispielsweise Falco im vCluster mit dem Namen tenant-x ausgerollt, erscheint der Pod im Host-Cluster als falco-tenant-x in dem Namespace, in dem der vCluster betrieben wird. Ein vCluster ist stets an einen Namespace im Host-Cluster gebunden. Nutzer des vCluster greifen jedoch über dessen eigene Control Plane darauf zu und sehen weder den Host-Cluster noch andere vClusters.
Für unser Metrik-Setup im Host-Cluster bedeutet das: Wir können den kube-prometheus-stack im Host-Cluster ausrollen. Das automatische Scraping funktioniert für Node-, Pod- und Container-Metriken über kubelet/cAdvisor. /metrics-Endpunkte auf Anwendungsebene erfordern weiterhin eine explizite Konfiguration, etwa über einen ServiceMonitor, PodMonitor oder Annotationen.

Für dieses Demo-Setup werden zwei vClusters in einem zentralen Minikube-Host-Cluster angelegt und darin die Google-Onlineboutique-Anwendung ausgerollt, um Metriken zu erzeugen. Der erste vCluster heißt shop1, der zweite shop2. Grafana im Host-Cluster stellt Dashboards für beide Cluster bereit, wobei Nutzer je nach Zugehörigkeit jeweils nur eines sehen. In einem Unternehmens-Setup würde man LDAP-Nutzer auf diese Berechtigungen abbilden; in dieser Demo werden zwei Grafana-Nutzer angelegt, einer je vCluster, die jeweils nur ihre eigenen Dashboards einsehen können.
Wir starten mit dem Host-Cluster und bereiten drei Namespaces vor: einen für das Monitoring und je einen pro Mandant. Auf dieser Basis installieren wir den Monitoring-Stack einmalig im Host-Cluster (Prometheus, Grafana, Alertmanager über kube-prometheus-stack). Prometheus überwacht nun den Host-Cluster und nutzt die Standard-Service-Discovery von Kubernetes, um Scrape-Ziele zu finden. Im regulären vCluster-Modell genügt das, weil die Workloads der Mandanten letztlich als gewöhnliche Kubernetes-Objekte im Host-Cluster auftauchen.
Als Nächstes werden die beiden Mandanten-vClusters (shop1 und shop2) jeweils in ihrem Host-Namespace angelegt. Jeder vCluster bringt einen eigenen API-Endpunkt und eigene Authentifizierungsdaten (kubeconfig) mit. Aus Sicht eines Mandanten wechselt das Erlebnis in diesem Moment von „gemeinsamem Plattform-Namespace” zu „meinem eigenen Cluster”. Er kann nun Namespaces anlegen, Helm-Charts ausrollen, RBAC anwenden und Workloads gegen eine Control Plane betreiben, die von anderen Mandanten isoliert ist.
Anschließend wird die Demo-Anwendung in jeden vCluster ausgerollt. Obwohl die Mandanten ihre Manifeste an ihre virtuellen API-Server übergeben, werden die tatsächlich laufenden Pods auf den gemeinsam genutzten Worker Nodes des Host-Clusters geplant und erscheinen für den Cluster-Administrator im zugehörigen Host-Namespace. Genau dieses Verhalten macht zentrales Monitoring hier so elegant: Prometheus muss sich nicht mit jeder Mandanten-Control-Plane verbinden, sondern beobachtet die Workloads schlicht dort, wo sie physisch laufen. Anders gesagt: Die Mandantentrennung erfolgt an der Grenze der Control Plane, die Observability auf der gemeinsamen Data Plane.
Sobald beide Mandanten denselben Workload betreiben, kann Grafana im Host-Cluster unmittelbar Metriken für beide anzeigen. Der verbleibende Schritt besteht darin, aus „zentraler Sichtbarkeit” eine „mandantensichere Sichtbarkeit” zu machen. In der Demo geschieht das, indem Dashboards je Mandant in einem eigenen Ordner pro vCluster organisiert und die Zugriffsrechte so eingeschränkt werden, dass jeder Mandantennutzer nur seine eigenen Dashboards sieht.

Oben sehen Sie das Beispiel-Dashboard für den vCluster shop2, das im Host-Cluster bereitgestellt wird.
Das Ergebnis: ein Monitoring-Stack im Betrieb, viele Mandanten-Cluster, die er bedient, und eine klare Aufgabentrennung. Platform Engineers verantworten Host-Cluster und Observability, Mandanten verwalten ihre Workloads über ihre vCluster-API. Auch der Kompromiss ist eindeutig: Da die Worker Nodes im regulären Modell geteilt werden, besteht keine Isolation auf Infrastrukturebene – womit wir beim nächsten Abschnitt über vCluster Private Nodes sind.
Private Nodes
Ein wesentlicher Unterschied bei Private Nodes ist, dass vCluster-Pods nicht länger über den Namespace des vCluster im Host-Cluster sichtbar sind.
Für dieses Setup kommt AWS EKS zum Einsatz, da physische Nodes erforderlich sind; zudem wird eine vCluster-Free- oder -Enterprise-Lizenz benötigt. Die Befehle zum Nachvollziehen sowie der Terraform-Code zur Erstellung des Clusters finden sich unter private_node_commands.md im GitHub-Repository.
Sobald das EKS-Fundament steht, stellt die Plattform zwei Mandanten-vClusters bereit (erneut shop1 und shop2). Entscheidend ist dabei, dass jedem vCluster bestimmte EC2-basierte Worker Nodes als Private Nodes zugewiesen werden, sodass sich die Mandanten weder untereinander noch mit dem Host-Cluster Compute teilen. Das verschärft die Isolation auf Infrastrukturebene und vermeidet viele Noisy-Neighbor- und Co-Scheduling-Probleme – bedeutet aber auch, dass der Host-Cluster keinen direkten Zugriff mehr auf die Workload-Objekte der Mandanten hat, um sie zu scrapen.
Damit kommen wir zum zentralen Monitoring: Aus betrieblicher Sicht wollen wir weiterhin einen einzigen kube-prometheus-stack, können uns aber nicht mehr darauf verlassen, dass das Host-Prometheus die Pods der Mandanten findet. Die Lösung in diesem Artikel besteht darin, einen Prometheus-Server je Mandant einzuführen:
Jeder vCluster betreibt ein minimales Prometheus, dessen Aufgabe darin besteht, innerhalb der Private-Node-Umgebung zu scrapen (wo die Pods tatsächlich sichtbar sind). Dieses mandantenspezifische Prometheus ist für Remote Writes an das zentrale Prometheus im Host-Cluster konfiguriert. Der Prometheus-Server im Host-Cluster muss dafür als Remote-Write-Empfänger aktiviert werden, über: enableRemoteWriteReceiver: true.
Damit diese Weiterleitung funktioniert, ohne den Monitoring-Stack nach außen zu öffnen, wird der Host-Prometheus-Endpunkt über einen internen Load Balancer bereitgestellt. Host-Cluster und vClusters teilen sich dieselbe VPC, sodass die Prometheus-Instanzen der Mandanten das Host-Prometheus ausschließlich über private Netzwerkpfade erreichen. Die Vorteile der Plattform bleiben bestehen – Alerting, Retention und Grafana an einem Ort – während das Setup der geringeren Sichtbarkeit von Private Nodes Rechnung trägt.

Schließlich müssen die Dashboards mandantenbezogen bleiben, auch wenn alle Metriken an das zentrale Prometheus gehen. In der Demo geschieht das bewusst einfach: Namespaces erhalten ein mandantenspezifisches Suffix (etwa -shop1 bzw. -shop2), und die Grafana-Dashboards werden auf diese Namespaces eingegrenzt. Das Muster ist leicht verständlich und für eine Demo gut geeignet. Für einen produktionsnäheren Ansatz können Sie ein einheitliches Mandanten-Label auf allen Workloads und Metriken erzwingen, etwa vcluster=<name>. Das Ergebnis spiegelt das Versprechen des Setups wider: zentrales Prometheus, Alerting und Grafana mit mandantengetrennten Sichten – bei gleichzeitiger Anerkennung der Realität von Private Nodes: Erst muss innerhalb jeder Mandantengrenze gesammelt werden, und erst danach lassen sich Metriken kontrolliert zentral aggregieren.
Eine Einschränkung bleibt: In vClusters mit Private Nodes werden Live-kubelet-Metriken der vCluster-Pods standardmäßig nicht von Prometheus gescraped. Umgehen lässt sich das, indem man diesen angepassten OTel-Collector installiert.
Die wichtigsten Erkenntnisse
Wir haben untersucht, wie sich die zentrale Metrikerfassung in mandantenfähigen Kubernetes-Plattformen mit vClusters umsetzen lässt. Kubernetes bringt zwar grundlegende Observability-Werkzeuge je Cluster mit, doch diese Metrik-Stacks für jeden Mandanten unabhängig zu skalieren, wird schnell komplex, ressourcenintensiv und schwer beherrschbar. Werden Metriken im Host-Cluster zentralisiert, entsteht ein einziger operativer Anlaufpunkt für Prometheus, Grafana und Alerting, während Mandanten weiterhin mit ihren isolierten virtuellen Clustern arbeiten. Im Artikel haben wir gezeigt, wie Mandanten-Workloads in regulären vClusters automatisch für das Prometheus des Host-Clusters sichtbar sind und wie sich Metriken in Private-Node-Setups über leichtgewichtige Prometheus-Instanzen mit Remote Write an ein zentrales Prometheus sicher je Mandant erfassen lassen. Zudem haben wir Strategien betrachtet, um die Mandantensicht in Grafana getrennt zu halten – über Ordnerstrukturen, Namenskonventionen für Namespaces und Labels. Diese Muster stellen sicher, dass Platform Engineers einen einzigen Observability-Stack effizient betreiben können, während Mandanten ein isoliertes, clusterartiges Erlebnis behalten. In einem künftigen Artikel weiten wir diese Muster auf Logs und Distributed Tracing aus und vervollständigen damit den vCluster-Observability-Stack.
Teilen