CKA — Endpoints & EndpointSlices

5 minute read

CKA Exam Domain

Domain Weight
Services & Networking 20%

Understanding how Endpoints and EndpointSlices work is key to troubleshooting Services on the CKA exam. If a Service isn’t routing traffic correctly, checking Endpoints is often the first debugging step.

How Endpoints Work

When you create a Service with a label selector, Kubernetes automatically creates an Endpoints object with the same name. This Endpoints object contains the IP addresses of all Pods that match the Service’s selector.

Here’s the flow:

  1. You create a Service with selector: app: web
  2. Kubernetes finds all Pods with app: web label that are in Ready state
  3. An Endpoints object is created listing those Pod IPs and ports
  4. kube-proxy reads the Endpoints and configures routing rules

Whenever Pods are created, deleted, or change readiness state, the Endpoints object is automatically updated.

Viewing Endpoints

# List endpoints for a specific service
kubectl get endpoints web-svc

# Example output:
# NAME      ENDPOINTS                                   AGE
# web-svc   10.244.1.5:8080,10.244.2.8:8080,10.244.3.3:8080   5m

# Get detailed endpoint information
kubectl describe endpoints web-svc

# List all endpoints in the namespace
kubectl get endpoints

Each entry in the Endpoints list is a <PodIP>:<Port> pair. If a Service has multiple ports defined, the Endpoints object tracks all of them.

EndpointSlices

EndpointSlices are the modern, scalable replacement for Endpoints. Instead of storing all backend Pod IPs in a single object, EndpointSlices break them into smaller chunks (up to 100 endpoints per slice by default).

Why does this matter? For large Services with hundreds of Pods, a single Endpoints object becomes huge. Every time a single Pod changes, the entire Endpoints object must be updated and propagated — this is expensive. EndpointSlices solve this by splitting the data into manageable pieces.

# List EndpointSlices
kubectl get endpointslices

# Example output:
# NAME            ADDRESSTYPE   PORTS   ENDPOINTS                     AGE
# web-svc-abc12   IPv4          8080    10.244.1.5,10.244.2.8,...     5m

# Describe an EndpointSlice
kubectl describe endpointslice web-svc-abc12

EndpointSlices are automatically created and managed by the EndpointSlice controller. You don’t need to create them manually.

Endpoints vs EndpointSlices

Feature Endpoints EndpointSlices
Scalability Single object, all IPs Split into chunks (default 100 per slice)
Update efficiency Entire object rewritten on change Only affected slice updated
Default since Kubernetes v1.0 Kubernetes v1.21 (default)
Max per object ~5000 (soft limit) 100 per slice (configurable)
Dual-stack support Limited Native IPv4/IPv6 support

In modern Kubernetes clusters, EndpointSlices are the default. The Endpoints object still exists for backward compatibility.

When Endpoints Are Empty

If you see a Service with no Endpoints, it means no Pods are matching the selector. Common causes:

  1. No Pods exist — The Deployment has 0 replicas or hasn’t been created
  2. Wrong labels — The Pod labels don’t match the Service selector
  3. Pods not Ready — Pods exist but readiness probes are failing
  4. Wrong namespace — Pods are in a different namespace than the Service

Debugging steps:

# Check the Service selector
kubectl describe svc web-svc | grep Selector

# Check if Pods have matching labels
kubectl get pods --show-labels

# Check Pod readiness
kubectl get pods
# Look for READY column — should show 1/1 (or n/n)

# Check endpoints
kubectl get endpoints web-svc

This is a very common CKA exam troubleshooting scenario — a Service that isn’t working because of mismatched labels.

Manual Endpoint Management

Sometimes you need a Service that points to an external resource (like a database outside the cluster) that doesn’t have Pods. You can create a Service without a selector and manually define the Endpoints.

Step 1: Create a Service without a selector:

apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

Notice there’s no selector field — Kubernetes won’t auto-create Endpoints.

Step 2: Create the Endpoints manually:

apiVersion: v1
kind: Endpoints
metadata:
  name: external-db    # Must match the Service name
subsets:
  - addresses:
      - ip: 192.168.1.100
      - ip: 192.168.1.101
    ports:
      - port: 3306

Now Pods in the cluster can access the external database via external-db:3306.

ExternalName Services

An alternative to manual Endpoints for external resources is the ExternalName Service type:

apiVersion: v1
kind: Service
metadata:
  name: external-api
spec:
  type: ExternalName
  externalName: api.external-service.com

This returns a CNAME DNS record — no proxying, no Endpoints object. It’s simpler than manual Endpoints but only works for DNS-resolvable external services.

kubectl Commands

# View endpoints for a service
kubectl get endpoints web-svc

# View all endpoints
kubectl get endpoints

# Describe endpoints
kubectl describe endpoints web-svc

# View EndpointSlices
kubectl get endpointslices

# View EndpointSlices with labels
kubectl get endpointslices --show-labels

# Check which service an EndpointSlice belongs to
kubectl get endpointslices -l kubernetes.io/service-name=web-svc

Practice Questions

Q1. A Service named backend-svc exists but traffic isn’t reaching the Pods. How do you check if Endpoints are populated?

Show Answer
kubectl get endpoints backend-svc

If the ENDPOINTS column is empty (<none>), no Pods match the Service selector. Check the selector and Pod labels:

kubectl describe svc backend-svc | grep Selector
kubectl get pods --show-labels

Q2. Create a Service named legacy-db that routes traffic to an external IP 10.0.0.50 on port 5432 using manual Endpoints.

Show Answer
# Service without selector
apiVersion: v1
kind: Service
metadata:
  name: legacy-db
spec:
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432
---
# Manual Endpoints
apiVersion: v1
kind: Endpoints
metadata:
  name: legacy-db
subsets:
  - addresses:
      - ip: 10.0.0.50
    ports:
      - port: 5432
kubectl apply -f legacy-db.yaml
kubectl get endpoints legacy-db

Q3. What is the maximum number of endpoints stored in a single EndpointSlice by default?

Show Answer

100 endpoints per EndpointSlice by default. If a Service has more than 100 backend Pods, multiple EndpointSlice objects are created automatically.

Q4. A Service has the selector app: api but the Pods have the label app: api-v2. What happens?

Show Answer

The Endpoints object for the Service will be empty because the label selector doesn’t match. The Service won’t route traffic to any Pod. Fix by updating either the Service selector or the Pod labels:

# Option 1: Update Pod labels
kubectl label pods -l app=api-v2 app=api --overwrite

# Option 2: Update Service selector (edit the Service)
kubectl edit svc <service-name>

Q5. How do you list all EndpointSlices that belong to a Service named web-svc?

Show Answer
kubectl get endpointslices -l kubernetes.io/service-name=web-svc

EndpointSlices are labeled with kubernetes.io/service-name to associate them with their parent Service.

Updated: