Skip to content

KEP-1645: define dual stack policies and fields #5264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions keps/sig-multicluster/1645-multi-cluster-services-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,6 @@ aware routing, but that API is currently in flux. As a result this proposal is
only suited to same-region multi-cluster services until the topology API
progresses.

As the plan for dual stack support is finalized, the Multi-Cluster Services API
will follow dual stack Service design. Until then, dual stack will not be
supported.

[Service Topology API]:
https://kubernetes.io/docs/concepts/services-networking/service-topology/

Expand Down Expand Up @@ -517,6 +513,15 @@ and `spec.exportedAnnotations`. Exporting labels and annotations is optionally
supported by MCS-API implementations. If supported, annotations or labels must
not be exported from the `metadata` of the `Service` or `ServiceExport` resources.

An implementation may use the `ipFamilies` field from the exported Services as
a hint to influence the `IPs` and `ipFamilies` of the ServiceImport object.
The exact mechanism for determining those fields is implementation-defined.

Also note that even in a dual stack cluster regular Services are by default SingleStack
which might default to IPv4 or IPv6 depending on the cluster configuration and there
are various constraints when mutating `ipFamilies` and `ipFamilyPolicy` on a Service
(see [ref](https://kubernetes.io/docs/concepts/services-networking/dual-stack/)).

Deleting a `ServiceExport` will stop exporting the name-mapped `Service`.

#### Restricting Exports
Expand Down Expand Up @@ -590,10 +595,12 @@ const (
type ServiceImportSpec struct {
// +listType=atomic
Ports []ServicePort `json:"ports"`
// +kubebuilder:validation:MaxItems:=1
// +kubebuilder:validation:MaxItems:=2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn’t we have this on IPFamilies too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regular services doesn't seems to have it (while it does for the clusterIPs field) but I don't mind adding it there too

Copy link
Member

@mikemorris mikemorris Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this actually be limited at all? It's not on the actual Service resource, and IIRC we had agreed that ServiceImport ports field should be the intersection of ports from Services exposed by a ServiceExport. (The KEP says union currently, but I believe we had decided this should be corrected to avoid publishing ports on the "frontend" which may not be available on some "backends").

Copy link
Member Author

@MrFreezeex MrFreezeex Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and IIRC we had agreed that ServiceImport ports

No we didn't, it's still is union and there is no one to my knowledge that have an active PR/doing something about this

Also note that the fields targeted here is the ips not the ports 😅

Copy link
Member

@mikemorris mikemorris Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also note that the fields targeted here is the ips not the ports 😅

Oops! Just read the diff wrong.

// +optional
IPs []string `json:"ips,omitempty"`
// +optional
IPFamilies []corev1.IPFamily `json:"ipFamilies,omitempty"`
// +optional
Type ServiceImportType `json:"type"`
// +optional
SessionAffinity corev1.ServiceAffinity `json:"sessionAffinity"`
Expand Down Expand Up @@ -655,6 +662,8 @@ metadata:
spec:
ips:
- 42.42.42.42
ipFamilies:
- IPv4
Comment on lines +665 to +666
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, IPV4 and IPV6 format are quite different, are the formats in the "ips" field alone not enough for the consumer to discern? I assume that the consumer knows what IP family it can support.

Copy link
Member Author

@MrFreezeex MrFreezeex Apr 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field is more aimed toward the allocation of the IPs than what happens after the IPs are already actually allocated a bit like the current type field or even how the ipFamilies field behave on a regular Service.

For instance for Cilium we would most likely want to do an intersection of all the ipFamilies in the exported Services which would put this as relevant as the other fields to "allocate" the IPs (meaning to create the derived service as it how we do this) to us essentially.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, IIRC, this is for some controller to act on this field? Are we not in the process of moving the serviceImport to either status or root?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sure what you mean but yes our controller will use this to create the derived service with the appropriate IPFamily

type: "ClusterSetIP"
ports:
- name: http
Expand Down Expand Up @@ -708,12 +717,16 @@ this cluster.

#### ClusterSetIP

A non-headless `ServiceImport` is expected to have an associated IP address, the
clusterset IP, which may be accessed from within an importing cluster. This IP
may be a single IP used clusterset-wide or assigned on a per-cluster basis, but
is expected to be consistent for the life of a `ServiceImport` from the
perspective of the importing cluster. Requests to this IP from within a cluster
will route to backends for the aggregated Service.
A non-headless `ServiceImport` is expected to have associated IP addresses, the
clusterset IPs, which may be accessed from within an importing cluster. These IPs
may be used clusterset-wide or assigned on a per-cluster basis, but is expected
to be consistent for the life of a `ServiceImport` from the perspective of the
importing cluster. Requests to these IPs from within a cluster will route to
backends for the aggregated Service. The `IPs` field must correspond to the
protocols defined in the `ipFamilies` field, if specified. How the `ipFamilies`
field is determined is implementation-defined, for instance it might correspond
to what IP protocols the constituent `ServiceExport`s support or only the IP
protocols that the local cluster supports.

Note: this doc does not discuss `NetworkPolicy`, which cannot currently be used
to describe a selector based policy that applies to a multi-cluster service.
Expand Down