The selector does not match the pod labels
CommonThe Service's selector and the pod template's labels differ — a typo, a renamed app, or a selector copied from another manifest. A subtler version: the selector was written against the labels on the Deployment object rather than the labels inside spec.template.metadata.labels, which are what the pods actually carry.
Confirm
kubectl get pods -l "$(kubectl get svc <service> -o jsonpath='{.spec.selector}' | tr -d '{}"' | tr ':' '=')" --show-labelsNo pods returned. Then compare against kubectl get pods --show-labels to see what labels the pods really carry
Fix
- Make the Service selector match
spec.template.metadata.labelsin the Deployment exactly, key and value. - Change the Service rather than relabelling running pods. A label added by hand is lost when the pod is replaced, and changing a label the ReplicaSet selects on orphans the pod and makes the ReplicaSet start a replacement.
- Keep the selector minimal. Matching on one stable label is more robust than matching on five that include a version.
kubectl get svc <service> -o jsonpath='{.spec.selector}'; echo; kubectl get deploy <deployment> -o jsonpath='{.spec.template.metadata.labels}'Prints the two things that must agree, next to each other.