Starting with Kubernetes 1.33, the traditional Endpoints
API is officially deprecated. This change affects how Services map to backend Pods or external IPs. The newer EndpointSlice API provides better scalability, improved performance, and richer metadata capabilities.
If your cluster has been manually using Endpoints
to map a Service to an external backend (for example, when the backend is not running inside Kubernetes), it’s time to migrate to EndpointSlice
.
Example: Existing Endpoints-Based Configuration
Below is an example configuration using the deprecated Endpoints
API:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
labels:
app: app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- app.example.com
secretName: example-tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: external-backend
port:
number: 9000
---
apiVersion: v1
kind: Service
metadata:
name: external-backend
spec:
ports:
- port: 9000
protocol: TCP
targetPort: 9000
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-backend
subsets:
- addresses:
- ip: 192.168.1.50
ports:
- port: 9000
protocol: TCP
This configuration exposes the external IP 192.168.1.50:9000
via the Service external-backend
and an NGINX Ingress route.
In Kubernetes 1.33 and above, you will start seeing deprecation warnings when reading or writing Endpoints
objects. The new approach uses the EndpointSlice
API.
Feature | Endpoints | EndpointSlices |
---|---|---|
API Group | v1 | discovery.k8s.io/v1 |
Structure | Single object per Service | Multiple slice objects per Service |
Update cost | Rewrites full list | Updates only affected slice |
Scalability | Poor (limited to ~1000 endpoints) | Excellent (each slice ≈100 endpoints) |
Status | Deprecated | Stable (from v1.21) |
Migrating to EndpointSlice
You can replace the Endpoints
resource with a manually created EndpointSlice
as shown below:
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: external-backend-static
labels:
kubernetes.io/service-name: external-backend
addressType: IPv4
ports:
- name: ""
port: 9000
protocol: TCP
endpoints:
- addresses:
- 192.168.1.50
This EndpointSlice
links to the same Service (external-backend
) via the label kubernetes.io/service-name: external-backend
. Once applied, traffic routed through the Service and Ingress will continue to function exactly as before.
What Happens When You Delete Endpoints
If you previously had both Endpoints
and EndpointSlice
objects for the same Service, you might wonder what happens if you delete the Endpoints
.
There are two possibilities:
- Auto-generated EndpointSlice
If the EndpointSlice was automatically created by the Kubernetes controller (mirrored from an Endpoints object), deleting theEndpoints
resource will also delete the relatedEndpointSlice
. - Manually created EndpointSlice
If you manually created theEndpointSlice
(like the example above), deleting theEndpoints
will not remove yourEndpointSlice
. It is fully independent, as long as it’s not listed underownerReferences
in its metadata.
You can verify this with the command:
kubectl get endpointslice external-backend-static -o yaml | grep ownerReferences
If no owner is listed, the slice is managed manually and safe from automatic deletion.
Checking Existing Slices
Before deleting your old Endpoints
, you can list all related slices:
kubectl get endpointslice -l kubernetes.io/service-name=external-backend
If only your manually created slice (for example, external-backend-static
) appears, you can safely delete the deprecated Endpoints
resource:
kubectl delete endpoints external-backend
Migrating to EndpointSlice
ensures compatibility with future Kubernetes versions while improving scalability and performance. The migration is straightforward if you are manually defining external backends.
Simply create an EndpointSlice
resource that maps to your Service, remove the old Endpoints
, and your application traffic will continue to work seamlessly.