Skip to content

Commit e13f841

Browse files
committed
make endpointslices optional, but structure required if they exist
Signed-off-by: lauralorenz <[email protected]>
1 parent 81d72f2 commit e13f841

File tree

1 file changed

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

1 file changed

+88
-52
lines changed

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

+88-52
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ 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+
- [EndpointSlices](#endpointslices)
103103
- [Endpoint TTL](#endpoint-ttl)
104104
- [Constraints and Conflict Resolution](#constraints-and-conflict-resolution)
105105
- [Global Properties](#global-properties)
@@ -546,20 +546,6 @@ resolution](#constraints-and-conflict-resolution)). If all `ServiceExport`
546546
instances are deleted, each `ServiceImport` will also be deleted from all
547547
clusters.
548548

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-
563549
```golang
564550
// ServiceImport describes a service imported from clusters in a clusterset.
565551
type ServiceImport struct {
@@ -641,6 +627,7 @@ type ClusterStatus struct {
641627
Cluster string `json:"cluster"`
642628
}
643629
```
630+
644631
```yaml
645632
apiVersion: multicluster.k8s.io/v1alpha1
646633
kind: ServiceImport
@@ -659,52 +646,28 @@ spec:
659646
status:
660647
clusters:
661648
- 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
688649
```
689650
690651
The `ServiceImport.Spec.IP` (VIP) can be used to access this service from within
691652
this cluster.
692653

654+
693655
### ClusterSet Service Behavior Expectations
694656

695657
#### Service Types
696658

697659
- `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)
660+
Each `EndpointSlice` in a producing cluster associated with the exported
661+
service is combined with slices from other clusters to make up the clusterset
662+
service. They will be imported to the cluster behind the clusterset IP, with a
663+
`ServiceImport` of type `ClusterSetIP`. The details on how the clusterset IP
664+
is allocated or how the combined slices are maintained may vary by
665+
implementation; see also [EndpointSlices](#EndpointSlices).
702666
- `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
667+
imported with a `ServiceImport` like any other `ClusterIP` service, but do not
668+
configure a VIP and must be consumed via [DNS](#DNS). Their `ServiceImport`s
669+
will be of type `Headless`. A multi-cluster service's headlessness is derived
670+
from it's constituent exported services according to the [conflict resolution
708671
policy](#constraints-and-conflict-resolution).
709672

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

0 commit comments

Comments
 (0)