The original Endpoint had one resource per Service and all the endpoints (ports) of a service were tracked by this resource. This caused issues with scalability as the cluster and services grew.
With the new EndpointSlice, there is an EndpointSlice resource per endpoint per service. I am wondering how does this solve the scalability issue? Each pod in a service supports all the ports (endpoints) opened by the service. That said, won’t each pod find a reference entry in each of the endpointSlice related to that service? Will that not require simultaneous update of multiple EndpointSlice resources every time there is a change in the pod (new addition or deletion)?
Example: Say there is a Service A. It has got 3 pods P1, P2, P3. The Service A has 3 open ports (endpoints). Now each of the pods support these endpoints. So if we are to create one EndpointSlice resource per service, per endpoint (port), then we will have 3 EndpointSlice resources ES1, ES2 and ES3 for the Service A corresponding to each of its endpoints. Now since each of the pods P1, P2and P3 support all 3 endpoints each of the EndpointSlice ES1, ES2 and ES3 will have a reference to each of the pod’s IP address and port. So in case there is a newly adde pod (with new IP address ofcourse) oran existing pod gets replaces, would these events not require update of all 3 endpoint slice resources? Will this not be more work than before? How does this improve scalability exactly?
Per service there is only one endpointslice
object. So in your example there will be only one endpointslice
object which will have all the 3 pod ip and port and it will group network endpoints
together by unique service
and port
combinations.
Read more here about what kind of issues the earlier endpoint object faced.
The official KEP talks about the some performance comparison between endpoints and endpointslice api.
The previous endpoints objects looks like
Subsets:
Addresses: 192.168.238.108,192.168.238.109,192.168.238.110
As you can see endpoints object for a service contains all the individual endpoints of that service. As a result, whenever even a single pod in a service is added/updated/deleted, the whole endpoints object (which includes even the other endpoints that didn't change) is re-computed, written to storage and sent to all readers.
New endpoint slice object looks like
Ports:
Name Port Protocol
---- ---- --------
http-queueadm 8022 TCP
http-autometric 9090 TCP
http-usermetric 9091 TCP
http 8012 TCP
Endpoints:
- Addresses: 192.168.238.108
Conditions:
Ready: true
Hostname: <unset>
TargetRef: Pod/helloworld-go-rk4j8-deployment-588ccc679b-4spkx
Topology: kubernetes.io/hostname=ip-10-0-0-92
- Addresses: 192.168.238.110
Conditions:
Ready: true
Hostname: <unset>
TargetRef: Pod/helloworld-go-rk4j8-deployment-588ccc679b-tdq24
Topology: kubernetes.io/hostname=ip-10-0-0-92
- Addresses: 192.168.238.109
Conditions:
Ready: true
Hostname: <unset>
TargetRef: Pod/helloworld-go-rk4j8-deployment-588ccc679b-bfxb8
Topology: kubernetes.io/hostname=ip-10-0-0-92
As you can see the endpoints are grouped and so when there is change i.e a single pod in a service is added/updated/deleted only relevant group can be updated rather than updating the entire object which improves the performance.