Alle Artikel
Multi-Tenancy-Muster – und welches das richtige für Sie ist
Zwischen einem Namespace pro Mandant und einem dedizierten Cluster liegt ein ganzes Spektrum an Isolationsmustern in Kubernetes – dieser Beitrag geht sie durch.
·
Dominik Heilbock

Hinweis: Dieser Beitrag wurde aus dem Englischen übersetzt. Fachbegriffe, Code und Befehle wurden bewusst im Original belassen.
Namespaces
Ein Namespace ist ein Mechanismus, um Ressourcen innerhalb eines einzelnen Clusters zu gruppieren. Über RoleBindings, die eine Rolle auf einen bestimmten Namespace begrenzen, sowie über Network Policies und Quotas lassen sich Isolationsmechanismen und Limits ergänzen. Namespaces sind sehr günstig und einfach – und da sie Kubernetes-nativ sind, versteht sie bereits jeder Controller
Einige Kernprobleme beim Einsatz von Namespaces je Mandant sind:
Cluster-weite Objekte werden geteilt. So liegen etwa
CustomResourceDefinition,ClusterRoleoderPersistentVolumesowie Admission-Webhook-Konfigurationen außerhalb jedes Namespace. Installiert Mandant A eine CRD mit derselben Group/Version, die Mandant B in einem anderen Schema benötigt, entsteht ein Konflikt ohne jede rettende Grenze. Das ist die größte strukturelle Einschränkung namespace-basierter Mandantenfähigkeit: Es gibt keine Möglichkeit, zwei Mandanten in einem Cluster unterschiedliche Versionen derselben CRD zu geben.API-Server, etcd, Scheduler und kubelet werden geteilt. Ein Mandant, der es schafft, den API-Server zu überlasten, beeinträchtigt alle. Es gibt keinen API-Server je Mandant.
Fehlende Netzwerksegmentierung. Ohne ein CNI, das Network Policies unterstützt, existiert keine Netzwerkgrenze zwischen Namespaces – Pods können über sie hinweg kommunizieren.
Nodes werden über Namespaces hinweg geteilt. Solange man Teams nicht per Taints und Tolerations an Nodes bindet, besteht nicht nur ein Noisy-Neighbor-Risiko: Bricht ein Angreifer auf den darunterliegenden, gemeinsam genutzten Node aus, lassen sich Durchsetzungen auf Namespace-Ebene theoretisch umgehen.
Namespaces eignen sich daher gut für interne Teams innerhalb derselben Vertrauensgrenze, bei denen globale Ressourcen nicht je Mandant unterschiedlich sein müssen. Für ein gewisses Maß an Sicherheit empfiehlt es sich, Rollen an Namespaces zu binden, nach Möglichkeit Network Policies und Quotas einzusetzen und für weitergehende Durchsetzung eine externe Policy Engine zu nutzen. Zudem ist das Anlegen eines neuen Namespace eine Cluster-Operation – und sofern Sie Teams nicht die Rechte geben wollen, Namespaces anzulegen und ResourceQuotas anzupassen, wird das schnell zum Flaschenhals.
Ein Cluster je Mandant
Alternativ lässt sich jedem Mandanten ein vollständig getrennter Kubernetes-Cluster geben – mit eigenem API-Server, eigenem etcd und eigenen Nodes. Das beseitigt die meisten der genannten Probleme der Namespace-Isolation, bringt aber eigene Nachteile mit sich.
Verdopplung von Komponenten. Control Plane und Kernkomponenten wie der Monitoring-Stack oder das CNI werden dupliziert. Das erhöht die Kosten und wird im großen Maßstab zunehmend komplex zu verwalten.
Kein Ressourcen-Sharing zwischen Mandanten. Die ungenutzte Kapazität eines ruhigen Mandanten lässt sich nicht vom Cluster eines ausgelasteten Mandanten mitnutzen. Sie überdimensionieren entweder jeden Cluster oder nehmen eine schlechte Auslastung in Kauf.
Fleet Management wird zur eigenen Disziplin. Bevor Sie Cluster für Mandanten anlegen, sollten Sie ein System aufbauen, um sie zentral zu verwalten und Drift möglichst gering zu halten.
Dedizierte Cluster je Mandant sind sinnvoll, wenn Mandanten strikte Isolation benötigen. In diesen Fällen brauchen Sie zunächst eine belastbare Fleet-Management-Architektur, etwa über ein Hub-and-Spoke-Modell mit ClusterAPI, deren Aufbau erhebliche Zeit erfordert. Bedenken Sie außerdem: Solange Netzwerkverkehr zwischen Clustern möglich ist, sind Mandanten nie wirklich isoliert.
vCluster: virtuelle Control Planes innerhalb eines Host-Clusters
vCluster liegt zwischen Namespaces und vollständigen Clustern. Die Grundidee: Jedem Mandanten eine Kubernetes-Control-Plane mit eigenem API-Server geben und diese Control Plane als Workload innerhalb eines Namespace eines gemeinsam genutzten Host-Clusters betreiben. Die Control Plane eines vCluster läuft in einem StatefulSet-Pod. Aus Sicht des Host-Clusters ist das schlicht ein Pod in einem Namespace. Der sogenannte Syncer beobachtet Objekte, die innerhalb des virtuellen Clusters entstehen, und übersetzt sie in echte Objekte im Namespace des Host-Clusters, damit sie tatsächlich geplant und ausgeführt werden können. Entscheidend ist: Höherwertige Ressourcen verlassen den virtuellen Cluster nie. Ein `Deployment`, ein `StatefulSet` oder eine CRD, die Sie innerhalb des vCluster installieren, existiert nur im virtuellen API-Server bzw. Datastore. Der API-Server des Host-Clusters bekommt sie nie zu sehen. Genau das verschafft Mandanten echte Autonomie bei CRDs und Admission Control, ohne dass sie Cluster-Admin auf dem Host benötigen. Auch für die Isolation auf Compute-Ebene hat vCluster eine Antwort, denn es kennt mehrere Node-Modelle. Shared Nodes: Mandanten-Workloads laufen als reguläre Pods auf dem gemeinsamen Node Pool des Host-Clusters. Mit Private Nodes lassen sich Cluster in einer 1:1-Beziehung auf Nodes abbilden, sodass sich stets nur ein Mandant auf einem Node befindet. Darüber hinaus erhält jeder virtuelle Cluster standardmäßig ein eigenes CoreDNS, sodass die Service Discovery im Cluster aus Mandantensicht normal funktioniert.
Allerdings hat vCluster auch Nachteile:
Die Compute-Isolation ist nur so stark wie das zugrundeliegende Node-Modell. Im standardmäßigen Shared-Nodes-Modus ist ein „Mandant" weiterhin nur eine Frage von Linux-cgroups und -Namespaces auf einem gemeinsamen Kernel – also dieselbe Isolationsstärke wie bei einfachen Namespaces. Für spürbar stärkere Compute-Isolation wechselt man zu Private Nodes, was das Argument der effizienten Ressourcenteilung abschwächt.
Der Control-Plane-Overhead je Mandant summiert sich. Jeder vCluster ist ein eigener API-Server- plus Datastore-Prozess, der CPU- und Speicherreserven braucht, aktualisiert werden muss und unabhängig vom Host selbst Probleme bekommen kann (etcd-/SQLite-Korruption, OOMs im API-Server). Hunderte vClusters zu betreiben bedeutet, Hunderte kleiner Control Planes zu überwachen.
Nicht alle Ressourcen und Funktionen lassen sich sauber virtualisieren. Bestimmte Operatoren, die cluster-weiten Zustand verwalten (Service Meshes, manche CNIs, cert-manager ClusterIssuer), virtualisieren schlecht und müssen häufig ausschließlich auf Host-Ebene leben – worüber Mandanten dann keine Kontrolle haben.
Der Host-Cluster bleibt ein Single Point of Compromise. Wird die Control Plane des Host-Clusters kompromittiert oder ist dessen RBAC fehlkonfiguriert, kann ein Angreifer potenziell auf die synchronisierten Ressourcen sämtlicher vClusters zugreifen, da sie alle im etcd des Hosts liegen. Legt etwa ein Entwickler in
vcluster-teamBein Secret mit einem Datenbankpasswort an, spiegelt der Syncer von vCluster es als reales Objekt in den Namespacehost-ns-teamBdes Host-Clusters. Verfügt jemand auf dem Host über eine breite, cluster-weit gebundene ClusterRole wieget/list secrets, kann diese Person nunkubectl get secret db-password -n host-ns-teamB -o yamlausführen und die Zugangsdaten von Team B direkt vom Host lesen – obwohl sie keinerlei Zugriff aufvcluster-teamBselbst hat und das vCluster-RBAC von Team B ihr den Zugriff verweigert hätte.
vCluster eignet sich gut für Plattformen, die Mandanten echte CRD- und Operator-Installationen ermöglichen müssen – oder allgemeiner: Isolation auf Ebene des API-Servers. Es erlaubt außerdem, gemeinsame Komponenten wie Observability im Host-Cluster zu betreiben und so Overhead zu reduzieren. Zu bedenken ist auch, dass alle Mandanten weiterhin im selben Host-Cluster leben und es stets potenzielle Ausbruchsvektoren aus einem vCluster gibt.
Capsule
Capsule schlägt eine andere Richtung ein als vCluster. Es gibt Mandanten keine eigene Control Plane innerhalb eines Host-Clusters, sondern macht Namespace-Grenzen besser für Mandantenfähigkeit geeignet – über eine Custom Resource Tenant, die Namespaces gruppiert und Policies auf sie herunterreicht. Sie installieren den Capsule-Controller (ein einzelnes Deployment plus einen Satz CRDs: Tenant, CapsuleConfiguration, GlobalTenantResource, TenantResource, ProxySettings). Cluster-Administratoren legen je Team oder Kunde ein Tenant-Objekt an und benennen Owner. Tenant Owner können anschließend selbst Namespaces anlegen, die automatisch ihrem Tenant zugeordnet werden – ohne Zutun eines Cluster-Administrators. Alles, was auf Tenant-Ebene definiert ist, wird automatisch von jedem Namespace dieses Tenants geerbt. Über Admission Rules lassen sich Policies auf Tenant-Objekten durchsetzen, etwa erlaubte Image-Registries, verbotene Security Contexts oder Vorlagen für Network Policies.
Um Namespace-Leakage zu verhindern, implementiert Capsule den Capsule Proxy: einen Reverse Proxy, über den sich Mandanten authentifizieren, statt direkt auf den API-Server zuzugreifen. Er filtert cluster-weite list- und watch-Anfragen wie kubectl get namespaces auf jene Objekte herunter, die dem anfragenden Mandanten gehören. Da Capsule nur aus einem Controller und wenigen CRDs besteht, ist es sehr leichtgewichtig und führt außer Tenants keine neue Abstraktion ein. Allerdings bleibt Capsule eine namespace-basierte Isolation – lediglich für Skalierung verbessert. Capsule gibt Mandanten keinen eigenen API-Server und erbt damit sämtliche Einschränkungen aus Abschnitt 1: keine CRD-Versionen je Mandant, keine Isolation cluster-weiter Ressourcen über das hinaus, was der Capsule Proxy beim Lesen filtert, und ein gemeinsamer Blast Radius auf dem realen API-Server bzw. etcd.
Es eignet sich gut für Plattformteams, denen die Isolationsstärke auf Namespace-Ebene genügt, die aber Self-Service-Provisionierung von Namespaces, mandantenbezogene Policy-Vererbung und eine „nur meine Namespaces"-Sicht benötigen.
Vergleich auf einen Blick
Dimension | Namespaces | Cluster je Mandant | vCluster | Capsule |
Isolationseinheit | Namespace | Gesamter Cluster | Virtuelle Control Plane (Pod) | Tenant (Gruppe von Namespaces) |
CRDs / API-Isolation je Mandant | Nein | Ja | Ja | Nein |
Control Plane je Mandant | Nein | Ja | Ja (virtuell) | Nein |
Compute-/Kernel-Isolation | Geteilt | Vollständig | Abhängig vom Node-Modus (shared/private) | Geteilt |
Bereitstellungsgeschwindigkeit | Sekunden | Mehrere zehn Minuten | Sekunden bis Minuten | Sekunden |
Betrieblicher Aufwand | Gering | Hoch | Mittel | Gering |
Governance / Reifegrad | Upstream-Kubernetes | Upstream-Kubernetes | Single-Vendor-OSS + kommerzielle Schicht | CNCF Sandbox |
Größte strukturelle Lücke | Keine Isolation von CRDs / cluster-weiten Ressourcen | Kosten & Cluster-Wildwuchs | Der Syncer kann nicht alles verlustfrei übersetzen | Teilt sich weiterhin eine Control Plane |
Wie Sie wählen
Aus der Praxis haben sich einige Entscheidungsheuristiken bewährt:
Wenn es eine kleine Zahl von „Mandanten" gibt, die interne Teams mit gegenseitigem Vertrauen sind und lediglich eine Trennung nach Umgebung oder Anwendung benötigen: Namespaces plus RBAC, ResourceQuota, NetworkPolicy und PSA können ausreichen.
Wenn Mandanten eigene Operatoren bzw. CRDs installieren müssen, Sie ihnen aber keine Cluster-Admin-Rechte geben wollen und Ihnen eine Compute-Isolation mit gemeinsamem Kernel genügt: vCluster ist die direkteste Antwort – besonders für kurzlebige Umgebungen (PR-Previews, CI, Sandboxes), bei denen schneller Abbau wichtiger ist als gehärtete Isolation.
Wenn Ihnen die Isolation auf Namespace-Ebene zusagt, Sie es aber leid sind, RBAC, Quotas und Policies je Namespace manuell zu verdrahten, und Mandanten Namespaces innerhalb von Leitplanken selbst anlegen sollen: Capsule ist der Weg mit dem geringsten Overhead – und verhindert zugleich Namespace-Leakage.
Wenn Ihre Mandanten externe Kunden sind, regulierte Workloads betreiben oder eine starke Trennung benötigen, sind separate Cluster je Mandant der bewährteste Weg – gepaart mit zentralisiertem, automatisiertem Cluster-Management, um den betrieblichen Aufwand im Griff zu behalten.
Zusammenfassung
Dieser Blogbeitrag hat mehrere Multi-Tenancy-Optionen verglichen und aufgezeigt, worin sie sich unterscheiden und wo sie jeweils sinnvoll sind. Diese Abwägungen in der eigenen Umgebung zu treffen, ist nicht immer einfach – die richtige Wahl hängt von Ihrer Teamstruktur, Ihren Sicherheitsanforderungen und Ihrer betrieblichen Reife ab. Wenn Sie Multi-Tenancy-Strategien bewerten oder eine Kubernetes-Plattform für Ihre Organisation aufbauen: Wir sind auf Platform Engineering und Kubernetes-Mandantenfähigkeit spezialisiert. Sprechen Sie uns an, wenn Sie Unterstützung dabei möchten, den passenden Ansatz für Ihr Setup zu finden.
Teilen