Design-Patterns der Interaktion zwischen den openEduSuite-Komponenten
Eine Plattform wie openEduSuite ist kein Einzelprodukt, sondern ein Ökosystem aus Diensten: Groupware, Dateispeicher, LMS, Videokonferenz, Identity, E-Mail. Wie diese Teile miteinander sprechen, entscheidet über den Nutzen der Plattform. Dieser Beitrag beschreibt die wiederkehrenden Design-Patterns der Komponenten-Interaktion; jede Aussage ist im Repository belegt.
Die Muster sind nicht openEduSuite-spezifisch; sie beantworten eine konkrete Frage: Wie lässt man viele eigenständige, teils fremd gepflegte Open-Source-Dienste so zusammenarbeiten, dass sie wie ein Produkt wirken? Vier Grundprinzipien tragen die Antworten: eine Quelle der Wahrheit für Identität, eine für Konfiguration, DNS als Vertrag statt IP-Adressen und explizite Schnittstellen zwischen Namespaces.
1. Die SSO-Kette als Integrationsmuster
Das Fundament aller Komponenten-Interaktion ist eine einzige Identitätsquelle. In openEduSuite übernimmt diese Rolle Keycloak, das als zentraler Identity Broker fungiert: gegenüber der Föderation spricht es SAML 2.0, gegenüber den eigenen Diensten OpenID Connect (OIDC). Diese Doppelrolle ist der architektonische Schlüssel — sie erlaubt es, nach außen mit der deutschen Hochschul-Identitätsföderation DFN-AAI (und über sie eduGAIN) zu sprechen, während alle internen Dienste nur eine moderne, einheitliche Schnittstelle sehen. Die vollständige Architektur ist in content/de/architecture/identity-authentication.md dokumentiert.
Wichtig ist die Richtung einer Kette: Der Nutzer authentifiziert sich genau einmal an seinem Heimat-IdP, Keycloak stellt daraufhin einen OIDC-Token aus, und jeder Dienst validiert nur noch diesen Token. Kein Dienst hält ein zweites Passwort, keiner kennt die Föderation direkt.
Zwei Protokollwege zur Aufnahme eines Dienstes haben sich etabliert:
- Natives OIDC für Dienste mit eigener OIDC-Unterstützung (Nextcloud, OpenProject, JupyterHub über
GenericOAuthenticator, Open WebUI), die direkt auf die Keycloak-Endpunkte zeigen — im Code der Collab-Services unterhelmfile/dokumentiert und im Artikelcontent/de/blog/collab-services-scientific-tools.md. - oauth2-proxy-Sidecar für Dienste ohne eigene OIDC-Fähigkeit. Ein Reverse-Proxy-Sidecar wird in denselben Pod injiziert, fängt den HTTP-Verkehr auf Port 4180 ab, leitet nicht authentifizierte Nutzer zu Keycloak weiter und proxyt authentifizierte Anfragen an den lokalen Anwendungs-Container. Dieses Muster wird für RStudio, ttyd, Slidev und das Collab Dashboard verwendet.
Der Sidecar-Ansatz ist der pragmatische Weg, eine Legacy- oder minimale Anwendung in das SSO-Ökosystem aufzunehmen, ohne sie umzuschreiben. Er verlagert die Authentifizierung an den Rand des Pods statt in die Anwendung. Einzelheiten der Kette Dienst → oauth2-proxy → Keycloak → SAML-IdP, stehen im Abschnitt „Single Sign-On-Architektur" des Collab-Services-Artikels.
Für die betriebliche Praxis bei den Secrets dieser Kette gilt das GitOps-Prinzip von Abschnitt 4: OIDC-Client-Secrets werden wie alle anderen kritischen Geheimnisse behandelt und gehören nicht im Klartext in Git (siehe content/de/blog/sops-secret-management-argocd-cmp.md, Priorität P1).
2. Der Reverse-Proxy als Fraktalmuster
Ein zweites, auffälliges Muster ist der Reverse-Proxy als Fraktal: Auf jeder Ebene des Systems steht derselbe Mechanismus — ein Proxy oder Ingress, der anhand des Host-Headers den Verkehr an den nächsten Dienst weiterleitet —, nur in anderer Größe.
Auf der äußersten Ebene terminiert ein Ingress-Controller den TLS-Verkehr und routet alle Hostnames über eine einzige Eingangs-IP. Der Traffic-Flow ist in content/de/architecture/networking-traffic-flow.md dokumentiert: Der Browser löst einen Hostnamen wie cloud.example.edu auf, der Ingress inspiziert den Host-Header und leitet an den passenden Kubernetes-Service weiter. Genau eine IP-Adresse bedient die gesamte Plattform — klassisches virtuelles Hosting.
Innerhalb der eingesetzten Cluster übernimmt diesen Job häufig ein HAProxy-basierter Ingress vor einer MetalLB-VIP (dokumentiert in content/de/blog/self-hosted-campus-k3s.md), während parallel Traefik für bestimmte HTTP/HTTPS-Szenarien zum Einsatz kommen kann. Der Punkt ist nicht die konkrete Wahl, sondern das Muster: unterschiedliche Domänen, ein einziger Einstiegspunkt.
Auf der inneren Ebene wiederholt sich dasselbe Muster als Sidecar oder Alias: Dienste wie Slidev oder das Collab Dashboard werden von einem kleinen nginx-Container ausgeliefert, und der oauth2-proxy-Sidecar sitzt als weiterer Mini-Proxy direkt davor (siehe die benutzerdefinierten Charts in content/de/blog/collab-services-scientific-tools.md). Ein Teil des Teams verwendet zusätzlich pro-Dienst nginx-alias-ähnliche Redirects, um einen kurzen, kanonischen Hostnamen auf einen längeren weiterzuleiten — praktisch das Fraktal nach innen. Wo diese Umleitungen (etwa per HTTP-301) realisiert werden, folgen sie demselben Kernprinzip: Einen eindeutigen kanonischen Host definieren und alles andere konsistent dorthin zeigen lassen, statt pro Dienst eigene URL-Aufbauten zu pflegen.
Der wiederkehrende Wert: Der Reverse-Proxy ist die eine Stelle, an der die Zuordnung Hostname → Dienst zentral verwaltet wird, statt sie in hundert Anwendungskonfigurationen zu verstreuen.
3. Service-Discovery über DNS statt hartverdrahteter IPs
Kubernetes-Dienste erhalten eine stabile, cluster-interne FQDN-Konvention (<service>.<namespace>.svc.cluster.local), die als Vertrag zwischen Komponenten dient: Eine Komponente referenziert eine andere nie über eine schwebende IP, sondern über diesen DNS-Namen. Der Namespace ist Teil des Namens, was zusätzlich explizit macht, wo eine Komponente lebt.
Das dokumentierte Muster vermeidet hartverdrahtete Adressen im Code. Die Grenze zeigt sich bei DNS-Fehlern eindrücklich: In der Community-of-Practice-Dokumentation (content/de/blog/community-of-practice-juni-2026.md) ist der Fall einer DNS-CNAME-Kette festgehalten, die einen SERVFAIL in CoreDNS auslöste und vorübergehend mit hostAliases überbrückt werden musste — also gerade nicht mit der ephemeren IP, sondern mit einer Entsprechung im Pod. Die Lehre daraus ist doppelt: Cluster-interne Dienste referenzieren einander über den DNS-FQDN; und wenn DNS krank ist, sind hostAliases ein Diagnose- und Überbrückungswerkzeug, keine dauerhafte Lösung, weil sie Informationen hart verdrahten, die sonst zentral gepflegt werden.
Für Dienste, die über den Ingress erreicht werden müssen, ist der Vertrag typischerweise eine Wildcard-DNS-Registrierung auf die Ingress-IP (siehe networking-traffic-flow.md), sodass ein neuer Dienst nur einen Ingress und einen DNS-Eintrag benötigt — kein weiteres Netzwerk-Rewriting.
4. GitOps: Konfiguration als Code als einzige Wahrheit
Das vierte Muster ist weniger ein Protokoll als eine Disziplin: Git ist die einzige Quelle der Wahrheit für den Clusterzustand. ArgoCD synchronisiert deklarativ gegen das Repository; eine Änderung ist ein Commit, Drift ist im ArgoCD-UI sichtbar. Die Bewertung ist in content/de/blog/gitops-argocd-app-of-apps-applicationset.md ausführlich nachzulesen, die praktische Anwendung unter anderem in content/de/blog/self-hosted-campus-k3s.md („Der Cluster ist ein Build-Artefakt").
Zwei Konfigurationstypen verhalten sich dabei unterschiedlich:
- Secrets gehören nie im Klartext in Git. Kritische Schlüssel wie OIDC-Client-Secrets oder LDAP-Bind-Credentials werden mit SOPS und age verschlüsselt als
.enc.yamlcommittet und erst zur Bereitstellungszeit über einen ArgoCD-Config-Management-Plugin-Sidecar entschlüsselt. Diese Architektur ist incontent/de/blog/sops-secret-management-argocd-cmp.mdvollständig beschrieben und trennt Verschlüsselung von Entschlüsselung zeitlich und lokal. - ConfigMaps sind die Wahrheit für nicht-geheime Konfiguration. Das Muster ist: ConfigMap aktualisieren →
apply→ Pod-Rollout auslösen. Der Haken wird in der Praxis gelernt: Nicht jede Anwendung lädt eine geänderte ConfigMap zur Laufzeit neu. Einige (etwa Webserver- und Groupware-Sidecars) behalten den alten Stand, bis der Pod neu gestartet wird. Deshalb gehören Checksum-Annotationen oder ein expliziter Rollout in den Workflow — sonst „lügt" die laufende Konfiguration gegen die im Git hinterlegte Wahrheit. Genau dafür steht im Selbst-Hosting-Artikel die Lektion, dass Umgebungsvariablen (etwaNEXTCLOUD_TRUSTED_DOMAINS) nur den Installer, nicht die laufende Anwendung konfigurieren: immutable Install-Parameter dürfen nicht mit lebendiger, hostabhängiger Konfiguration verwechselt werden.
Ein realistisches Korrektiv: ArgoCD „lügt" dort, wo Teile des Systems außerhalb von Git verwaltet werden (etwa per kubectl-Ad-hoc-Änderung oder durch nix-basierte Verwaltung). Drift-Handling ist damit nicht nur eine kosmetische, sondern eine Sicherheitsfrage, und es ist eine bewusst eingeräumte Schwachstelle.
5. Mail- und Verzeichnis-Interaktion
Die Mail-Integration zeigt, wie openEduSuite mehrere Komponenten hinter demselben SSO zu einem Dienst verbindet. Als Groupware-Frontend dient SOGo für Kalender, Kontakte und E-Mail; die Mailzustellung selbst übernehmen klassische Komponenten (Dovecot/Postfix in der Kernplattform, siehe content/de/blog/service-landscape.md). Für größere, föderierte Szenarien ist zusätzlich Stalwart Mail als Rust-basierter IMAP/SMTP/JMAP-Server dokumentiert (content/de/blog/federated-student-email-architecture.md).
Entscheidend für die Interaktion ist das Verzeichnis dahinter: Die Nutzerverwaltung liegt nicht bei jedem Maildienst, sondern bei einem zentralen Verzeichnis (LDAP/OpenLDAP) hinter Keycloak. Ein Dienst authentifiziert Nutzer nicht selbst, sondern verlässt sich auf die vom Identity-Broker verordnete Zuordnung — die LDAP-Bind-Credentials zählen zu den kritischen Secrets aus Abschnitt 4 (Priorität P1 in der SOPS-Dokumentation). So bleibt die Maildomäne an das selbe Nutzerverzeichnis angebunden wie jedes andere Dienst-Konto, ohne dass sich die Mail-Komponenten eigene Identitäten ausdenken.
6. Autorisierung und Isolation als Schnittstellenvertrag
Wo mehrere Dienste in einem Cluster koexistieren, ist Isolation ein Vertrag, kein Gefühl. openEduSuite nutzt dafür zwei Mechanismen, die in content/de/architecture/security.md und networking-traffic-flow.md beschrieben sind:
- Namespace-Isolation: Dienste laufen in eigenen Kubernetes-Namespaces (in den Einsatzbeispielen etwa
openedu,llm,home,monitoring,backup,argocd). Einhome-Namespace für Portale ist vonllmfür KI-Workloads getrennt, sodass eine defekte Komponente eingedämmt bleibt — dokumentiert incontent/de/blog/self-hosted-campus-k3s.md. - Netzwerkrichtlinien mit Default-Deny: Der gesamte Pod-zu-Pod-Verkehr ist standardmäßig abgelehnt und muss explizit erlaubt werden. Eine NetworkPolicy ist damit der verbindliche Schnittstellenvertrag zwischen zwei Komponenten: Wer mit wem sprechen darf, steht deklarativ in Git und ist versionierbar, statt implizit in der Netzwerktopologie zu liegen.
Dieses Default-Deny-Modell ist die logische Ergänzung zur SSO-Kette aus Abschnitt 1: Identität regelt, wer ein Nutzer ist; Netzwerkrichtlinien regeln, was ein Pod erreichen darf — auch dann, wenn die Identitätsebene bereits umgangen wurde.
7. Grenzen: Was die Muster nicht lösen
Die dokumentierten Betriebserfahrungen zeigen auch, wo die Muster an Grenzen stoßen:
- ArgoCD „lügt" bei parallelem Konfigurationsmanagement. Wo Deployment-Teile außerhalb von Git entstehen (Ad-hoc-
kubectl, nix-managte Stände), stimmt die laufende Konfiguration nicht mehr mit der Git-Wahrheit überein. GitOps ist nur so ehrlich wie die Disziplin, alles durch Git laufen zu lassen. - Domain-Renames sind ein hohes Risiko. Eine Domänenmigration berührt jede Komponente. Die dokumentierte Lektion aus dem Selbst-Hosting-Artikel: Env-Variablen wie
NEXTCLOUD_TRUSTED_DOMAINSwirken nur bei Neuinstallation; nachträgliche Änderungen brauchen den anwendungseigenen Konfigurationsweg (occ config:system:set). Verwaiste Drucke alter Domänen (id.umr-Ähnliches) bleiben beim Umbenennen schnell zurück. Die saubere Antwort ist Sichtbarkeit: Manifests und Runbooks gehören neben den Code, den sie betreffen. - Sichtbarkeit durch Verifikationstests statt Vertrauen. Weil die Kette aus Abschnitt 1 so zentral ist, wird sie nicht als selbstverständlich angenommen, sondern als Kontrakt getestet. Die dokumentierte Spec-Contract-Test-Pyramide (
content/de/blog/spec-contract-test-pyramid.md) organisiert genau das: Spezifikationen (was benötigt wird), Verträge (wie Dienste kommunizieren) und automatisierte Tests (dass es funktioniert). Eine SSO-Matrix über alle Dienste, verifiziert per End-to-End-Test, schützt davor, dass eine scheinbar harmlose Keycloak-Änderung eine Gruppe von Diensten stumm aus dem Login aussperrt. Robuste Guards — etwa dass keine Service-Kachel in einem Portal „tote" Links zeigt — sind Teil dieser Kontrakt-Denkweise.
Fazit
Die Interaktionsmuster von openEduSuite lassen sich in einem Satz zusammenfassen: Eine Quelle der Wahrheit pro vertikalem Anliegen. Eine für Identität (Keycloak), eine für Konfiguration (Git), ein Vertrag für Erreichbarkeit (DNS), ein Vertrag für Erlaubnis (NetworkPolicies). Der Reverse-Proxy wiederholt dieses Prinzip als Fraktal auf jeder Ebene, und jede Ausnahme von der Regel wird dokumentiert, damit sie beim nächsten Betriebseingriff nicht überrascht.
Wer diese Liste mit in das eigene Deployment nimmt, findet in den zitierten Repository-Dateien den Beleg für jedes Muster — und in den dokumentierten Grenzen das Korrektiv, das ein Architekturmuster belastbar macht.