Skip to content

Commit f361e4b

Browse files
authored
Merge pull request #3950 from lauralorenz/endpointslices-optional
KEP-1645: make endpointslices optional, but structure required if they exist
2 parents 01efead + db81549 commit f361e4b

File tree

1 file changed

+95
-52
lines changed
  • keps/sig-multicluster/1645-multi-cluster-services-api

1 file changed

+95
-52
lines changed

Diff for: keps/sig-multicluster/1645-multi-cluster-services-api/README.md

+95-52
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ tags, and then generate with `hack/update-toc.sh`.
9999
- [DNS](#dns)
100100
- [No PTR records necessary for multicluster DNS](#no-ptr-records-necessary-for-multicluster-dns)
101101
- [Not allowing cluster-specific targeting via DNS](#not-allowing-cluster-specific-targeting-via-dns)
102-
- [EndpointSlice](#endpointslice)
102+
- [Tracking Endpoints](#tracking-endpoints)
103+
- [Using <code>EndpointSlice</code> objects to track endpoints](#using--objects-to-track-endpoints)
103104
- [Endpoint TTL](#endpoint-ttl)
104105
- [Constraints and Conflict Resolution](#constraints-and-conflict-resolution)
105106
- [Global Properties](#global-properties)
@@ -546,20 +547,6 @@ resolution](#constraints-and-conflict-resolution)). If all `ServiceExport`
546547
instances are deleted, each `ServiceImport` will also be deleted from all
547548
clusters.
548549

549-
Since a given `ServiceImport` may be backed by multiple `EndpointSlices`, a
550-
given `EndpointSlice` will reference its `ServiceImport` using the label
551-
`multicluster.kubernetes.io/service-name` similarly to how an `EndpointSlice` is
552-
associated with its `Service` in a single cluster.
553-
554-
Each imported `EndpointSlice` will also have a
555-
`multicluster.kubernetes.io/source-cluster` label with the cluster id, a
556-
clusterset-scoped unique identifier for the cluster. The `EndpointSlice`s
557-
imported for a service are not guaranteed to exactly match the originally
558-
exported `EndpointSlice`s, but each slice is guaranteed to map only to a single
559-
source cluster.
560-
561-
The mcs-controller is responsible for managing imported `EndpointSlice`s.
562-
563550
```golang
564551
// ServiceImport describes a service imported from clusters in a clusterset.
565552
type ServiceImport struct {
@@ -641,6 +628,7 @@ type ClusterStatus struct {
641628
Cluster string `json:"cluster"`
642629
}
643630
```
631+
644632
```yaml
645633
apiVersion: multicluster.k8s.io/v1alpha1
646634
kind: ServiceImport
@@ -659,52 +647,28 @@ spec:
659647
status:
660648
clusters:
661649
- cluster: us-west2-a-my-cluster
662-
---
663-
apiVersion: discovery.k8s.io/v1beta1
664-
kind: EndpointSlice
665-
metadata:
666-
name: imported-my-svc-cluster-b-1
667-
namespace: my-ns
668-
labels:
669-
multicluster.kubernetes.io/source-cluster: us-west2-a-my-cluster
670-
multicluster.kubernetes.io/service-name: my-svc
671-
ownerReferences:
672-
- apiVersion: multicluster.k8s.io/v1alpha1
673-
controller: false
674-
kind: ServiceImport
675-
name: my-svc
676-
addressType: IPv4
677-
ports:
678-
- name: http
679-
protocol: TCP
680-
port: 80
681-
endpoints:
682-
- addresses:
683-
- "10.1.2.3"
684-
conditions:
685-
ready: true
686-
topology:
687-
topology.kubernetes.io/zone: us-west2-a
688650
```
689651
690652
The `ServiceImport.Spec.IP` (VIP) can be used to access this service from within
691653
this cluster.
692654

655+
693656
### ClusterSet Service Behavior Expectations
694657

695658
#### Service Types
696659

697660
- `ClusterIP`: This is the straightforward case most of the proposal assumes.
698-
Each `EndpointSlice` associated with the exported service is combined with
699-
slices from other clusters to make up the clusterset service. They will be
700-
imported to the cluster behind the clusterset IP, with a `ServiceImport` of
701-
type `ClusterSetIP`. [Details](#EndpointSlice)
661+
Each endpoint from a producing cluster associated with the exported service is
662+
aggregated with endpoints from other clusters to make up the clusterset
663+
service. They will be imported to the cluster behind the clusterset IP, with a
664+
`ServiceImport` of type `ClusterSetIP`. The details on how the clusterset IP
665+
is allocated or how the combined slices are maintained may vary by
666+
implementation; see also [Tracking Endpoints](#TrackingEndpoints).
702667
- `ClusterIP: none` (Headless): Headless services are supported and will be
703-
imported with a `ServiceImport` and `EndpointSlices` like any other
704-
`ClusterIP` service, but do not configure a VIP and must be consumed via
705-
[DNS](#DNS). Their `ServiceImport`s will be of type `Headless`. A
706-
multi-cluster service's headlessness is derived from it's constituent exported
707-
services according to the [conflict resolution
668+
imported with a `ServiceImport` like any other `ClusterIP` service, but do not
669+
configure a VIP and must be consumed via [DNS](#DNS). Their `ServiceImport`s
670+
will be of type `Headless`. A multi-cluster service's headlessness is derived
671+
from it's constituent exported services according to the [conflict resolution
708672
policy](#constraints-and-conflict-resolution).
709673

710674
_Exporting a non-headless service to an otherwise headless service can
@@ -713,7 +677,7 @@ this cluster.
713677
deployment error. Conditions and events on the `ServiceExport` will be used to
714678
communicate conflicts to the user._
715679
- `NodePort` and `LoadBalancer`: These create `ClusterIP` services that would
716-
sync as expected. For example If you export a `NodePort` service, the
680+
sync as expected. For example if you export a `NodePort` service, the
717681
resulting cross-cluster service will still be a clusterset IP type. The local
718682
service will not be affected. Node ports can still be used to access the
719683
cluster-local service in the source cluster, and only the clusterset IP will
@@ -891,8 +855,25 @@ additional label gives additional context, which is implementation-dependent and
891855
may be used for instance to uniquely identify the cluster registry with which a
892856
cluster is registered.
893857
858+
### Tracking Endpoints
859+
860+
The specific mechanism by which the `mcs-controller` maintains references to the
861+
individual backends for an aggregated service is an implementation detail not
862+
fully prescribed by this specification. Implementations may depend on a higher
863+
level (possibly vendor-specific) API, offload to a load balancer or xDS server
864+
(like Envoy), or use Kubernetes networking APIs. If the implementation depends
865+
on Kubernetes networking APIs, specifically `EndpointSlice` objects, they must
866+
conform to the specification in the following section.
867+
868+
#### Using `EndpointSlice` objects to track endpoints
894869
895-
#### EndpointSlice
870+
_Optional to create, but specification defined if present._
871+
872+
If an implementation does create `discovery.k8s.io/v1 EndpointSlice`s, they must
873+
conform to the following structure. This structure was originally required as
874+
part of this specification in alpha, and are the structure on which other
875+
SIG-endorsed reference implementations and tooling, like the [CoreDNS
876+
multicluster plugin](https://github.com/coredns/multicluster/), depend.
896877
897878
When a `ServiceExport` is created, this will cause `EndpointSlice` objects for
898879
the underlying `Service` to be created in each importing cluster within the
@@ -904,6 +885,68 @@ controller, so that the endpoint slice controller doesn’t delete them.
904885
`EndpointSlices` will have an owner reference to their associated
905886
`ServiceImport`.
906887
888+
Since a given `ServiceImport` may be backed by multiple `EndpointSlices`, a
889+
given `EndpointSlice` will reference its `ServiceImport` using the label
890+
`multicluster.kubernetes.io/service-name` similarly to how an `EndpointSlice` is
891+
associated with its `Service` in a single cluster.
892+
893+
Each imported `EndpointSlice` will also have a
894+
`multicluster.kubernetes.io/source-cluster` label with the cluster id, a
895+
clusterset-scoped unique identifier for the cluster. The `EndpointSlice`s
896+
imported for a service are not guaranteed to exactly match the originally
897+
exported `EndpointSlice`s, but each slice is guaranteed to map only to a single
898+
source cluster.
899+
900+
If the implementation is using `EndpointSlice`s in this way, the mcs-controller
901+
is responsible for managing the imported `EndpointSlice`s and making sure they
902+
are conformant with this section.
903+
904+
```yaml
905+
apiVersion: multicluster.k8s.io/v1alpha1
906+
kind: ServiceImport
907+
metadata:
908+
name: my-svc
909+
namespace: my-ns
910+
spec:
911+
ips:
912+
- 42.42.42.42
913+
type: "ClusterSetIP"
914+
ports:
915+
- name: http
916+
protocol: TCP
917+
port: 80
918+
sessionAffinity: None
919+
status:
920+
clusters:
921+
- cluster: us-west2-a-my-cluster
922+
---
923+
apiVersion: discovery.k8s.io/v1beta1
924+
kind: EndpointSlice
925+
metadata:
926+
name: imported-my-svc-cluster-b-1
927+
namespace: my-ns
928+
labels:
929+
multicluster.kubernetes.io/source-cluster: us-west2-a-my-cluster
930+
multicluster.kubernetes.io/service-name: my-svc
931+
ownerReferences:
932+
- apiVersion: multicluster.k8s.io/v1alpha1
933+
controller: false
934+
kind: ServiceImport
935+
name: my-svc
936+
addressType: IPv4
937+
ports:
938+
- name: http
939+
protocol: TCP
940+
port: 80
941+
endpoints:
942+
- addresses:
943+
- "10.1.2.3"
944+
conditions:
945+
ready: true
946+
topology:
947+
topology.kubernetes.io/zone: us-west2-a
948+
```
949+
907950
```
908951
<<[UNRESOLVED]>>
909952
We have not yet sorted out scalability impact here. We hope the upper bound for

0 commit comments

Comments
 (0)