🧩 System Design Cases Lektion 4/18 ~8 Min. Experte

Case: Multi-Tenant K8s Platform (50 Teams)

Shared Cluster, Namespace Isolation, Self-Service.

📝 Meine Notizen

Lernziele

Nach dieser Lektion kannst du den Klassiker unter den Platform-Cases durchspielen: eine Multi-Tenant-Kubernetes-Plattform für 50 Teams auf gemeinsamen Clustern. Du kennst die Isolationsstufen von Namespace bis dediziertem Cluster, kannst Self-Service-Provisionierung ohne Ticket-Prozess designen und hast Antworten auf die Standard-Einwände zu Noisy Neighbors, Cluster-Upgrades und Control-Plane-Isolation parat.

Das Szenario

„Designe eine Kubernetes-Plattform für 50 Entwicklungsteams. Jedes Team soll sich Umgebungen selbst provisionieren können. Das Budget erlaubt keinen Cluster pro Team.” Dieser Case ist deshalb so beliebt, weil er das Kerndilemma des Platform Engineering in einem Satz enthält: Shared Infrastructure spart Geld und Betriebsaufwand, erzeugt aber Isolations- und Fairness-Probleme. Der Interviewer will sehen, ob du die Isolationsstufen kennst, sie nach Bedarf statt nach Maximalprinzip auswählst — und ob Self-Service bei dir mehr ist als ein Buzzword.

Anforderungen klären: die Fragen, die das Design kippen

Deine ersten Fragen entscheiden, welche Plattform du baust. Diese fünf solltest du stellen, mit der jeweiligen Konsequenz im Kopf:

  • „Wie groß sind die Teams, wie viele Services insgesamt?” — Angenommen: 50 Teams, ~200 Entwickler, ~500 Microservices. Das ergibt grob 500 Services × 3 Umgebungen × 2–3 Replicas ≈ 3.000–4.500 Pods. Wichtig für die Schlussfolgerung: Das ist für moderne Kubernetes-Cluster kein Kapazitätsproblem — die eigentliche Designfrage ist Isolation, nicht Skalierung.
  • „Welche Isolationsanforderungen gibt es — reicht logische Trennung, oder verlangt Compliance harte Grenzen?” — Angenommen: SOC-2-Audit, Netzwerk-Isolation zwischen Teams Pflicht, aber keine regulatorische Vorgabe für physisch getrennte Cluster. Das erlaubt Shared Cluster mit Namespace-Isolation.
  • „Wie homogen sind die Workloads?” — Wenn drei Teams GPU-Training fahren und eines PCI-Daten verarbeitet, brauchen die Sonderbehandlung. Angenommen: überwiegend Standard-Web-Workloads.
  • „Was heißt Self-Service konkret — was sollen Teams ohne Plattform-Team tun können?” — Angenommen: Namespace mit Quota anlegen, deployen, Logs/Metriken sehen. Cluster-weite Änderungen bleiben beim Plattform-Team.
  • „Cloud und Bestand?” — Angenommen: AWS mit EKS, GitHub vorhanden.

Fasse zusammen: „Shared EKS-Cluster, harte Netzwerk- und Quota-Isolation pro Team, Self-Service für Namespaces und Deployments — einverstanden?”

Architektur: Isolationsstufen bewusst wählen

Das Rückgrat der Antwort ist eine Isolations-Leiter, die du explizit machst — denn die Wahl der Stufe ist die zentrale Entscheidung:

  1. Namespace pro Team und Umgebung (z. B. team-checkout-prod): logische Trennung, RBAC-Grenze, Quota-Grenze. Reicht für die große Mehrheit.
  2. Node-Isolation via Taints/Tolerations oder dedizierte Node Pools: für Workloads mit Sonderanforderungen (GPU, Compliance), ohne neuen Cluster.
  3. Virtuelle Cluster (z. B. vCluster): eigene Control Plane pro Tenant im Shared Cluster — für die wenigen Teams, die CRDs installieren oder eigene Operatoren betreiben wollen.
  4. Dedizierter Cluster: die teuerste Stufe, reserviert für harte regulatorische Anforderungen.

Empfehlung im Case: Stufe 1 als Default, Stufe 3 als Escape Hatch — und das laut begründen: „Ich starte mit Namespaces, weil 45 von 50 Teams nie eine eigene Control Plane brauchen werden. vCluster halte ich als dokumentierten Ausnahmepfad bereit, statt für alle die teuerste Isolation zu bezahlen.”

Cluster-Layout: drei Cluster nach Umgebung (prod, staging, dev), nicht nach Teams. Das begrenzt den Blast Radius von Cluster-Upgrades und erlaubt, Änderungen durch dev und staging zu promoten, bevor sie prod erreichen.

Die Self-Service-Mechanik ist der zweite Schwerpunkt. Der Fluss: Team stellt im Portal (z. B. Backstage) einen Namespace-Request → das erzeugt einen Pull Request in einem Tenants-Git-Repo → nach Merge legt GitOps (Argo CD) den Namespace an → eine Policy-Engine (Kyverno) generiert beim Anlegen automatisch die Pflicht-Ausstattung: default-deny NetworkPolicy, ResourceQuota, LimitRange, RBAC-Bindings auf die Team-Gruppe aus dem Identity Provider. Der entscheidende Satz dazu: „Isolation entsteht bei mir nicht durch Disziplin, sondern durch Automatik — kein Namespace kann ohne Quota und NetworkPolicy existieren, weil die Policy-Engine sie generiert.”

Für Fairness auf den Nodes: ResourceQuotas begrenzen Teams, LimitRanges erzwingen Requests pro Pod, damit der Scheduler ehrlich rechnen kann. Observability mit Tenant-Label (team=...) auf allen Metriken und Logs, damit jedes Team nur seine Daten sieht und du Showback/Chargeback ermöglichen kannst.

Einwände des Interviewers

„Team A frisst CPU — was passiert mit Team B?” Der Noisy-Neighbor-Klassiker. Antwort in Schichten: ResourceQuota deckelt das Team-Gesamtbudget; LimitRange erzwingt Requests, sodass der Scheduler nicht überbucht; für garantierte Leistung kritischer Workloads QoS-Klasse Guaranteed (Requests = Limits). Ehrliche Restgrenze nennen: Gegen Sättigung geteilter Ressourcen wie Node-Netzwerk oder Disk-I/O helfen Quotas nur begrenzt — wer das braucht, bekommt Stufe 2, dedizierte Nodes.

„Was ist beim Cluster-Upgrade — 50 Teams gleichzeitig betroffen?” Ja, das ist der Preis des Shared Clusters, und genau deshalb drei Cluster nach Umgebung: Upgrade läuft zuerst durch dev, dann staging, dann prod, mit Soak-Time dazwischen. Plus: API-Deprecation-Checks vor dem Upgrade und PodDisruptionBudgets der Teams als Schutz beim Node-Draining.

„Warum nicht gleich vCluster für alle?” Kosten und Komplexität: 50 virtuelle Control Planes sind 50 zusätzliche bewegliche Teile, die das Plattform-Team betreiben muss — für ein Bedürfnis, das die meisten Teams nicht haben. Isolation nach Bedarf, nicht nach Maximalprinzip.

„Ein Team braucht einen eigenen Operator mit Cluster-weiten CRDs.” Genau der Fall für den Escape Hatch: vCluster für dieses Team, oder das Plattform-Team adoptiert den Operator als Shared Service, wenn mehrere Teams ihn brauchen. Wichtig ist, dass der Ausnahmepfad definiert ist, bevor der erste Ausnahmefall eintritt.

Praxis

Spiele den Case 45 Minuten am Whiteboard komplett durch, laut und mit Timer. Diese fünf Punkte müssen vorkommen:

  1. Fünf Klärungsfragen inklusive der Isolations- und Compliance-Frage, mit lauter Zusammenfassung am Ende.
  2. Die Pod-Abschätzung (Services × Umgebungen × Replicas) und die daraus abgeleitete Aussage „Isolation ist das Problem, nicht Kapazität”.
  3. Die Isolations-Leiter mit vier Stufen und einer begründeten Default-Wahl.
  4. Der komplette Self-Service-Fluss vom Portal-Request bis zum fertig ausgestatteten Namespace — als erzählter Datenfluss.
  5. Die Noisy-Neighbor-Antwort in Schichten, inklusive der ehrlichen Grenze bei Netzwerk- und Disk-I/O.

Wiederhole den Case nach einigen Tagen mit geänderter Vorgabe — „Compliance verlangt harte Trennung für 5 der 50 Teams” — und beobachte, wie sich dein Design verschiebt.

Typische Stolperfallen

Pro Team ein Cluster vorschlagen, obwohl die Aufgabe es ausschließt. Die Budget-Einschränkung steht in der Aufgabenstellung; wer sie überhört, hat Phase 1 des Frameworks übersprungen.

Namespace-Isolation als absolut verkaufen. Namespaces trennen logisch, aber alle Pods teilen Kernel und Nodes. Wer auf Nachfrage nicht weiß, dass Container-Escape-Szenarien oder Kernel-Exploits Namespace-Grenzen ignorieren, wirkt schnell oberflächlich. Die ehrliche Formel: Namespaces + NetworkPolicy + Quotas decken den Normalfall; für feindliche Tenants braucht es stärkere Grenzen.

Self-Service ohne Guardrails. „Teams können sich Namespaces anlegen” ohne automatische Quota- und Policy-Generierung ist ein Incident-Generator. Self-Service und Guardrails immer im selben Atemzug nennen.

Die Plattform-Komponenten selbst vergessen. Argo CD, Kyverno und der Monitoring-Stack laufen auch im Cluster — wer sie nicht in eigene, geschützte Namespaces mit eigener Kapazität legt, hat den wichtigsten Tenant übersehen: das Plattform-Team.

Interview-Vorbereitung

Deine Kernbotschaft: Shared Cluster mit Namespace-Isolation als Default, eine explizite Isolations-Leiter für Sonderfälle, Self-Service über Portal → Git → GitOps, und Guardrails, die per Policy-Engine automatisch entstehen statt per Konvention.

Rechne mit diesen Follow-ups:

  • „Namespace oder Cluster pro Team?” — Namespace als Default (Kosten, Betriebsaufwand, Upgrade-Zentralisierung), Cluster nur bei harten regulatorischen Grenzen; dazwischen Node Pools und vCluster.
  • „Wie verhinderst du, dass ein Team den Cluster lahmlegt?” — ResourceQuota pro Namespace, LimitRange für Pod-Defaults, PriorityClasses für Plattform-Komponenten — und zugeben, wo die Grenzen liegen.
  • „Wie funktioniert das Onboarding eines neuen Teams konkret?” — Portal-Template → PR ins Tenants-Repo → Review/Merge → Argo CD legt Namespaces an → Kyverno generiert NetworkPolicy, Quota, RBAC → Team kann in Minuten deployen.
  • „Was würdest du bei 500 statt 50 Teams ändern?” — Mehrere Shared Cluster als Zellen (Sharding), Teams auf Zellen verteilen, Cluster-Provisionierung selbst automatisieren — die Namespace-Mechanik pro Zelle bleibt gleich.

Zusammenfassung

Der Multi-Tenant-Case prüft, ob du Isolation als Spektrum begreifst: Namespaces mit automatisch generierten NetworkPolicies, Quotas und RBAC als Default, dedizierte Nodes und vCluster als abgestufte Escape Hatches, Cluster-Trennung nach Umgebung statt nach Team. Self-Service heißt Portal → Git → GitOps mit Guardrails aus der Policy-Engine — Sicherheit durch Automatik, nicht durch Disziplin. In der nächsten Lektion weitet sich der Blick: Statt einer Kubernetes-Plattform designst du eine komplette Internal Developer Platform für 500 Entwickler — von Golden Paths bis zur Frage, wie man Adoption misst.