- Authors

- Name
- Phillip Pham
- @ddppham
Service ohne Endpoints: Selector und Readiness
TL;DR
Ein Service leitet nur auf Pods, die in Endpoints stehen. Ist die Liste leer, wirft der Service den Traffic weg, auch wenn Pods Running sind. Die Liste ist der Befund:
kubectl get endpoints SERVICE -n NAMESPACE
kubectl describe endpoints SERVICE -n NAMESPACE
Zwei Ursachen. Der Selector trifft die Labels der Pods nicht. Oder er trifft sie, und die Readiness-Probe ist nicht ready. Beides steht im describe: NotReadyAddresses gegen eine komplett leere Menge. Pod läuft nicht: Pod startet nicht.
Selector und Labels
kubectl get svc SERVICE -o jsonpath='{.spec.selector}{"\n"}'
kubectl get pods -n NAMESPACE --show-labels
Jedes Key-Value-Paar im Selector muss auf dem Pod stehen. app: api am Service und app: api-v2 am Pod ist eine leere Endpunktliste, ohne Warning am Pod. Der Pod ist gesund. Er gehört dem Service nur nicht.
Ein Service ohne selector hat nie automatische Endpoints. Die Liste kommt aus einem EndpointSlice, den jemand von Hand pflegt, oder sie bleibt leer. Das ist Absicht bei einem externen Ziel. Es ist ein Versehen, wenn der Selector beim Kopieren des Manifests verloren ging.
Namespace muss derselbe sein. Ein Service in prod sieht keine Pods in default.
Ready ist nicht Running
Running heißt: der Prozess läuft. In die Endpoints kommt der Pod erst, wenn jede Readiness-Probe erfolgreich ist. Bis dahin steht die Adresse unter NotReady, und der Service schickt keinen Traffic.
kubectl describe pod POD zeigt Ready: False und die Probe, die fehlschlägt. Ein HTTP-Check auf einen Pfad, der 500 liefert, ein TCP-Port, der noch nicht lauscht, ein initialDelay, der zu kurz ist. Die Liveness killt den Pod. Die Readiness nimmt ihn nur aus dem Service. Wer die Readiness zur Liveness umbaut, erzeugt Exit 143 oder 137 statt einer leeren Traffic-Liste.
Kein Probe definiert: der Container gilt als ready, sobald er gestartet ist. Dann ist eine leere Endpunktliste kein Probe-Problem, sondern der Selector.
Was Sie nicht neu anlegen müssen
Den Service zu löschen und gleich wieder anzulegen ändert die Endpoints nicht, solange Selector und Pod-Labels gleich bleiben. Das ClusterIP wechselt dabei und bricht Clients, die es gecacht haben. Zuerst die Labels angleichen oder die Probe auf einen Pfad legen, der 200 liefert, ohne die Datenbank im kritischen Pfad zu haben.
Ein Ingress mit 503 bei gesetzter Address ist oft genau diese leere Liste: Ingress ohne Address ist der andere Fall, nämlich gar keine IP davor.
Quellen
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
kubectl connection refused 6443 beheben
kubectl connection refused auf Port 6443: der API-Server antwortet nicht. kubeconfig, Kontext, Firewall, API-Prozess. Der Pod-Status kommt erst danach.
Error from server Forbidden: RBAC-Recht
kubectl Forbidden: Error from server (Forbidden) nennt User, Verb und Ressource. kubectl auth can-i zeigt das Recht, bevor jemand cluster-admin vergibt.
ContainerCreating hängt: Volume, Sandbox, CNI
ContainerCreating hängt: der Pod hat einen Node, der Container startet nicht. FailedMount, Pod-Sandbox und CNI stehen in den Events, nicht in den Logs.
CreateContainerConfigError: Secret und ConfigMap
CreateContainerConfigError: fehlendes Secret, falscher Key oder Namespace. Der Container startet nicht, logs --previous bleibt leer. Das Event nennt das Objekt.
Kubernetes DNS fehlgeschlagen: CoreDNS, ndots
Kubernetes DNS fehlgeschlagen: CoreDNS-Pods, das Service-ClusterIP und ndots:5. Wann ein Name im Cluster auflöst und wann die NetworkPolicy UDP 53 schluckt.
Exit Code 1: die erste Zeile im Previous-Log
Exit Code 1 auf Kubernetes: die Anwendung beendet sich selbst. kubectl logs --previous zeigt die Zeile. Speicher, Image-Pull und SIGKILL sind andere Codes.
Exit Code 143: SIGTERM und Graceful Shutdown
Exit Code 143 ist SIGTERM: 128 plus 15. Beim Rollout ist das normal. Im Loop fehlt ein Handler oder die Grace-Period ist kürzer als der Stopp der Anwendung.
Ingress ohne Address: Controller und Class
Ingress ohne Address: kein Controller, falsche IngressClass oder der LoadBalancer dahinter bleibt Pending. ADDRESS leer ist der Controller, nicht das Backend.