You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: geps/gep-713/index.md
+38-21Lines changed: 38 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,7 @@ In many cases, it will be better to work to include configuration directly insid
25
25
When designing Gateway API, a recurring challenge became apparent. There was often a need to change or augment the behavior of objects without modifying their specs.
26
26
27
27
There are several cases where this happens, such as:
28
+
28
29
- when changing the spec of the object to hold the new piece of information is not possible (e.g., `ReferenceGrant`, from [GEP-709](../gep-709/index.md), when affecting Secrets and Services);
29
30
- when the new specification applies at different scopes (different object kinds), making it more maintainable if the declaration is extracted to a separate object, rather than adding new fields representing the same functionality across multiple objects;
30
31
- when the augmented behavior is intended to [span across relationships of an object](#spanning-behavior-across-relationships-of-a-target) other than the object that is directly referred in the declaration;
@@ -46,17 +47,22 @@ After multiple iterations of Gateway API experimenting with policies—whether t
46
47
### User stories
47
48
48
49
-[Ana](../../concepts/roles-and-personas.md#ana) or [Chihiro](../../concepts/roles-and-personas.md#Chihiro) would like to specify some new behavior for a standard Kubernetes resource, but that resource doesn't have a way to specify the behavior and neither Ana nor Chihiro can modify it.
49
-
- For example, Ana may want to add a rate limit to a Kubernetes Service. The Service object itself doesn't have a field for rate limiting, and Ana can't modify the Service object's definition.
50
+
E.g., Ana may want to add a rate limit to a Kubernetes Service. The Service object itself doesn't have a field for rate limiting, and Ana can't modify the Service object's definition.
51
+
50
52
- A Gateway API implementer would like to define some implementation-specific behaviors for Gateway API objects that are already standard.
51
-
- For example, an implementer might want to provide a way for Chihiro to plug in a WebAssembly module to a particular Gateway listener, including all the configuration required by the module. Support for WebAssembly modules is a feature of this implementation specifically and the Gateway listener spec does not contain fields to declare WebAssembly configuration.
53
+
E.g., an implementer might want to provide a way for Chihiro to plug in a WebAssembly module to a particular Gateway listener, including all the configuration required by the module. Support for WebAssembly modules is a feature of this implementation specifically and the Gateway listener spec does not contain fields to declare WebAssembly configuration.
54
+
52
55
- Chihiro would like a way to allow Ana to specify certain behaviors, but not others, in a very fine-grained way.
53
-
- For example, Chihiro might want to allow Ana to specify rate limits for a Service, but not to specify the Service's ports.
56
+
E.g., Chihiro might want to allow Ana to specify rate limits for a Service, but not to specify the Service's ports.
57
+
54
58
- A Gateway API implementer would like to define a way to specify a behavior that applies to a whole hierarchy of objects.
55
-
- For example, an implementer might want to define a way to specify a behavior that applies to all HTTPRoutes that are attached to a Gateway.
59
+
E.g., an implementer might want to define a way to specify a behavior that applies to all HTTPRoutes that are attached to a Gateway.
60
+
56
61
- A Gateway API implementer would like to define a way to specify a behavior that applies to multiple kinds of objects with a single declaration.
57
-
- For example, an implementer might want to define a way to specify a behavior that applies to selected HTTPRoutes and selected TCPRoutes. Even though the HTTPRoute object could otherwise be extended via an implementation-specific filter, the TCPRoute object cannot.
62
+
E.g., an implementer might want to define a way to specify a behavior that applies to selected HTTPRoutes and selected TCPRoutes. Even though the HTTPRoute object could otherwise be extended via an implementation-specific filter, the TCPRoute object cannot.
63
+
58
64
- A third-party provider would like to offer a way to independently extend the behavior of Gateways controlled by one or more Gateway API implementers.
59
-
- For example, a provider that knows how to configure Gateways controlled by one or more Gateway API implementers might want to define a way for Gateway API users to activate this feature in a standard way across the supported implementations, without direct involvement of the implementers.
65
+
E.g., a provider that knows how to configure Gateways controlled by one or more Gateway API implementers might want to define a way for Gateway API users to activate this feature in a standard way across the supported implementations, without direct involvement of the implementers.
60
66
61
67
All [risks and caveats](#tldr) considered, these are in general a few reasons for using metaresources and policies over another (possibly more direct) way to modify the spec ("augment the behavior") of an object:
62
68
@@ -115,6 +121,7 @@ Designers of new policy kinds are encouraged to read this section top-to-bottom
115
121
### Metaresources
116
122
117
123
As defined above, a metaresource is a resource whose purpose is to augment the behavior of some other resource. At its most basic level, the metaresource pattern consists of:
124
+
118
125
- A user defines a metaresource describing both the target resource(s) they want to augment, and the intent of the augmentation.
119
126
- The controller(s) implementing the metaresource notices the metaresource and applies the intent to the target resource(s).
120
127
- The controller(s) implementing the metaresource reports the status of the metaresource, indicating whether the intent is being applied or not.
@@ -176,7 +183,7 @@ spec:
176
183
<details>
177
184
<summary>Implementation tip</summary>
178
185
179
-
This targeting method can be implemented in Golang by using a type such as Gateway API's [`LocalPolicyTargetReference`](https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#LocalPolicyTargetReference) type. E.g.:
186
+
This targeting method can be implemented in Golang by using a type such as Gateway API's <a href="https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#LocalPolicyTargetReference"><code>LocalPolicyTargetReference</code></a> type. E.g.:
180
187
181
188
```go
182
189
package color
@@ -221,13 +228,14 @@ Policies can opt for allowing instances to target objects across Kubernetes name
221
228
Although not strictly forbidden, this is in general discouraged due to [discoverability](#the-discoverability-problem) issues and security implications. Cross namespace references can often lead to escalation of privileges associated with the [Confused deputy problem](https://en.wikipedia.org/wiki/Confused_deputy_problem).
222
229
223
230
Implementations that opt for designing policies that allow for cross namespace references MUST support one of the following combined approaches, to address the security concern:
231
+
224
232
- The policy is paired with [ReferenceGrants](https://gateway-api.sigs.k8s.io/api-types/referencegrant/?h=referencegrant) or some other form of equivalent handshake that ensures that the target is accepting the policy.
225
-
- The policy applied client-side and does not grant the client any additional access or permissions than it would otherwise have.
233
+
- The policy applied is client-side and does not grant the client any additional access or permissions than it would otherwise have.
226
234
227
235
<details>
228
236
<summary>Implementation tip</summary>
229
237
230
-
This targeting method can be implemented in Golang by using a type such as Gateway API's [`NamespacedPolicyTargetReference`](https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#NamespacedPolicyTargetReference) type. E.g.:
238
+
This targeting method can be implemented in Golang by using a type such as Gateway API's <ahref="https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#NamespacedPolicyTargetReference"><code>NamespacedPolicyTargetReference</code></a> type. E.g.:
231
239
232
240
```go
233
241
package color
@@ -290,7 +298,7 @@ spec:
290
298
<details>
291
299
<summary>Implementation tip</summary>
292
300
293
-
This targeting method can be implemented in Golang by using a type such as Gateway API's [`LocalPolicyTargetReferenceWithSectionName`](https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#LocalPolicyTargetReferenceWithSectionName) type. E.g.:
301
+
This targeting method can be implemented in Golang by using a type such as Gateway API's <a href="https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2#LocalPolicyTargetReferenceWithSectionName"><code>LocalPolicyTargetReferenceWithSectionName</code></a> type. E.g.:
294
302
295
303
```go
296
304
package color
@@ -364,6 +372,7 @@ Typically, the relationships between direct and indirect target kinds are organi
364
372
An example of such is a policy that targets a Namespace. Depending on the design of the policy kind, the policy object may declare intent to affect the behavior of the namespace itself (for what concerns the implementation of Namespaces in Kubernetes) or alternatively it can act as a means to affect the behavior of other objects that exist in the referred namespace (e.g. ConfigMaps). While in the former case, the (direct) target object is the Namespace itself, in the latter the (indirect) target is a set of objects of a different kind (e.g. ConfigMaps.)
365
373
366
374
Another example of this semantic difference in the context of Gateway API objects is a policy that targets the `Gateway` kind, which can be:
375
+
367
376
* a way to augment the behavior of the `Gateway` object itself (e.g. reconcile cloud infrastructure provider settings from the spec declared by the `Gateway` according to the rules specified by the policy attached to the `Gateway`), or
368
377
* a means to augment the behavior of all `HTTPRoute` objects attached to the `Gateway` (in a way that every new `HTTPRoute` that gets created or modified so it enters the context of the `Gateway` is automatically put in the scope of the policy.)
369
378
@@ -459,6 +468,7 @@ graph
459
468
```
460
469
461
470
The above yields 2 Effective policies:
471
+
462
472
- For `Route 1`: some combination of `Policy 1` and `Policy 2`
463
473
- For `Route 2`: equal to `Policy 1`
464
474
@@ -469,6 +479,7 @@ If multiple policies have the same scope (that is, multiple CRs based on the sam
469
479
Conflicts MUST be resolved according to a defined _merge strategy_. A merge strategy is a function that receives two conflicting specs and returns a new spec with the conflict resolved. I.e., `𝑓(spec, spec) → spec`
470
480
471
481
This GEP defines the following merge strategies, specified in the subsections below:
482
+
472
483
* None
473
484
* Atomic defaults
474
485
* Atomic overrides
@@ -487,6 +498,7 @@ In a conflict resolution scenario between two specs (two policies), one spec MUS
487
498
Knowing the distinction between _established_ and _challenger_ is useful to determine which and how a particular merge strategy will be applied.
488
499
489
500
With the exception of the **None** merge strategy, the following rules, continuing on ties, MUST be followed to assign which spec (which policy object) is the _established_ and which one is the _challenger_:
501
+
490
502
1. Between two policies targeting at different levels of the hierarchy, the one attached higher (less specific) MUST be assigned as the _established_ one.
491
503
2. Between two policies targeting at the same level of the hierarchy, the older policy based on creation timestamp MUST be assigned as the _established_ one.
492
504
3. Between two policies targeting at the same level of the hierarchy and identical creation timestamps, the policy appearing first in alphabetical order by `{namespace}/{name}` MUST be assigned as the _established_ one.
@@ -540,6 +552,7 @@ Implementations MAY specify _custom_ merge strategies. These are implementation-
540
552
##### Selecting a merge strategy at runtime
541
553
542
554
Implementations that support multiple merge strategies associated with a particular Policy kind MUST define how a particular merge strategy can be selected at runtime. I.e., how users can specify their preferred merge strategy to use to resolve the conflicts between Policy CRs of that kind. One of the following approaches SHOULD be adopted for this:
555
+
543
556
- The Policy CRD allows specifying, at any individual Policy CR, one and only one of the merge strategies associated with the Policy CRD, and that specified merged strategy MUST be used to resolve conflicts involving this Policy CR according to the [Conflict resolution rules](#conflict-resolution-rules) specified in this GEP.
544
557
- The controller implementing the policy has its own predefined way to determine among multiple implemented merge strategies which merge strategy to apply to resolve the conflicts between the Policy CRs according to the [Conflict resolution rules](#conflict-resolution-rules) specified in this GEP. This approach MAY include configurations of the controller implementing the Policy kind or any other way other than specifying the merge strategy at individual Policy CRs.
545
558
@@ -548,14 +561,16 @@ Policy CRDs that let users specify at any individual Policy CR one of multiple i
548
561
User MUST NOT be allowed to specify at any individual Policy CR more than one merge strategy at a time.
549
562
550
563
Two known patterns adopted by Policy implementations that support specifying one of multiple merge strategies in the Policy CRs are:
564
+
551
565
- The definition of a `strategy` field in the `spec` stanza of the Policy, or equivalentely a `mergeType` field.
552
566
- The definition of `defaults` and/or `overrides` fields in the `spec` stanza of the policy wrapping the "spec proper" fields.
553
567
554
-
Policy CRDs that define a `defaults` field to specify the merge strategy at individual Policy CRs, in the lack further discrimination of a more specific strategy, SHOULD assume the **Atomic Defaults** merge strategy whenever this field is used to determine the merge strategy.
568
+
Policy CRDs that define a `defaults` field to specify the merge strategy at individual Policy CRs, in the lack of further discrimination of a more specific strategy, SHOULD assume the **Atomic Defaults** merge strategy whenever this field is used to determine the merge strategy.
555
569
556
-
Policy CRDs that define an `overrides` field to specify the merge strategy at individual Policy CRs, in the lack further discrimination of a more specific strategy, SHOULD assume the **Atomic Overrides** merge strategy whenever this field is used to determine the merge strategy.
570
+
Policy CRDs that define an `overrides` field to specify the merge strategy at individual Policy CRs, in the lack of further discrimination of a more specific strategy, SHOULD assume the **Atomic Overrides** merge strategy whenever this field is used to determine the merge strategy.
557
571
558
572
For Policy kinds that implement multiple merge strategies, whenever the merge strategy is not specified, the first of the following merge strategies associated with the Policy kind, in order, SHOULD be assumed:
573
+
559
574
- Atomic Defaults
560
575
- Patch Defaults
561
576
- Atomic Overrides
@@ -1102,7 +1117,7 @@ Gateway API defines two kinds of Direct policies, both for augmenting the behavi
Defines two kinds of metaresources respectively for specifying *default* and *override* of networking policy rules: **AdminNetworkPolicy** and **BaselineAdminNetworkPolicy**. Builds on top of Kubernetes core `NetworkPolicy` kind.
1176
1191
1177
1192
Although the Network Policy API custom resources do not strictly implement the Metaresources and Policy Attachment pattern, they are based on similar concepts that involve policy rules for augmenting the behavior of other Kubernetes objects (pods), attachment points, nested contexts (through namespaces and pod selectors), and Defaults & Overrides.
Does not implement Metaresources and Policy Attachment. However, defines a virtual policy kind (**ConfigurationPolicy**) and supports distributing other third-party kinds of policies such as Gatekeeper's **ConstraintTemplate** kind, via a **Policy** resource whose targets are nonetheless controlled by a separate set of resource (**Placement** and **PlacementBinding**).
1184
1199
@@ -1188,20 +1203,22 @@ The following tools can be useful for implementing and supporting policies and p
CLI tool for visualizing and managing Gateway API resources in a Kubernetes cluster. Includes commands to visualize effective policies affecting the resources in compliance with the Metaresources and Policy Attachment pattern.
Golang library for implementing policy controllers. Defines types and functions to build Directed Acyclic Graphs (DAG) to represent hierarchies of targetable resources and attached policies, calculate effective policies based on standard and custom merge strategies, etc. Includes helpers for applications based on Gateway API.
1200
1215
1201
1216
## References
1202
1217
1203
1218
**Issues**
1219
+
1204
1220
* [Extensible Service Policy and Configuration](https://github.com/kubernetes-sigs/gateway-api/issues/611)
1205
1221
1206
1222
**Docs**
1223
+
1207
1224
* [Policy Attachment and Binding](https://docs.google.com/document/d/13fyptUtO9NV_ZAgkoJlfukcBf2PVGhsKWG37yLkppJo/edit?resourcekey=0-Urhtj9gBkGBkSL1gHgbWKw)
0 commit comments