Blog · 27. Mai 2025 · Aktualisiert am 7. September 2026 · 10 Min. Lesezeit

Kubernetes Service Types erklärt

Blick in einen belebten Supermarktgang mit Hinweisschildern über den Regalen
Foto: BI ravencrow / Pexels

Ein Kubernetes Service ist ein Objekt, das einer Gruppe von Pods eine feste IP-Adresse und einen DNS-Namen gibt und eingehende Anfragen auf diese Pods verteilt. Pods kommen und gehen, ihre IP-Adressen wechseln mit jedem Neustart. Der Service bleibt stehen und findet über Labels immer die Pods, die gerade laufen. Die vier Typen ClusterIP, NodePort, LoadBalancer und ExternalName unterscheiden sich nur in einer Frage: von wo aus der Service erreichbar ist.

Wer einmal ein Frontend fest auf die IP-Adresse eines Backend-Pods verdrahtet hat, weiß, warum es den Service gibt. Nach dem nächsten Rollout zeigt die Adresse ins Leere, und die Fehlersuche beginnt an der falschen Stelle. Der Service ist die Konstante, die dieses Problem aus der Welt schafft.

Ich betreibe Kubernetes-Cluster in Produktion und habe das Kubernetes-Praxisbuch bei Rheinwerk geschrieben (2024). Der Service hat dort einen eigenen Abschnitt in Kapitel 3. Hier steht die Kurzfassung mit den Punkten, die in meinen Projekten am häufigsten Fragen auslösen. Alle meine Beiträge zu Kubernetes findest du gesammelt auf der Seite Kubernetes.

Warum Pods eine feste Adresse brauchen

Kubernetes gibt jedem Pod eine eigene IP-Adresse, und jeder Pod kann jeden anderen Pod im Cluster direkt erreichen, ohne NAT. Die Adresse, die du im Pod siehst, ist dieselbe, über die andere Pods ihn ansprechen. Das klingt, als könnte dein Frontend das Backend einfach über dessen IP-Adresse aufrufen.

Technisch geht das, praktisch ist es ein Fehler. Ein Pod in Kubernetes ist vergänglich: Das Deployment tauscht ihn aus, wenn er nicht mehr antwortet, die Skalierung erzeugt morgens fünf und nachts zwei davon, und beim Rollout einer neuen Version werden alle nacheinander ersetzt. Jeder neue Pod bekommt eine neue IP-Adresse. Du brauchst deshalb einen Eingang, der stehen bleibt, während sich dahinter alles ändert.

Genau das leistet der Service, und zwar mit drei Aufgaben. Er kennt alle Pods, die zu ihm gehören, und aktualisiert diese Liste laufend (Service Discovery). Er verteilt die Anfragen auf die verfügbaren Pods (Load Balancing). Und er bietet eine feste virtuelle IP-Adresse und einen DNS-Namen, an die sich andere Anwendungen halten können. Auf jeder Node sorgt die Komponente kube-proxy dafür, dass Pakete an diese virtuelle Adresse bei einem der passenden Pods ankommen.

Kubernetes Service Discovery: Selektor, Labels und Endpoints

Der Service findet seine Pods nicht über Namen, sondern über Labels. Unter spec.selector gibst du an, welche Labels ein Pod tragen muss, damit der Service ihn aufnimmt. Kubernetes gleicht diese Auswahl permanent mit den laufenden Pods ab und pflegt daraus eine Liste von Endpoints, also Pod-IP plus Port. Nur Pods, deren Readiness Probe erfolgreich ist, landen in dieser Liste.

Das folgende Manifest zeigt ein Deployment mit zwei Nginx-Pods und den passenden Service. Entscheidend ist, dass das Label app: nginx im Pod-Template und im Selektor des Service übereinstimmt.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80

port ist der Port, unter dem der Service erreichbar ist, targetPort der Port im Container. Beide dürfen sich unterscheiden, und du kannst mehrere Ports mit Namen definieren, etwa http und https. Ohne Angabe von type entsteht ein ClusterIP-Service.

Der häufigste Fehler bei Services ist ein Selektor, der auf kein Label passt: Der Service existiert, hat eine IP-Adresse, und trotzdem bekommst du Connection refused. Der Blick auf die Endpoints zeigt das sofort.

kubectl get service nginx-service
kubectl get endpoints nginx-service
kubectl describe service nginx-service

Steht bei den Endpoints <none>, passt der Selektor nicht zu den Pod-Labels oder kein Pod ist ready. Wie Labels und Selektoren im Detail zusammenspielen, erkläre ich in Kubernetes Labels und Annotations erklärt.

Die Kubernetes Service Types im Vergleich

Alle Service-Typen bauen aufeinander auf. Ein NodePort ist ein ClusterIP-Service mit zusätzlichem Port auf jeder Node, ein LoadBalancer ist ein NodePort mit zusätzlicher externer IP-Adresse. Nur ExternalName fällt aus der Reihe, weil er auf keine Pods zeigt.

Typ Erreichbar von Typischer Einsatz
ClusterIP nur innerhalb des Clusters Kommunikation zwischen Anwendungen, Ziel für einen Ingress
NodePort jeder Node-IP auf einem festen Port Nicht-HTTP-Protokolle, Testcluster, einfache Setups
LoadBalancer externer IP-Adresse eines Load Balancers Eingang für einen Ingress Controller, TCP-Dienste nach außen
ExternalName innerhalb des Clusters, zeigt aber nach draußen Datenbank oder API außerhalb des Clusters unter internem Namen
Headless (kein eigener Typ, clusterIP: None) innerhalb des Clusters, ohne eigene IP-Adresse StatefulSets, wenn Clients einzelne Pods ansprechen müssen

ClusterIP: der Standard innerhalb des Clusters

Wenn jemand von einem Kubernetes Service spricht, meint er fast immer ClusterIP. Der Service bekommt eine virtuelle IP-Adresse aus dem Service-Netz des Clusters und ist nur von dort erreichbar. Für die Kommunikation zwischen deinen Anwendungen ist das genau richtig, denn nichts davon soll von außen sichtbar sein. Die Adresse kannst du mit clusterIP fest vorgeben, sie muss aber im Service-Netz liegen und frei sein. In der Praxis brauchst du das selten, weil ohnehin alle über den DNS-Namen gehen.

NodePort: ein Port auf jeder Node

Mit type: NodePort öffnet Kubernetes auf jeder Node des Clusters denselben Port, standardmäßig aus dem Bereich 30000 bis 32767, und leitet alles, was dort ankommt, an den Service weiter. Du erreichst deine Anwendung dann über die IP-Adresse einer beliebigen Node plus diesen Port. Den Port kannst du mit nodePort fest setzen, damit er nach jedem Neuanlegen gleich bleibt.

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

NodePort arbeitet auf Layer 4: Er sieht Pakete und Ports, keine URLs oder Hostnamen. Für Protokolle jenseits von HTTP, etwa eine Datenbank oder einen Message Broker, ist das die passende Wahl. Für Webanwendungen nutze ich ihn nur zum Testen, weil ein Ingress dort deutlich mehr Steuerung bietet.

LoadBalancer: eine externe IP-Adresse vom Anbieter

Ein Kubernetes Service vom Typ LoadBalancer bittet die Umgebung um einen externen Load Balancer mit eigener IP-Adresse. In einer Cloud übernimmt das der Cloud Controller Manager des Anbieters: Er legt den Load Balancer an, hängt die Nodes dahinter und trägt die Adresse unter status.loadBalancer ein. In meinen Clustern auf Hetzner Cloud entsteht auf diesem Weg ein Hetzner Load Balancer, ohne dass ich ihn von Hand anlegen muss.

apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80

Wichtig zu wissen: Jeder LoadBalancer-Service kostet beim Anbieter meist Geld und eine eigene IP-Adresse. Deshalb hängt in meinen Clustern nur ein einziger Service dieses Typs vor dem Ingress Controller, und alle Webanwendungen laufen dahinter über Ingress-Regeln.

ExternalName: ein DNS-Alias nach draußen

ExternalName hat keinen Selektor und keine Pods. Der Service ist nur ein CNAME auf einen externen Hostnamen. Deine Anwendung spricht datenbank an, und Kubernetes löst das auf den Hostnamen einer Datenbank auf, die außerhalb des Clusters läuft. Der Charme liegt in der Austauschbarkeit: In Produktion zeigt der Name auf die gemanagte Datenbank, in der Entwicklungsumgebung ersetzt du den ExternalName durch einen ClusterIP-Service mit einem Datenbank-Pod. Der Anwendungscode bleibt gleich.

apiVersion: v1
kind: Service
metadata:
  name: datenbank
spec:
  type: ExternalName
  externalName: db.example.com

Kubernetes Service DNS: so finden Pods den Service

Jeder Service bekommt automatisch einen DNS-Eintrag, den der Cluster-DNS (in aktuellen Clustern CoreDNS) bereitstellt. Das Schema ist immer gleich: <service>.<namespace>.svc.cluster.local. Ein Service nginx-service im Namespace default heißt also nginx-service.default.svc.cluster.local.

Innerhalb desselben Namespace reicht der kurze Name nginx-service, weil die DNS-Konfiguration im Pod den eigenen Namespace als Suchdomäne ergänzt. Aus einem anderen Namespace heraus brauchst du mindestens nginx-service.default. Ich empfehle, in Konfigurationen immer den Namen mit Namespace zu schreiben. Das kostet nichts und erspart die Überraschung, wenn eine Anwendung später in einen anderen Namespace umzieht.

Testen kannst du das mit einem Hilfs-Pod im Cluster:

kubectl run test --rm -it --image=busybox -- sh
wget -qO- nginx-service
wget -qO- nginx-service.default.svc.cluster.local

Beide Aufrufe liefern die Nginx-Startseite. Für den schnellen Blick von deinem Rechner aus, ohne NodePort oder LoadBalancer, hilft kubectl port-forward service/nginx-service 8080:80, danach antwortet der Service unter localhost:8080.

LoadBalancer ohne Cloud: was on-premise passiert

Die Frage, die mir aus dem Mittelstand am häufigsten begegnet: Was passiert mit type: LoadBalancer, wenn kein Cloud-Anbieter dahintersteht? Die ehrliche Antwort: erst einmal nichts. Der Service bleibt mit EXTERNAL-IP auf <pending> stehen, weil niemand im Cluster weiß, wie er einen Load Balancer beschaffen soll. Die Funktion des ClusterIP und NodePort ist trotzdem da, nur die externe Adresse fehlt.

Für eigene Hardware oder einen Server beim Hoster füllt MetalLB diese Lücke. Du gibst ihm einen Bereich freier IP-Adressen aus deinem Netz, und er weist jedem LoadBalancer-Service eine davon zu und macht sie über ARP oder BGP erreichbar. Damit verhält sich dein Cluster wie in der Cloud, nur dass du die Adressen selbst verwaltest. Bei k3s bringt die Distribution mit ServiceLB bereits eine einfache Variante mit, die die Node-IPs für LoadBalancer-Services nutzt. Für ein einzelnes Testsystem reicht das, für Produktion mit mehreren Nodes ist MetalLB oder ein Load Balancer des Hosters die stabilere Wahl.

Unabhängig vom Weg gilt: Der LoadBalancer-Service ist der Eingang auf Layer 4. Sobald du Hostnamen, Pfade oder TLS-Zertifikate steuern willst, brauchst du dahinter einen Ingress. Wie das zusammenspielt und welcher Ingress Controller wann passt, steht in Kubernetes Ingress und Ingress Controller.

Häufige Fragen

Was ist der Unterschied zwischen Service und Ingress?

Der Service gibt Pods eine stabile Adresse und verteilt Anfragen auf Layer 4, also nach IP-Adresse und Port. Der Ingress arbeitet auf Layer 7 und entscheidet anhand von Hostname und Pfad einer HTTP-Anfrage, an welchen Service sie geht. Ein Ingress braucht immer einen Service als Ziel, ein Service braucht keinen Ingress.

Warum steht mein LoadBalancer-Service auf pending?

Weil kein Cloud Controller Manager und kein MetalLB im Cluster läuft, der eine externe IP-Adresse zuweisen könnte. In einer Cloud fehlt dann meist die Anbindung an den Anbieter, on-premise fehlt MetalLB oder eine vergleichbare Komponente. Der Service selbst ist trotzdem als ClusterIP und NodePort nutzbar.

Ist NodePort in Produktion eine gute Idee?

Für HTTP-Anwendungen nicht. Der Port liegt in einem ungewohnten Bereich, jede Node muss ihn nach außen öffnen, und du hast keine Steuerung über Hostnamen oder TLS. Für einzelne TCP-Dienste hinter einer eigenen Firewall oder als Unterbau eines externen Load Balancers ist NodePort dagegen ein legitimer, einfacher Weg.

Wie erreiche ich einen Kubernetes Service aus einem anderen Namespace?

Über den DNS-Namen mit Namespace, also <service>.<namespace> oder vollständig <service>.<namespace>.svc.cluster.local. Der kurze Name allein funktioniert nur im selben Namespace. Ob der Zugriff erlaubt ist, entscheidet nicht der Service, sondern gegebenenfalls eine NetworkPolicy.

Kann ich einen Service ohne Selektor anlegen?

Ja. Dann pflegt Kubernetes die Ziele nicht automatisch, und du legst sie selbst an, zum Beispiel mit der IP-Adresse eines Systems außerhalb des Clusters. Das aktuelle Objekt dafür ist EndpointSlice; das ältere Endpoints-Objekt gibt es noch, neue Setups schreiben aber EndpointSlices. Das ist die Alternative zu ExternalName, wenn du eine IP-Adresse statt eines Hostnamens hast oder Port-Umsetzung brauchst.

Wie du weitermachst

Der Service ist die Brücke zwischen deinen Pods und allem, was sie erreichen will. Nach innen reicht ClusterIP mit DNS, nach außen führt der Weg in der Regel über einen einzigen LoadBalancer-Service vor einem Ingress Controller. Wie du HTTP-Verkehr dann mit Hostnamen, Pfaden und Zertifikaten steuerst, beschreibe ich in Kubernetes Ingress und Ingress Controller. Wenn du bei den Grundlagen noch einmal ansetzen willst, ist Kubernetes Pod: was ist ein Pod? der passende Einstieg.

Mein Vorschlag für heute: Leg das Deployment und den Service von oben an, prüfe mit kubectl get endpoints, ob beide Pods gelistet sind, und ändere dann testweise das Label im Selektor. Du siehst sofort, wie die Endpoints verschwinden und die Anwendung nicht mehr antwortet. Die vollständige Referenz zu allen Feldern findest du in der Kubernetes-Dokumentation zu Services, die Namensregeln in der Dokumentation zu DNS für Services und Pods.

Ausführlich mit allen Beispielen, vom ersten ClusterIP über NodePort bis zum Zusammenspiel mit Ingress, steht das in Kapitel 3 meines Kubernetes-Praxisbuchs bei Rheinwerk.

Kevin Welter

Kevin Welter

Entwickler, IT-Architekt, Fachbuchautor (Kubernetes, Cloud-Infrastrukturen) und Speaker. Betreibt sein Business mit einer KI-Belegschaft aus acht KI-Mitarbeitern und zeigt Selbstständigen in seiner Community, wie sie ihren ersten KI-Mitarbeiter einstellen.

Mehr über KI-Mitarbeiter

Kubernetes von den Grundlagen bis zum produktionsreifen Cluster

Zum Buch