How is the EndpointSlice improve efficiency over the old Endpoint resource?

6/27/2020

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?

-- adi
kubernetes

1 Answer

6/27/2020

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.

-- Arghya Sadhu
Source: StackOverflow