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: TCPThis 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.50This 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 theEndpointsresource will also delete the relatedEndpointSlice.
- Manually created EndpointSlice
 If you manually created theEndpointSlice(like the example above), deleting theEndpointswill not remove yourEndpointSlice. It is fully independent, as long as it’s not listed underownerReferencesin its metadata.
You can verify this with the command:
kubectl get endpointslice external-backend-static -o yaml | grep ownerReferencesIf 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-backendIf only your manually created slice (for example, external-backend-static) appears, you can safely delete the deprecated Endpoints resource:
kubectl delete endpoints external-backendMigrating 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.
