Kubernetes Endpoints & EndpointSlices: Who’s Really Behind That Service?
Overview
What Are Endpoints?
Ever wondered how a Service
in Kubernetes actually knows which pods to forward traffic to? Enter the Endpoint, Kubernetes’ behind-the-scenes phonebook.
When you create a Service
, Kubernetes auto-generates an Endpoint
object. It’s a simple list of pod IPs and ports that match the Service
’s selector. Basically:
“Hey Service X, your pods are at 10.42.0.12:8080 and 10.42.0.15:8080. Go get ‘em, tiger.”
You can check them out with:
1kubectl get endpoints
Or the cooler kids do:
1kubectl describe endpoints my-service
But wait—there’s a plot twist.
The EndpointSlice Era Has Begun
Endpoints
were fine… until they weren’t. They hit scaling issues. Imagine having thousands of pods—Kubernetes would cram them all into one giant Endpoint
object. That’s a lot of YAML for one API call.
So Kubernetes introduced EndpointSlices in v1.17, and they became the default in v1.21. They break up those massive lists into smaller, manageable chunks.
Think of it like this:
- Endpoints: A party guest list scribbled on a napkin
- EndpointSlices: Alphabetized spreadsheets with tabs, filters, and color-coding
What’s Inside an EndpointSlice?
An EndpointSlice
contains:
- A list of endpoints (IP + port)
- Their conditions (e.g., is the pod ready?)
- Metadata like hostname, nodeName, and topology
- Ports and protocols (TCP/UDP/SCTP — Kubernetes doesn’t judge)
1apiVersion: discovery.k8s.io/v1
2kind: EndpointSlice
3metadata:
4 name: my-service-abc123
5 labels:
6 kubernetes.io/service-name: my-service
7addressType: IPv4
8ports:
9 - name: http
10 protocol: TCP
11 port: 8080
12endpoints:
13 - addresses:
14 - 10.42.0.12
15 conditions:
16 ready: true
17 nodeName: node-1
18 topology:
19 zone: us-west1-a
Pro tip: If you’re using headless Services (ClusterIP: None
), the EndpointSlice is your DNS source of truth.
Comparing Endpoints vs. EndpointSlices
Feature | Endpoints | EndpointSlices |
---|---|---|
Scale | Struggles beyond ~100 pods | Scales to thousands of pods |
API Version | v1 |
discovery.k8s.io/v1 |
Default in v1.21+ | no | yes |
Grouped by port/IP | All in one | Sliced by 100 endpoints max |
Extensible metadata | Basic | Rich (conditions, topology) |
So yeah, EndpointSlices are the cool, scalable, modern replacement. But don’t worry—your kubectl get endpoints
still works. Kubernetes quietly builds the Endpoints
object from the EndpointSlices for backward compatibility.
Like a polite butler translating your outdated commands into the new API.
Debugging: Who’s Behind the Service?
If you’re wondering which pods your Service actually targets:
1kubectl get endpoints my-service -o yaml
Or go full slice-mode:
1kubectl get endpointslices -l kubernetes.io/service-name=my-service -o yaml
This gives you a peek behind the curtain. You’ll see the actual IPs that the Service routes to, which is super handy when something breaks and you want to blame DNS (but it’s actually your selector).
Advanced Example: Headless Service with StatefulSet
Headless Services (ClusterIP: None
) let each pod in a StatefulSet get its own DNS record. That’s useful for databases like Cassandra, RabbitMQ, or anyone who hates load balancers.
1apiVersion: v1
2kind: Service
3metadata:
4 name: my-db
5spec:
6 clusterIP: None
7 selector:
8 app: my-db
9 ports:
10 - port: 9042
11 name: cql
Combined with a StatefulSet, you get stable DNS like: my-db-0.my-db.default.svc.cluster.local
And yes, EndpointSlices make this possible.
When Things Go Weird
Sometimes you have a Service, but the Endpoints are… empty.
No IPs! Just vibes.
Common causes:
- The selector doesn’t match any pod labels
- The pods aren’t
Ready
- You’re using a headless Service and didn’t configure DNS properly
- The network plugin (CNI) is misbehaving
- The Service and pods are in different namespaces (rookie mistake, we’ve all been there)
Use kubectl describe service my-service
and kubectl get pods --show-labels
to troubleshoot.
Best Practices
- Don’t touch Endpoints manually: They’re auto-generated. Editing them is like editing
/proc
: mostly a bad idea. - Use labels wisely: Services live and die by their selectors.
- Use readiness probes: Kubernetes won’t route traffic to a pod unless it’s
Ready
. No probe = no traffic. - Headless Services + StatefulSets = ❤️: Want stable DNS for individual pods? Use
ClusterIP: None
with StatefulSets and enjoy DNS likeweb-0.my-service
. - Use
kubectl get endpointslices
for clarity: It’s the future. Embrace it.
Wrapping It Up
Endpoints and EndpointSlices are the invisible magic behind every Kubernetes Service. They keep traffic flowing to the right pods, even as your cluster scales or reshuffles.
TL;DR:
- Endpoints are the OGs—still around, but slowly being phased out
- EndpointSlices are the scalable future
- Kubernetes maintains both for compatibility, but you should understand slices
- Don’t forget to check them when debugging—services aren’t psychic
So next time you hit your Service
and it works, thank your Endpoints. Or better yet, thank your EndpointSlices—they’re doing most of the heavy lifting now.
Because behind every good Service is a slice... or two.
Posts in this series
- Kubernetes Deployments: Like a Boss (Who Delegates Everything)
- Kubernetes StatefulSets: Because Some Pods Need to Remember Things
- Kubernetes Services: The Network Matchmakers
- Kubernetes Ingress: Your Cluster's Traffic Director
- Kubernetes Ingress: 7 Common Mistakes (and How to Avoid Them)
- Kubernetes Network Policies: Your Cluster’s Traffic Bouncer
- Kubernetes Endpoints & EndpointSlices: Who’s Really Behind That Service?
- Kubernetes RBAC: Who Can Do What, and Where?
- Kubernetes Pod Affinity and Anti-Affinity: Scheduling With Style
- Kubernetes Volumes: Where Pods Keep Their Stuff