Kubernetes Tutorial: Diagnose Why a Deployment Has Ready Pods but Its Service Has No Endpoints
This tutorial guides you through troubleshooting a common Kubernetes scenario: a Deployment successfully creating pods, but the corresponding Service doesn’t expose them. We’ll walk through the diagnostic steps using YAML and `kubectl` commands.
Understanding the Problem
A Deployment manages the desired state of your application. Pods are the running instances created by the Deployment. A Service aims to provide a stable IP address and DNS name to access these pods. If the Service has no endpoints, it means no pods are being selected by the Service’s selector. This discrepancy is a frequent indicator of misconfiguration.
Example 1: Initial State – The Problem
Let’s set up a minimal deployment and service to illustrate the issue. This example contains an error we will specifically address.
Deployment (deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: busybox:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-service
labels:
app: my-app
spec:
selector:
app: my-app-deployment # Incorrect label, matches Deployment, not Service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
kubectl Commands
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get services
kubectl get pods --all-namespaces
kubectl describe service my-app-service
Expected Outcome (with error)
Running the `kubectl get services` command will show the `my-app-service` service but the `ENDPOINTS` column will be empty. Running `kubectl describe service my-app-service` will highlight the selector mismatch.
Example 2: Correcting the Service Selector
The problem here is that the Service selector uses the label `app: my-app-deployment` which matches the Deployment’s labels, not the Service’s labels. We need to adjust the Service selector to match the Service’s labels.
Deployment (deployment.yaml) – No Changes
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: busybox:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-service
labels:
app: my-app
spec:
selector:
app: my-app # Corrected label
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
kubectl Commands
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get services
kubectl get pods --all-namespaces
kubectl describe service my-app-service
Expected Outcome
After applying the corrected YAML, `kubectl get services` will now show the `my-app-service` service with endpoints pointing to the three pods created by the deployment. `kubectl describe service my-app-service` will show that the Service selector matches the Service’s labels, and the `ENDPOINTS` column will be populated.
Example 3: Verifying the Deployment and Service
Let’s confirm the deployment is running correctly and the service is properly configured.
kubectl Commands
kubectl get pods --all-namespaces -o wide
kubectl get services --all-namespaces
kubectl logs my-app-container -c my-app-container -n default # Check application logs
kubectl describe deployment my-app-deployment
Expected Outcome
You should see the three pods in the `my-app-deployment` deployment running, each with its own IP address. The `my-app-service` should be accessible on port 80. Examining the logs of the pods should confirm the application is running.



Leave a Reply