-
Notifications
You must be signed in to change notification settings - Fork 513
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
Adding GEP-3539: Gateway API to Expose Pods on Cluster-Internal IP Address (ClusterIP Gateway) #3608
base: main
Are you sure you want to change the base?
Adding GEP-3539: Gateway API to Expose Pods on Cluster-Internal IP Address (ClusterIP Gateway) #3608
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
apiVersion: gateway.networking.k8s.io/v1 | ||
kind: Gateway | ||
metadata: | ||
name: example-cluster-ip-gateway | ||
spec: | ||
addresses: | ||
- 10.12.0.15 | ||
gatewayClassName: cluster-ip | ||
listeners: | ||
- name: example-service | ||
protocol: TCP | ||
port: 8080 | ||
allowedRoutes: | ||
kinds: | ||
- kind: TCPRoute/CustomRoute |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
apiVersion: gateway.networking.k8s.io/v1 | ||
kind: GatewayClass | ||
metadata: | ||
name: cluster-ip | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this name "special" or can it be anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's intended that GatewayClass names can be any valid Kubernetes object name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See expanded question under https://github.com/kubernetes-sigs/gateway-api/pull/3608/files#r1964558745 |
||
spec: | ||
controllerName: "cluster-ip-controller" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this name "special" or can it be anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name can be anything but implementations must only reconcile GatewayClasses that has a Some implementations allow configuration of this string (for example, Contour allows it so that you can run multiple instances of Contour in a cluster). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that the behavior we want here? In Service, its a single object with (many) multiple controllers consuming it. If I want my service exposed to the CNI, kube-proxy, service mesh, observability platform, ... do I need to make N Gateways? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See expanded question under https://github.com/kubernetes-sigs/gateway-api/pull/3608/files#r1964558745 Agree with John's question, and I think it betrays a fundamental difference in perspective. I see this idea as "Services with a better API" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we're using the same object that can be used in other contexts though (ie Gateway), we need a way to disambiguate, and the way we have is GatewayClass. I'd be happy to see proposals around alternatives to GatewayClass, but I haven't seen anything to date that handles the problem that implementations of Gateway API almost always need multiple-namespace access, and the only currently available thing we have that's bigger than a single namespace is cluster-wide. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
kind: TCPRoute/CustomRoute | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this syntax There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the context, it appears that this is covering the base of "I'm not sure what actual Kind we're talking about here". @ptrivedi - if that's what you mean, I'd recommend leaving a comment next to it to explain and/or using an optional-selection notation like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was meant to say "It could be a TCPRoute or another kind of L4 route, custom or not". Will modify to incorporate @youngnick's suggestion. |
||
metadata: | ||
name: service-route | ||
spec: | ||
parentRefs: | ||
- name: example-cluster-ip-gateway | ||
rules: | ||
config: | ||
sessionAffinity: false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the indent wrong on this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not just the indent, this config section was meant to be under spec. Likely a copy/paste foobar, will fix. To explain further, I had brought this up as an open question/discussion point during the community meeting presentation. For Service features like internalTrafficPolicy, sessionAffinity, etc. (and possibly other things in the future), does it make sense to have a RouteConfig section under RouteSpec? FWIW, for the internal implementation of ClusterIP Gateway we are doing for multi-network environments, we use a custom route where we had some debate around whether these parameters should go directly under RouteSpec or in a separate section under RouteSpec. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are parts of the service API that are deeply entangled with the implementation details. If we can untangle them, great, but they likely are not "generic" enough to apply to just any Gateway, or even to any L4 or L3 Gateway. Let's look at the table from below: sessionAffinity: seems generally applicable to any L3 or L4 GW allocateLoadBalancerNodePorts: should be moot if NodePort is a different gateway than clusterIP or LB externalIPs: a gross hack that perhaps we can abandon externalTrafficPolicy: by definition does not apply to clusterIPs internalTrafficPolicy: by definition ONLY applies to cluster IPs. It's not clear to me if we could have a generic trafficDiustirbution: definitely matters for clusterIP, maybe is generic L4? ipFamily: this is a request to the GW IP allocator, so it probably makes sense as a parameter to the Gateway? How do we express v4 vs v6 today? publishNotReadyAddresses: This is related to endpoint selection which you are trying to factor out, but it IS used. headless service: I feel like this is a different "kind" of Gateway. The fact that it was implemented as a variation of ClusterIP rather than a distinct value for externalName: Again, this is probably a different kind of gateway type: obviated - the class of Gateway should capture the same concept space I can't tell if I just argued for a generic L4 Route or for a special VirtualService route or something else? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We don't. When requesting a static address, you can request either type (by string conversion, not by structured field), and it's up to the implementation to figure out if it can fulfill the request, and also what addresses to give if you don't specify anything. Note that implementations are totally allowed to give out multiple addresses here if no static addresses are speciffied. We do have a We also have #3616 to make the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, pre-allocated IPs matter a lot more for "north-south" than "east-west", but it seems inevitable that people want to express things like "IPv6 but you choose the address" or "dual-stack if possible, but single-stack is OK". The Service ipFamilyPolicy covers that and I will be shocked if you don't need essentially the same gamut of config. |
||
backendRefs: | ||
- kind: EndpointSelector | ||
port: 8080 | ||
name: exampleapp-app-pods | ||
--- | ||
apiVersion: gateway.networking.k8s.io/v1alpha1 | ||
kind: EndpointSelector | ||
metadata: | ||
name: exampleapp-app-pods | ||
spec: | ||
selector: | ||
- key: app | ||
value: exampleapp | ||
operator: In | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
apiVersion: networking.gke.io/v1alpha1 | ||
kind: EndpointSelector | ||
metadata: | ||
name: front-end-pods | ||
spec: | ||
kind: Pod | ||
selector: | ||
- key: app | ||
value: frontend | ||
operator: In |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
kind: TCPRoute | ||
metadata: | ||
name: service-route | ||
spec: | ||
parentRefs: | ||
- name: example-cluster-ip-gateway | ||
rules: | ||
config: | ||
sessionAffinity: false | ||
backendRefs: | ||
- kind: EndpointSelector | ||
port: 8080 | ||
name: front-end-pods | ||
weight: 100 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
# GEP-3539: ClusterIP Gateway - Gateway API to Expose Pods on Cluster-Internal IP Address | ||
|
||
* Issue: [#3539](https://github.com/kubernetes-sigs/gateway-api/issues/3539) | ||
* Status: Memorandum | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should currently be The This also needs to be changed in the corresponding |
||
|
||
## TLDR | ||
|
||
Gateway API enables advanced traffic routing and can be used to expose a | ||
logical set of pods on a single IP address within a cluster. With some changes, | ||
it could be used as a next generation ClusterIP Service replacement, | ||
providing more flexibility and composability than the existing Service API. | ||
|
||
This comes at the expense of some additional configuration | ||
and manageability burden, but we believe that the additional value | ||
gained is worth the cost. | ||
|
||
## Goals | ||
|
||
* Define Gateway API usage to accomplish ClusterIP Service style behavior | ||
* Propose DNS layout and record format for ClusterIP Gateway | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem like we have fleshed this out. Compared to https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ we have just 1-2 sentences with a lot of ambiguity here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is correct, we haven't. DNS bit has been identified as a good candidate to be split out into its own GEP There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've expressed elsewhere, but will say again - my ideal outcome is that users could 1-for-1 convert Services (maybe not "while running", but convert YAML) into this new form of Gateway and not change their clients at all. Ideally this new thing gets the same name as the equivalent Service. |
||
* Extend the use of Gateway API to provide NodePort and LoadBalancer Service | ||
type of functionality | ||
|
||
## Non-Goals | ||
|
||
* Make significant changes to Gateway API | ||
* Provide path for existing ClusterIP Services in a cluster to migrate to | ||
Gateway API model | ||
|
||
## API Changes Summary | ||
|
||
* EndpointSelector is recognized as a backend | ||
* DNS record format for ClusterIP Gateways | ||
|
||
## Introduction | ||
|
||
Gateway API provides a generic and composable model for defining L4 and L7 | ||
routing in Kubernetes. Very simply, it describes how to get traffic into pods. | ||
ClusterIP provides similar functionality of an ingress point for routing traffic | ||
into pods. As the Gateway API has evolved, there have been discussions around whether | ||
it can be a substitute for the increasingly complex and overloaded Service API. This | ||
document aims to describe what this could look like in practice, with a focus on | ||
ClusterIP and a brief commentary on how the concept design can be extended to | ||
accommodate LoadBalancer and NodePort Services. | ||
|
||
## Overview | ||
|
||
Gateway API can be thought of as decomposing Service API into multiple separable | ||
components that allow for definition of the ClusterIP address and listener configuration | ||
(Gateway resource), implementation specifics and common configuration (GatewayClass | ||
resource), and routing traffic to backends (Route resource). | ||
|
||
### Limitations of Service API | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to be realistic here and acknowledge the benefits of the Service API from a user's POV - which I think we could summarize as that, for simple use cases, its very simple. It's only one object, as opposed to (at minimum) four in the simplest case here (GatewayClass, Gateway, Route, and EndpointSelector). I completely agree that breaking Service apart for more advanced use cases is useful, but we should acknowledge the reason why it's stuck around for so long - the level of simplicity and flexibility it has allows folks to get started much more easily. Additionally, Service is a GA API that's not going anywhere, so we need to be very clear that we're not talking about deprecating or replacing Service with this. As with Gateway API north/south and Ingress, the GA core resource is going to stick around, but this proposal is about giving us a better base to look at adding features to rather than trying to fit them into the existing, overloaded Service construct. Speaking from experience, putting a section outlining this into this document now will save a lot of discussion later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 agree, which is why, IMO, the best path forward here is making Service the higher level API that decomposes into these resources. Then you can chose to break the abstraction and manually configure the underlying resources (as you can do today by manually creating EndpointSlice!). Otherwise we end up with a split universe indefinitely There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whether literally |
||
|
||
Besides what has been discussed in the past about Service API maintainability, evolvability, | ||
and complexity concerns, see: https://www.youtube.com/watch?v=Oslwx3hj2Eg, we ran into | ||
additional practical concerns that rendered Service API insufficient for the needs at hand. | ||
|
||
Service IPs can only be assigned out of the ServiceCIDR range configured for the API server. | ||
While Kubernetes 1.31 added a Beta feature that allows for the Extension of Service IP Ranges, | ||
there have been use cases where multi-NIC pods (pods with multiple network interfaces) require | ||
the flexibility of specifying different ServiceCIDR ranges to be used for ClusterIP services | ||
corresponding to the multiple different networks. There are strict traffic splitting and network | ||
isolation requirements that demand non-overlapping ServiceCIDR ranges for per-network ClusterIP | ||
service groups. Because of the way service definition and IP address allocation are tightly | ||
coupled in API server, it is not possible to use the current Service API to achieve this model | ||
without resorting to inelegant and klugey implementations. | ||
|
||
Gateway API also satisfies, in a user-friendly and uncomplicated manner, the need for advanced | ||
routing and load balancing capabilities in order to enable canary rollouts, weighted traffic | ||
distribution, isolation of access and configuration. | ||
|
||
### Service Model to Gateway API Model | ||
|
||
 | ||
|
||
### EndpointSelector as Backend | ||
|
||
A Route can forward traffic to the endpoints selected via selector rules defined in EndpointSelector. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, I can imagine a path toward maybe making this a regular core feature. I am sure that it would be tricky but I don't think it's impossible. Eg. Define a Service with selector foo=bar. That triggers us to create a PodSelector for foo=bar. That triggers the endpoints controller(s) to do their thing. Same as we do with IP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting thought. For starters at least, there seemed to be agreement on having a GEP for EndpointSelector as the next step. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As always, Gateway proves something is a good idea, then core steals the spotlight. |
||
While Service is the default resource kind of the referent in backendRef, EndpointSelector is | ||
suggested as an example of a custom resource that implementations could have to attach pods (or | ||
potentially other resource kinds) directly to a Route via backendRef. | ||
|
||
```yaml | ||
{% include 'standard/clusterip-gateway/tcproute-with-endpointselector.yaml' %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these does not render. or does it suppose to be like this? see https://github.com/ptrivedi/gateway-api/blob/gep-clusterip-gateway/geps/gep-3539/index.md There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is. Please see the deploy preview here: https://deploy-preview-3608--kubernetes-sigs-gateway-api.netlify.app/geps/gep-3539/ Also added this to the PR description: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, wasnt aware of that page. |
||
``` | ||
|
||
The EndpointSelector object is defined as follows. It allows the user to specify which endpoints | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to have a config field so we can have implementation specific parameters? |
||
should be targeted for the Route. | ||
|
||
```yaml | ||
{% include 'standard/clusterip-gateway/endpointselector.yaml' %} | ||
``` | ||
|
||
To allow more granular control over traffic routing, there have been discussions around adding | ||
support for using Kubernetes resources besides Service (or external endpoints) directly as backendRefs. | ||
Gateway API allows for this flexibility, so having a generic EndpointSelector resource supported as a | ||
backendRef would be a good evolutionary step. | ||
|
||
### User Journey | ||
|
||
Infrastructure provider supplies a GatewayClass corresponding to the type of service-like behavior to | ||
be supported. | ||
|
||
Below is the example of a GatewayClass for ClusterIP support: | ||
```yaml | ||
{% include 'standard/clusterip-gateway/clusterip-gatewayclass.yaml' %} | ||
``` | ||
|
||
The user must then create a Gateway in order to configure and enable the behavior as per their intent: | ||
```yaml | ||
{% include 'standard/clusterip-gateway/clusterip-gateway.yaml' %} | ||
``` | ||
|
||
By default, IP address(es) from a pool specified by a CIDR block will be assigned unless a static IP is | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the default path should be to allocate from the same ServiceCIDR resource. If you need an IP from a different resource you would do something different. Either a different class or a different allocator or something. |
||
configured in the _addresses_ field as shown above. The CIDR block may be configured using a custom CR. | ||
Subject to further discussion, it may make sense to have a GatewayCIDR resource available upstream to | ||
specify an IP address range for Gateway IP allocation. | ||
|
||
Finally the specific Route and EndpointSelector resources must be created in order to set up the backend | ||
pods for the configured ClusterIP. | ||
```yaml | ||
{% include 'standard/clusterip-gateway/customroute.yaml' %} | ||
``` | ||
|
||
### Backends on Listeners | ||
|
||
As seen above, Gateway API requires at least three CRs to be defined. This introduces some complexity. | ||
GEP-1713 proposes the addition of a ListenerSet resource to allow sets of listeners to attach to a Gateway. | ||
As a part of discussions around this topic, the idea of directly adding backendRefs to listeners has come | ||
up. Allowing backendRefs directly on the listeners eliminates the need to have Route objects for simple | ||
cases. More complex traffic splitting and advanced load balancing cases can still use Route attachments via | ||
allowedRoutes. | ||
|
||
### DNS | ||
|
||
ClusterIP Gateways in the cluster need to have consistent DNS names assigned to allow ClusterIP lookup by | ||
name rather than IP address. DNS A and/or AAAA record creation needs to happen when Kubernetes publishes | ||
information about Gateways, in a manner similar to ClusterIP Service creation behavior. DNS nameservers | ||
in pods’ /etc/resolv.conf need to be programmed accordingly by kubelet. | ||
|
||
``` | ||
<name of gateway>.<gateway-namespace>.gw.cluster.local | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think DNS is a fraught topic. We REALLY REALLY do not want to add more search paths, especially if they could cause ambiguous names. We could just lean on the "svc" space for this, since these are effectively services. We would need to define how to avoid collisions and I'd be lying if I said I had a great answer. Maybe, like IPAddress, we extract ServiceName to new resource, and whomever gets there first wins? That sort of transaction doesn't work well for CRDs but I guess it could be async. Weird failure modes. |
||
``` | ||
|
||
This results in the following search option entries in Pods’ /etc/resolv.conf: | ||
``` | ||
search <ns>.gw.cluster.local gw.cluster.local cluster.local | ||
``` | ||
|
||
### Cross-namespace References | ||
|
||
Gateway API allows for Routes in different namespaces to attach to the Gateway. | ||
|
||
When modeling ClusterIP service networking, the simplest recommendation might be to keep Gateway and Routes | ||
within the same namespace. While cross namespace routing would work and allow for evolved functionality, | ||
it may make supporting certain cases tricky. One specific example for this case is the pod DNS resolution | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given we are making a new DNS name, do we actually care to support this POD-IP DNS name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The pod-ip DNS name is for headless only: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#:~:text=Any%20Pods%20exposed,domain.example. Headless, in case of Gateway API would likely be expressed using a separate GatewayClass, in order to avoid conflating ClusterIP and Headless and provide clean separation of concerns. So, you are right, does not necessarily need to be supported for ClusterIP Gateway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we end up in a new DNS space, this whole proposal's value is diminished. IMO. |
||
support of the following format | ||
|
||
``` | ||
pod-ipv4-address.gateway-name.my-namespace.gw.cluster-domain.example | ||
``` | ||
|
||
If Gateway and Routes (and hence the backing pods) are in different namespaces, there arises ambiguity in | ||
whether and how to support this pod DNS resolution format. | ||
|
||
## LoadBalancer and NodePort Services | ||
|
||
Extending the concept further to LoadBalancer and NodePort type services follows a similar pattern. The idea | ||
is to have a GatewayClass corresponding to each type of service networking behavior that needs to be modeled | ||
and supported. | ||
|
||
 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. image missing or incorrect file name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was a missing image. Fixed. Thanks for catching |
||
|
||
Note that Gateway API allows flexibility and clear separation of concerns so that one would not need to | ||
configure cluster-ip and node-port when configuring a load-balancer. | ||
|
||
But for completeness, the case shown below demonstrates how load balancer functionality analogous to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of this proposal makes sense as a logic way to solve "If you had to implement Service using Gateway API primitives, how would you do it". What doesn't make sense to me is the why and the how this becomes something practically useful from a proposal to a thing in the real world. The diagram below shows 1 object becoming 8. Do we expect users to actually create these 8 objects? Which projects are expected to, and which are commited to, supporting these? Kube-proxy? Coredns? Various 3p CNIs (Cilium, calico, etc)? Service meshes? All gateway implementations? |
||
LoadBalancer Service API can be achieved using Gateway API. | ||
|
||
 | ||
|
||
## Additional Service API Features | ||
|
||
Services natively provide additional features as listed below (not an exhaustive list). Gateway API can be | ||
extended to provide some of these features natively, while others may be left up to the specifics of | ||
implementations. | ||
|
||
| Feature | ServiceAPI options | Gateway API possibilities | | ||
|---|---|---| | ||
| sessionAffinity | ClientIP <br /> NoAffinity | Route level | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does L4 Gateway support affinity? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not currently, no. |
||
| allocateLoadBalancerNodePorts | True <br /> False | Not supported for ClusterIP Gateway <br /> Supported for LoadBalancer Gateway | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could say N/A for this approach, since you can create LB type without NodePort - sort of simplification. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That might be clearer until further discussion on each of these. |
||
| externalIPs | List of externalIPs for service | Not supported? | | ||
| externalTrafficPolicy | Local <br /> Cluster | Supported for LB Gateways only, Route level | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are all interesting challenges which maybe need something more than a plain TCP Route? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A more generic L4Route that combines TCP/UDPRoutes? |
||
| internalTrafficPolicy | Local <br /> Cluster | Supported for ClusterIP Gateways only, Route level | | ||
| ipFamily | IPv4 <br /> IPv6 | Route level | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the IPs are specified only in the Gateway and not in the Routes, why would the ipFamily be at the Route Level? |
||
| publishNotReadyAddresses | True <br /> False | Route or EndpointSelector level | | ||
| ClusterIP (headless service) | IPAddress <br /> None | GatewayClass definition for Headless Service type | | ||
| externalName | External name reference <br /> (e.g. DNS CNAME) | GatewayClass definition for ExternalName Service type | | ||
|
||
## References | ||
|
||
* [Original Doc](https://docs.google.com/document/d/1N-C-dBHfyfwkKufknwKTDLAw4AP2BnJlnmx0dB-cC4U/edit) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: internal.gateway.networking.k8s.io/v1alpha1 | ||
kind: GEPDetails | ||
number: 3539 | ||
name: ClusterIP Gateway - Gateway API to Expose Pods on Cluster-Internal IP Address | ||
status: Experimental | ||
authors: | ||
- ptrivedi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does kube-proxy (or Cilium or Antrea or ...) know which Gateways it should be capturing traffic for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally that's handled by the rollup of Gateway -> GatewayClass. Implementations own GatewayClasses that specify the correct string in GatewayClass
spec.controllerName
. All Gateways in that GatewayClass in that GatewayClass would need to be serviced by an implementation that can fulfill this request (that is, it both has the required functionality, and, in this case of requesting a static address, is actually able to assign that address). In the case that an implementation cannot fulfil this Gateway for some reason, it must be marked as not Accepted (by having anAccepted
type condition in the Gateway's status withstatus: false
).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't tell if you are giving me a hard time or not :)
What I meant to ask is:
Service
as a built-in API is (more or less) universally implemented by on-node agents (kube-proxy, cilium or antrea, ovn, etc). If we are trying to offer a form of ClusterIPGateway
which replaces part of theService
API, how does a user express "this is a cluster IP gateway" in a portable way such that all of the implementations know "this is for me"?If each implementation has its own
controllerName
, and theGatewayClass
can be named anything the cluster admin wants, how does our poor beleaguered app operator know what to put in their YAML?Today they can say:
...and be confident that ANY cluster, regardless of which CNI, will allocate a virtual IP and route traffic.
I'd like to write a generic tool which does:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, okay, I see the use case, but this is the problem with extensions v core - we left the flexibility there for implementations, (for good reason), and now we don't have a way to define a default GatewayClass at all, even for specific use cases.
I think that practically, a tool like you describe would need to know the gatewayclass it was targeting, and output Gateways based on that.
We could conceivably have a convention and pick a reserved name (like
cni-clusterip
or something), but we've been reluctant in the past to do that, preferring the increased specificity of requiring people to specify something (even though there is a friction cost to be paid there).(And I wasn't trying to give you a hard time - I have details get pushed out of my head all the time, so wanted to make sure this hadn't happened here. 😄 But also, I wanted to help other readers understand too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hence my questions about "is this name special". One answer is "thou shalt use the name 'clusterip' and the 'clusterip' is the name thou shalt use", and just hope not to collide with users. Another answer is to define a sub-space of names that users can't currently use, or are exceedingly unlikely to be using e.g. k8s.io:clusterip. This is an appropriate place to ideate, right?