ADR-0007: Eureka fuer das Compose-Profil, Kubernetes-native Discovery fuer das K8s-Profil
Status
Akzeptiert (2026-08-04)
Kontext
"Service Discovery" beantwortet die Frage "unter welcher Netzwerkadresse erreiche ich gerade eine Instanz von member-service?" - relevant, sobald es mehr als eine Instanz geben kann oder Adressen sich dynamisch aendern (Container-Neustarts, Auto-Scaling).
Es gibt zwei grundsaetzlich verschiedene Ansaetze:
- Client-Side Discovery: jeder Client (bzw. dessen Client-Library) fragt eine Registry (hier: Netflix Eureka) nach verfuegbaren Instanzen und waehlt selbst eine aus (Client-Side Load Balancing, z. B. via Spring Cloud LoadBalancer).
- Server-Side / plattformnative Discovery: die Plattform selbst (hier: Kubernetes) loest einen logischen Service-Namen per DNS auf eine (ggf. lastverteilte) Adresse auf - der Client merkt davon nichts, er ruft einfach einen stabilen DNS-Namen auf.
Entscheidung
Wir betreiben beides, je nach Deployment-Profil, mit demselben Anwendungscode:
- Compose-Profil (Podman Compose, lokal):
discovery-server(Eureka) laeuft mit, Services registrieren sich dort und nutzenspring-cloud-starter-netflix-eureka-clientfuer Client-Side Discovery (klassisches Spring-Cloud-Muster, in vielen bestehenden Unternehmensarchitekturen noch aktiv im Einsatz). - Kubernetes/Helm-Profil: kein Eureka. Services adressieren sich gegenseitig ueber
Kubernetes-
Service-DNS-Namen (http://catalog-service.library.svc.cluster.local), das Eureka-Client-Autoconfiguration wird per Spring-Profil (k8s) deaktiviert.
Konsequenzen
Positiv
- Direkter Vergleich beider Ansaetze am selben Code - ein haeufiges Interviewthema ("Wie funktioniert Service Discovery bei euch, Eureka oder Kubernetes-nativ, und warum?") laesst sich hier praktisch nachvollziehen statt nur in der Theorie zu verstehen.
- Migrationsuebung: der Umstieg von Eureka auf Kubernetes-native Discovery ist ein reales Szenario beim Umzug einer bestehenden Spring-Cloud-Landschaft in einen Kubernetes-Cluster.
Negativ / Trade-offs
- Zwei Profile zu pflegen bedeutet doppelten Konfigurationsaufwand und die Gefahr, dass ein Profil "verwaist" (nicht mehr regelmaessig getestet wird).
- Eureka bringt in der Compose-Umgebung einen zusaetzlichen Single-Point-of-Failure- Kandidaten mit (wird hier nur mit einem Knoten betrieben, kein Peer-Awareness-Cluster).
Nachtrag (Phase 13): Feign-Clients nutzen Eureka jetzt tatsaechlich zur Adressaufloesung
Zunaechst registrierten sich catalog-service/member-service/lending-service zwar bei Eureka
(sichtbar im Dashboard unter :8761), aber lending-services Feign-Clients riefen sie trotzdem
ueber feste, in application.yml/docker-compose.yml (Dateiname unveraendert) konfigurierte
URLs auf - die Eureka-Registry wurde also nie tatsaechlich zur ADRESSAUSWAHL genutzt (siehe
documentation/docs/07-pattern-katalog/pattern-katalog.md, war dort als Vertiefungsaufgabe
gefuehrt). Inzwischen behoben: spring-cloud-starter-loadbalancer als Dependency ergaenzt,
@FeignClient(..., url = "${...:}") (leerer Default) laesst Feign bei fehlender expliziter URL
automatisch auf namensbasierte Eureka-/LoadBalancer-Aufloesung zurueckfallen. Nur die
VOLL containerisierte Compose-Umgebung (infra/docker-compose.yml) setzt die URL
tatsaechlich leer - die "Local"-Stufe (lending-service via IDE) behaelt feste URLs als
Default, da ein bloss lokal laufender IDE-Prozess Eureka-registrierte container-interne
IP-Adressen anderer, containerisierter Services nicht zuverlaessig erreichen kann. Das
Kubernetes-Profil ist
unveraendert: kein Eureka, feste K8s-DNS-Namen ueber Helm-Werte.
Alternativen erwogen
- Nur Kubernetes-native Discovery, auch lokal via Compose per fixer Hostnamen (Compose-DNS loest Servicenamen ohnehin automatisch auf) - haette Eureka als Lernthema komplett gestrichen; verworfen, weil Eureka in vielen bestehenden (nicht-Kubernetes-) Unternehmenslandschaften weiterhin relevant ist.
- Consul als alternative, plattformunabhaengige Service-Registry - fuer dieses Projekt als "eine Technologie zu viel" verworfen, im Tech-Stack-Katalog aber als Alternative erwaehnt.