Endpoints & EndpointSlice

Endpoints and EndpointSlice are Kubernetes resources that track which pod IP addresses a Service should route traffic to. When you create a Service with a selector, Kubernetes automatically creates Endpoints (or EndpointSlice) resources that list the IP addresses of all pods matching the selector. Understanding these resources helps you debug Service routing and understand how Services find and connect to pods.

What are Endpoints?

An Endpoints resource is automatically created for each Service with a selector. It contains a list of IP addresses and ports for all pods that match the Service’s selector. The Service uses this list to know where to route traffic.

graph TB A[Service Created] --> B[Selector Evaluated] B --> C[Pods Matching Selector Found] C --> D[Endpoints Resource Created] D --> E[Service Routes Traffic to Endpoints] F[New Pod Created] --> G{Matches Selector?} G -->|Yes| H[Added to Endpoints] G -->|No| I[Not Added] H --> J[Service Routes to New Pod] K[Pod Deleted] --> L[Removed from Endpoints] L --> M[Service Stops Routing] style A fill:#e1f5ff style D fill:#e8f5e9 style J fill:#e8f5e9 style M fill:#ffe1e1

How Endpoints Work

When you create a Service:

  1. Service defines selector - Labels that identify target pods
  2. Kubernetes watches pods - Continuously monitors pods in the cluster
  3. Matches pods to selector - Finds all pods with matching labels
  4. Creates/updates Endpoints - Lists pod IPs and ports
  5. Service uses Endpoints - Routes traffic to IPs listed in Endpoints
graph LR A[Service<br/>Selector: app=web] --> B[Controller Watches Pods] B --> C[Pod 1: app=web<br/>IP: 10.244.1.5] B --> D[Pod 2: app=web<br/>IP: 10.244.1.6] B --> E[Pod 3: app=web<br/>IP: 10.244.2.3] C --> F[Endpoints Resource] D --> F E --> F F --> G[Service Routes to These IPs] style A fill:#e1f5ff style F fill:#e8f5e9 style G fill:#fff4e1

Viewing Endpoints

You can view Endpoints for a Service:

kubectl get endpoints <service-name>

Example output:

NAME           ENDPOINTS                                           AGE
web-service    10.244.1.5:8080,10.244.1.6:8080,10.244.2.3:8080    5m

The Endpoints resource shows:

  • IP addresses of pods matching the selector
  • Ports that pods are listening on
  • Subsets grouping endpoints by port and readiness

Endpoints Resource Structure

Here’s what an Endpoints resource looks like:

apiVersion: v1
kind: Endpoints
metadata:
  name: web-service  # Same name as Service
  namespace: default
subsets:
- addresses:
  - ip: 10.244.1.5
    nodeName: node-1
    targetRef:
      kind: Pod
      name: web-pod-1
      namespace: default
  - ip: 10.244.1.6
    nodeName: node-1
    targetRef:
      kind: Pod
      name: web-pod-2
      namespace: default
  - ip: 10.244.2.3
    nodeName: node-2
    targetRef:
      kind: Pod
      name: web-pod-3
      namespace: default
  ports:
  - port: 8080
    protocol: TCP

Key fields:

  • addresses - List of pod IPs that are ready
  • notReadyAddresses - Pod IPs that aren’t ready (if any)
  • ports - Ports that pods are listening on
  • targetRef - Reference to the pod object

Readiness and Endpoints

Endpoints only include pods that are ready. Pods that fail readiness probes are excluded:

graph TB A[Pod Created] --> B{Pod Ready?} B -->|Yes| C[Added to Endpoints] B -->|No| D[Not Added] E[Pod Becomes Ready] --> F[Added to Endpoints] G[Pod Becomes Not Ready] --> H[Removed from Endpoints] style C fill:#e8f5e9 style D fill:#ffe1e1 style F fill:#e8f5e9 style H fill:#ffe1e1

Ready pods → Included in addresses
Not ready pods → Included in notReadyAddresses (if Service has publishNotReadyAddresses: true)

EndpointSlice (Modern Approach)

EndpointSlice is the newer, more scalable alternative to Endpoints. It was introduced to address limitations of the Endpoints resource:

  • Scalability - Endpoints can become large with many pods
  • Performance - EndpointSlice is more efficient for large Services
  • Network topology - Supports zone/region awareness
graph TB subgraph endpoints[Endpoints] A[Single Resource] B[All Pods in One List] C[Size Limit Issues] end subgraph endpointslice[EndpointSlice] D[Multiple Resources] E[Pods Split Across Slices] F[Better Scalability] end style endpoints fill:#fff4e1 style endpointslice fill:#e8f5e9

EndpointSlice Structure

EndpointSlice resources are automatically created (if the feature is enabled):

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: web-service-abc123  # Generated name
  namespace: default
  labels:
    kubernetes.io/service-name: web-service
addressType: IPv4
endpoints:
- addresses:
  - "10.244.1.5"
  conditions:
    ready: true
  targetRef:
    kind: Pod
    name: web-pod-1
    namespace: default
  zone: us-west-1a
- addresses:
  - "10.244.1.6"
  conditions:
    ready: true
  targetRef:
    kind: Pod
    name: web-pod-2
    namespace: default
  zone: us-west-1b
ports:
- name: http
  port: 8080
  protocol: TCP

Key differences from Endpoints:

  • Multiple EndpointSlice resources per Service (split by size)
  • Zone/region information for topology-aware routing
  • More efficient for large Services
  • Generated names (not same as Service name)

Viewing EndpointSlice

# List EndpointSlices for a Service
kubectl get endpointslice -l kubernetes.io/service-name=web-service

# Describe an EndpointSlice
kubectl describe endpointslice <endpointslice-name>

Endpoints vs EndpointSlice

graph TB subgraph endpoints[Endpoints] A[One Resource per Service] B[All Pods in Single Resource] C[Legacy Approach] D[Size: Up to 1000 IPs] end subgraph endpointslice[EndpointSlice] E[Multiple Resources per Service] F[Pods Split Across Slices] G[Modern Approach] H[Size: Up to 100 IPs per Slice] end style endpoints fill:#fff4e1 style endpointslice fill:#e8f5e9

Endpoints:

  • Single resource per Service
  • All pod IPs in one list
  • Legacy, but still widely used
  • Can become large with many pods

EndpointSlice:

  • Multiple resources per Service
  • Pods split across slices (max 100 per slice)
  • Modern, scalable approach
  • Better for Services with many pods
  • Supports topology awareness

Service Without Selector

You can create a Service without a selector and manually manage Endpoints:

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-service  # Must match Service name
subsets:
- addresses:
  - ip: 192.168.1.100  # External IP
  ports:
  - port: 8080

This allows Services to route to external endpoints (databases, APIs, etc.) outside the cluster.

graph TB A[Service Without Selector] --> B[Manual Endpoints] B --> C[External IP: 192.168.1.100] C --> D[External Service] E[Pod in Cluster] --> A A --> C style A fill:#e1f5ff style B fill:#fff4e1 style D fill:#ffe1e1

Debugging with Endpoints

Endpoints are invaluable for debugging Service issues:

Service Not Routing Traffic

# Check if Endpoints exist
kubectl get endpoints <service-name>

# If empty, Service has no pods to route to
# Check pod selector
kubectl get pods -l app=web

# Verify pods are ready
kubectl get pods -l app=web

Pods Not in Endpoints

  1. Check selector matches: kubectl get pods -l app=web
  2. Verify pod labels: kubectl get pods --show-labels
  3. Check pod readiness: kubectl get pods -l app=web
  4. Review Endpoints: kubectl describe endpoints <service-name>

Endpoints Empty

If Endpoints are empty, possible causes:

  • No pods match the selector
  • Pods exist but aren’t ready
  • Pods are in different namespace
  • Selector labels don’t match pod labels

Monitoring Endpoints

You can monitor Endpoints to track Service health:

# Watch Endpoints changes
kubectl get endpoints <service-name> -w

# Count endpoints
kubectl get endpoints <service-name> -o jsonpath='{.subsets[0].addresses[*].ip}' | wc -w

# List all endpoint IPs
kubectl get endpoints <service-name> -o jsonpath='{.subsets[0].addresses[*].ip}'

Best Practices

  1. Monitor Endpoints - Regularly check that Services have expected Endpoints
  2. Use readiness probes - Ensure pods report readiness correctly
  3. Verify selectors - Double-check Service selectors match pod labels
  4. Check EndpointSlice - If using EndpointSlice, monitor multiple resources
  5. Debug with Endpoints - Use Endpoints to troubleshoot Service routing issues
  6. Understand readiness - Know that only ready pods are included
  7. Monitor changes - Watch for Endpoints changes during deployments
  8. Use external Endpoints - Leverage manual Endpoints for external services

Troubleshooting

Endpoints Empty

  1. Check pod selector: kubectl get pods -l app=my-app
  2. Verify labels match: kubectl get pods --show-labels
  3. Check pod readiness: kubectl get pods -l app=my-app
  4. Verify namespace: Ensure Service and pods are in same namespace
  5. Check Endpoints resource: kubectl get endpoints <service-name> -o yaml

Endpoints Not Updating

  1. Check controller: Verify endpoints controller is running
  2. Check pod status: Ensure pods are actually ready
  3. Verify selector: Double-check Service selector
  4. Check events: kubectl get events --field-selector involvedObject.name=<service-name>

Wrong Pods in Endpoints

  1. Review selector: kubectl get service <service-name> -o yaml | grep selector
  2. Check pod labels: kubectl get pods --show-labels
  3. Verify namespace: Ensure correct namespace
  4. Check for label conflicts: Multiple pods with same labels in different namespaces

EndpointSlice Not Created

  1. Check feature gate: Verify EndpointSlice feature is enabled
  2. Check Kubernetes version: EndpointSlice requires Kubernetes 1.17+
  3. Verify API enabled: Ensure discovery.k8s.io/v1 API is available
  4. Check controller: Verify endpoints controller is running

See Also