@@ -17,44 +17,60 @@ just wants to create a Route that "works from the outside world" and she
17
17
really doesn't care what the Gateway is called.
18
18
19
19
Therefore, Ana would like a way to be able to rely on a default Gateway that
20
- she doesn't have to explicitly name, and can simply trust to exist.
20
+ she doesn't have to explicitly name, and can simply trust to exist. Ana
21
+ recognizes that this will involve ** giving up** a certain amount of control
22
+ over how requests reach her workloads. She's OK with that, and she understands
23
+ that it means that relying on a default Gateway is not always appropriate: for
24
+ example, if she needs to be sure that her Route is protected by specific
25
+ authorization policies, she should confer with Chihiro to make sure that she
26
+ explicitly specifies a Gateway that meets those requirements.
21
27
22
- [ Ana ] : https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
28
+ ## Definitions
29
+
30
+ - ** defaulted Route** : a Route that Ana creates without explicitly specifying
31
+ a Gateway
32
+
33
+ - ** default Gateway** : a Gateway that Chihiro has configured to accept
34
+ defaulted Routes
23
35
24
36
## Goals
25
37
26
38
- Give Ana a way to use Gateway API without having to explicitly specify a
27
- Gateway for every Route, ideally without mutating Routes.
39
+ Gateway for every Route, ideally without mutating Routes. (In other words,
40
+ give Ana an easy way to create a defaulted Route.)
28
41
29
- - Give Ana an easy way to determine which Gateway is the default, and which of
30
- her Routes are bound to it.
42
+ - Give Ana an easy way to determine which default Gateways are present in the
43
+ cluster, if any, and which of her Routes are currently bound to these
44
+ Gateways.
31
45
32
- - Continue supporting multiple Gateways in a cluster, while allowing exactly
33
- one of them to be the default Gateway .
46
+ - Continue supporting multiple Gateways in a cluster, while allowing zero or
47
+ more of them to be configured as default Gateways .
34
48
35
- - Allow [ Chihiro] to retain control over which Gateway is the default, so that
36
- they can ensure that it meets their requirements for security, performance,
37
- and other operational concerns.
49
+ - Allow [ Chihiro] to retain control over which Gateways accept defaulted
50
+ Routes, so that they can ensure that all Gateways meet their requirements
51
+ for security, performance, and other operational concerns.
38
52
39
- - Allow Chihiro to choose not to provide a default Gateway .
53
+ - Allow Chihiro to choose not to provide any default Gateways at all .
40
54
41
- - Allow Chihiro to rename, reconfigure, or replace the default Gateway at
55
+ - Allow Chihiro to rename, reconfigure, or replace any default Gateway at
42
56
runtime.
43
57
44
- - If Chihiro renames the default Gateway, Routes using the default Gateway
45
- MUST remain bound to the new default Gateway. Ana shouldn't need to go
46
- recreate all her Routes just because Chihiro is being indecisive.
58
+ - While Kubernetes does not allow renaming a resource, Chihiro MUST be able
59
+ to duplicate a default Gateway under a new name, then remove the old
60
+ default Gateway, without disrupting routing. Ana MUST NOT need to go
61
+ update all her Routes just because Chihiro is being indecisive about
62
+ naming.
47
63
48
- - Determine how (or if) to signal changes in functionality if the default
49
- Gateway implementation is changed. For example, suppose that Chihiro
50
- switches the default Gateway from an implementation that supports the
64
+ - Determine how (or if) to signal changes in functionality if a default
65
+ Gateway's implementation is changed. For example, suppose that Chihiro
66
+ switches a default Gateway from an implementation that supports the
51
67
` HTTPRoutePhaseOfTheMoon ` filter to an implementation that does not.
52
68
53
69
(Note that this problem is not unique to default Gateways; it affects
54
70
explicitly-named Gateways as well.)
55
71
56
- - Allow Chihiro to control which Routes may bind to the default Gateway, and
57
- to enumerate which Routes are currently bound to the default Gateway.
72
+ - Allow Chihiro to control which Routes may bind to a default Gateway, and to
73
+ enumerate which Routes are currently bound to a default Gateway.
58
74
59
75
- Support easy interoperation with common CI/CD and GitOps workflows.
60
76
@@ -63,25 +79,11 @@ she doesn't have to explicitly name, and can simply trust to exist.
63
79
64
80
## Non-Goals
65
81
66
- - Support multiple "default" Gateways in a single cluster. If Ana has to make
67
- a choice about which Gateway she wants to use, she'll need to be explicit
68
- about that.
69
-
70
- Loosening this restriction later is a possibility. For example, we may later
71
- want to consider allowing a default Gateway per namespace, or a default
72
- Gateway per implementation running in a cluster. However, these examples are
73
- not in scope for this GEP, in order to have a fighting chance of getting
74
- functionality into Gateway API 1.4.
75
-
76
- Additionally, note that providing support for Chihiro to swap the default
77
- Gateway without downtime may very well require supporting multiple default
78
- Gateways at the same time, since Kubernetes does not support atomic swaps of
79
- resources.
82
+ - Allow Ana to override Chihiro's choices for default Gateways for a given
83
+ Route without explicitly specifying the Gateway: a Route can either be
84
+ defaulted, or it MUST specify a Gateway explicitly.
80
85
81
- - Allow Ana to override Chihiro's choice for the default Gateway for a given
82
- Route without explicitly specifying the Gateway.
83
-
84
- - Require that every possible routing use case be met by a Route using the
86
+ - Require that every possible routing use case be met by a Route using a
85
87
default Gateway. There will be a great many situations that require Ana to
86
88
explicitly choose a Gateway; the existence of a default Gateway is not a
87
89
guarantee that it will be correct for any given use case.
@@ -161,15 +163,16 @@ Ana has easy access to this information, and that it's clear enough for her to
161
163
understand, is clearly important for many more reasons than just default
162
164
Gateways.
163
165
166
+ [ Ana ] : https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
164
167
[ Chihiro ] : https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#chihiro
165
168
[ Ian ] : https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ian
166
169
167
170
## API
168
171
169
172
The main challenge in the API design is to find a way to allow Ana to use
170
173
Routes without requiring her to specify the Gateway explicitly, while still
171
- allowing Chihiro and Ian to retain control over the Gateway and its
172
- configuration .
174
+ allowing Chihiro and Ian to retain control over Gateways and their
175
+ configurations .
173
176
174
177
An additional concern is CD tools and GitOps workflows. In very broad terms,
175
178
these tools function by applying manifests from a Git repository to a
@@ -189,30 +192,29 @@ Gateway controller write a new `parentRefs` stanza to the resource.
189
192
There has been (much!) [ discussion] about whether the ideal API for this
190
193
feature will mutate the ` parentRefs ` of a Route using a default Gateway to
191
194
reflect the Gateway chosen, or whether it should not, relying instead on the
192
- ` status ` stanza to carry this information. This is obviously a key point that
193
- will need resolution before this GEP can graduate.
195
+ ` status ` stanza to carry this information. Ultimately, mutating the ` spec ` of
196
+ a Kubernetes resource introduces complexity which we should avoid if it's not
197
+ required. Since we can gracefully provide default-Gateway functionality
198
+ without mutating ` parentRefs ` , we will rely on ` status ` instead of mutating
199
+ ` parentRefs ` .
194
200
195
201
[ discussion ] : https://github.com/kubernetes-sigs/gateway-api/pull/3852#discussion_r2140117567
196
202
197
- Finally, although support for multiple default Gateways is a non-goal for this
198
- GEP, it's worth noting that allowing Chihiro full control over the default
199
- Gateway is very much a goal, which includes giving Chihiro a clean way to swap
200
- one default Gateway for another. This is important because a zero-downtime
201
- swap implies having two default Gateways running at the same time, since
202
- Kubernetes does not support any sort of atomic swap operation.
203
-
204
203
### Gateway for Ingress (North/South)
205
204
206
205
There are two main aspects to the API design for default Gateways:
207
206
208
- 1 . Giving Ana a way to bind Routes to the default Gateway.
207
+ 1 . Giving Ana a way to indicate that a Route should be defaulted.
208
+
209
+ 2 . Giving Chihiro a way to control which Gateways (if any) will accept
210
+ defaulted Routes.
209
211
210
- 2 . Giving Chihiro a way to control which Gateway is the default, and to
211
- enumerate which Routes are bound to it .
212
+ 3 . Give anyone with read access to Routes (Ana, Chihiro, or Ian) a way to
213
+ enumerate which Routes are bound to the default Gateways .
212
214
213
- #### 1. Binding a Route to the Default Gateway
215
+ #### 1. Binding a Route to a Default Gateway
214
216
215
- For Ana to indicate that a Route should use the default Gateway, she MUST
217
+ For Ana to indicate that a Route should use a default Gateway, she MUST
216
218
leave ` parentRefs ` empty in the ` spec ` of the Route, for example:
217
219
218
220
``` yaml
@@ -227,7 +229,7 @@ spec:
227
229
port : 80
228
230
` ` `
229
231
230
- would route _all_ HTTP traffic arriving at the default Gateway to ` my-service`
232
+ would route _all_ HTTP traffic arriving at any default Gateway to ` my-service`
231
233
on port 80.
232
234
233
235
Note that Ana MUST omit `parentRefs` entirely : specifying an empty array for
@@ -236,20 +238,19 @@ Note that Ana MUST omit `parentRefs` entirely: specifying an empty array for
236
238
refuse to accept it. (Omitting `parentRefs` entirely will work much more
237
239
cleanly with GitOps tools than specifying an empty array.)
238
240
239
- Note also that if Ana specifies _any_ `parentRefs`, the default Gateway MUST
240
- NOT claim the Route unless of the `parentRefs` explicitly names the default
241
+ Note also that if Ana specifies _any_ `parentRefs`, a default Gateway MUST NOT
242
+ claim the Route unless of the `parentRefs` explicitly names that particular
241
243
Gateway. To do otherwise makes it impossible for Ana to define mesh-only
242
244
Routes, or to specify a Route that is meant to use only a specific Gateway
243
245
that is not the default. This implies that for Ana to specify a Route intended
244
246
to serve both north/south and east/west roles, she MUST explicitly specify the
245
- Gateway in `parentRefs`, even if that Gateway happens to be the default
246
- Gateway.
247
+ Gateway in `parentRefs`, even if that Gateway happens to be a default Gateway.
247
248
248
- All other characteristics of a Route using the default Gateway MUST behave the
249
- same as if the default Gateway were explicitly specified in `parentRefs`.
249
+ All other characteristics of a Route using a default Gateway MUST behave the
250
+ same as if the default Gateway(s) were explicitly specified in `parentRefs`.
250
251
251
- The default Gateway MUST use `status.parents` to announce that it has bound
252
- the Route, for example :
252
+ A default Gateway MUST use `status.parents` to announce that it has bound the
253
+ Route, for example :
253
254
254
255
` ` ` yaml
255
256
status:
@@ -264,40 +265,18 @@ status:
264
265
message: "Route is bound to default Gateway"
265
266
` ` `
266
267
267
- The default Gateway MUST NOT rewrite the `parentRefs` of a Route using the
268
+ A default Gateway MUST NOT rewrite the `parentRefs` of a Route using the
268
269
default Gateway; it MUST leave `parentRefs` empty. This becomes important if
269
- the default Gateway changes, or (in some situations) if GitOps tools are in
270
- play.
271
-
272
- # #### Enumerating Routes Bound to the Default Gateway
273
-
274
- To enumerate Routes bound to the default Gateway, Ana can look for Routes with
275
- no `parentRefs` specified, and then check the `status.parents` of those Routes
276
- to see if the Route has been claimed. This will also tell Ana which Gateway is
277
- the default, even if she doesn't have RBAC to query Gateway resources
278
- directly.
270
+ the set of default Gateways changes, or (in some situations) if GitOps tools
271
+ are in play.
279
272
280
- While this is possible with `kubectl get -o yaml`, it's not exactly a friendly
281
- user experience, so adding this functionality to a tool like `gwctl` would be
282
- a dramatic improvement. In fact, looking at the `status` of a Route is very
283
- much something that we should expect Ana to do often, whether or not default
284
- Gateways are in play; `gwctl` or something similar SHOULD be able to show her
285
- which Routes are bound to which Gateways in every case, not just with default
286
- Gateways.
273
+ # ### 2. Controlling which Gateways accept Defaulted Routes
287
274
288
- # #### Open Questions
289
-
290
- Should the Gateway also add a `condition` explicitly expressing that the Route
291
- has been claimed by the default Gateway, perhaps with `type : DefaultGateway`?
292
- This could help tooling like `gwctl` more easily enumerate Routes bound to the
293
- default Gateway.
294
-
295
- # ### 2. Controlling which Gateway is the Default
296
-
297
- Since Chihiro must be able to control which Gateway is the default, selecting
298
- the default Gateway must be an active configuration step taken by Chihiro,
299
- rather than any kind of implicit behavior. To that end, the Gateway resource
300
- will gain a new field, `spec.isDefault` :
275
+ Since Chihiro must be able to control which Gateways accept defaulted Routes,
276
+ configuring a Gateway to accept defaulted Routes must be an active
277
+ configuration step taken by Chihiro, rather than any kind of implicit
278
+ behavior. To that end, the Gateway resource will gain a new field,
279
+ `spec.isDefault` :
301
280
302
281
` ` ` go
303
282
type GatewaySpec struct {
@@ -325,9 +304,9 @@ If `spec.isDefault` is not present or is set to `false`, the Gateway MUST NOT
325
304
claim those Routes and MUST NOT set the `DefaultGateway` condition in its
326
305
` status` .
327
306
328
- # #### Access to the Default Gateway
307
+ # #### Access to a Default Gateway
329
308
330
- The rules for which Routes may bind to a Gateway do not change for the default
309
+ The rules for which Routes may bind to a Gateway do not change for a default
331
310
Gateway. In particular, if a default Gateway should accept Routes from other
332
311
namespaces, then it MUST include the appropriate `AllowedRoutes` definition,
333
312
and without such an `AllowedRoutes`, a default Gateway MUST accept only Routes
@@ -349,10 +328,11 @@ removed.
349
328
350
329
# #### Multiple Default Gateways
351
330
352
- Support for multiple default Gateways in a cluster is not one of the original
353
- goals of this GEP. However, allowing Chihiro to control which Gateway is the
354
- default - including being able to switch which Gateway is the default at
355
- runtime, without requiring downtime - is a goal.
331
+ Support for multiple default Gateways in a cluster was not one of the original
332
+ goals of this GEP. However, allowing Chihiro full control over which Gateways
333
+ accept defaulted Routes - including being able to change the set of default
334
+ Gateways at runtime, without requiring downtime - has always been a goal, and
335
+ this turns out to require support for multiple default Gateways.
356
336
357
337
Kubernetes itself will not prevent setting `spec.isDefault` to `true` on
358
338
multiple Gateways in a cluster, and it also doesn't support any atomic swap
@@ -375,11 +355,12 @@ possible options here.
375
355
Gateways in the cluster, then detecting that multiple Gateways have
376
356
` spec.isDefault` set to `true` is relatively straightforward.
377
357
378
- For option 2, every Gateway with `spec.isDefault` set to `true` can simply
379
- refuse to accept Routes with no `parentRefs` specified, behaving as if no
380
- Gateway has been chosen as the default. Each Gateway would also update its
381
- ` status` with a `condition` of type `DefaultGateway` and `status` false to
382
- indicate that it is not the default Gateway, for example :
358
+ In this case, every Gateway with `spec.isDefault` set to `true` would
359
+ simply refuse to accept Routes with no `parentRefs` specified, behaving as
360
+ if no Gateway has been chosen as the default. Each Gateway would also
361
+ update its `status` with a `condition` of type `DefaultGateway` and
362
+ ` status` false to indicate that it is not the default Gateway, for
363
+ example :
383
364
384
365
` ` ` yaml
385
366
status:
@@ -428,7 +409,7 @@ testing of the new default Gateway before the old one is deleted.
428
409
429
410
# #### Changes in Functionality
430
411
431
- If Chihiro changes the default Gateway to a different implementation that does
412
+ If Chihiro changes a default Gateway to a different implementation that does
432
413
not support all the functionality of the previous default Gateway, then the
433
414
Routes that were bound to the previous default Gateway will no longer function
434
415
as expected. This is not a new problem : it already exists when Ana changes a
@@ -456,6 +437,31 @@ is considered later, the guiding principle SHOULD be that `spec.isDefault`
456
437
SHOULD NOT affect where a Gateway listens for traffic or whether it can be
457
438
merged with other Gateways.
458
439
440
+ # ### 4. Enumerating Routes Bound to Default Gateways
441
+
442
+ To enumerate Routes bound to the default Gateways, any of Ana, Chihiro, or Ian
443
+ can look for Routes with no `parentRefs` specified, and then check the
444
+ ` status.parents` of those Routes to see if the Route has been claimed. Since
445
+ this will also show _which_ Gateways have claimed a given defaulted Route, it
446
+ neatly solves the problem of allowing Ana to determine which default
447
+ Gateway(s) her Route is using even if she doesn't have RBAC to query Gateway
448
+ resources directly.
449
+
450
+ While this is possible with `kubectl get -o yaml`, it's not exactly a friendly
451
+ user experience, so adding this functionality to a tool like `gwctl` would be
452
+ a dramatic improvement. In fact, looking at the `status` of a Route is very
453
+ much something that we should expect any user of Gateway API to do often,
454
+ whether or not default Gateways are in play; `gwctl` or something similar
455
+ SHOULD be able to show her which Routes are bound to which Gateways in every
456
+ case, not just with default Gateways.
457
+
458
+ # #### Open Questions
459
+
460
+ Should the Gateway also add a `condition` explicitly expressing that the Route
461
+ has been claimed by the default Gateway, perhaps with `type : DefaultGateway`?
462
+ This could help tooling like `gwctl` more easily enumerate Routes bound to the
463
+ default Gateway.
464
+
459
465
# ## Gateway For Mesh (East/West)
460
466
461
467
Mesh traffic is defined by using a Service as a `parentRef` rather than a
492
498
as well as how namespacing would work -- it's especially unhelpful for Ana
493
499
if she has to know the namespace of the default Gateway in order to use it.
494
500
501
+ (Also, this is a breaking change if Chihiro has already created a
502
+ non-default Gateway with whatever name we choose to use for the convention.)
503
+
495
504
- A default Gateway could overwrite a Route's empty `parentRefs` with a
496
505
non-empty `parentRefs` pointing to the default Gateway. The main challenge
497
506
with this approach is that once the `parentRefs` are overwritten, it's no
0 commit comments