5
5
6
6
## TLDR
7
7
8
- This GEP aims to standardize attachment of one Kubernetes object to another in
9
- Gateway API by establishing a pattern which defines how _ metaresources_ such as
10
- ` Policy ` API types can have their relevant effects applied to network traffic.
11
- _ Metaresources_ are a type of object that _ augments_ the behavior of an object
12
- in a standard way. ReferenceGrant is an example of this general type of metaresource.
13
-
14
- "Policy Attachment" is a specific type of _ metaresource_ that controls how policy
15
- can flow _ across_ multiple objects in a hierarchy.
16
- Individual policy APIs (e.g. ` TimeoutPolicy ` , ` RetryPolicy ` , etc) must include a
17
- common ` TargetRef ` field in their specification to identify how and where to
18
- apply that policy, along with a consistent set of behaviors around defaults and
19
- overrides.
20
-
21
- This will be important for providing a consistent experience across
22
- implementations of the API, even for configuration details that may not be fully
23
- portable.
8
+ This GEP aims to standardize terminology and process around using one Kubernetes
9
+ object modify the functions of one or more other objects.
10
+
11
+ Generally, a Kubernetes object that that _ augments_ the behavior of an object
12
+ in a standard way is called a _ Metaresource_ are a type of object. ReferenceGrant
13
+ is an example of this general type of metaresource, but it is far from the only
14
+ one.
15
+
16
+ This document proposes controlling the creation of configuration in the underlying
17
+ Gateway data plane using two types of Policy Attachment.
18
+ A "Policy Attachment" is a specific type of _ metaresource_ that can affect specific
19
+ settings across either one object (this is "Direct Policy Attachment"), or objects
20
+ in a hierarchy (this is "Hierarchical Policy Attachment").
21
+
22
+ Individual policy APIs must
23
+ - be their own CRDs (e.g. ` TimeoutPolicy ` , ` RetryPolicy ` etc),
24
+ - can be included in the Gateway API API group and installation or be defined by
25
+ implementations
26
+ - and must include a common ` TargetRef ` struct in their specification to identify how and where to
27
+ apply that policy, along with a field that indicates if the reference is ` Direct `
28
+ or ` Hierarchical ` . (Shorter name suggestions welcomed)
29
+
30
+ For Hierarchical Policies, this GEP also describes a set of expected behaviors
31
+ for how settings can flow across a defined hierarchy.
32
+
24
33
25
34
## Goals
26
35
27
- * Clearly communicate what metaresources are, and that policy resources are a
28
- specific _ type_ of metaresource
29
- * Establish a pattern for metaresources which will be used for any metaresources
30
- or policies included in the Gateway API spec
31
- * Establish a pattern for metaresources and policy attachment which should be
32
- used for any implementation specific policies used with Gateway API resources
36
+ * Establish a pattern for Policy objects which will be used for any policies
37
+ included in the Gateway API spec
38
+ * Establish a pattern for Policy attachment, whether Direct or Hierarchical,
39
+ which must be used for any implementation specific policies used with
40
+ Gateway API resources
33
41
* Provide a way to distinguish between required and default values for all
34
42
policy API implementations
35
43
* Enable policy attachment at all relevant scopes, including Gateways, Routes,
36
- Backends
44
+ Backends, along with how values should flow across a hierarchy if necessary
37
45
* Ensure the policy attachment specification is generic and forward thinking
38
46
enough that it could be easily adapted to other grouping mechanisms like
39
47
Namespaces in the future
@@ -54,8 +62,9 @@ When designing Gateway API, one of the things we’ve found is that we often nee
54
62
able change the behavior of objects without being able to make changes to the spec
55
63
of those objects. Sometimes, this is because we can’t change the spec of the object
56
64
to hold the information we need ( ReferenceGrant, from GEP-709, affecting Secrets
57
- and Services is an example), and sometimes it’s because we want the behavior change
58
- to flow across multiple objects (this is what Policy Attachment is for).
65
+ and Services is an example, as is Direct Policy Attachment), and sometimes it’s
66
+ because we want the behavior change to flow across multiple objects
67
+ (this is what Hierarchical Policy Attachment is for).
59
68
60
69
To put this another way, sometimes we need ways to be able to affect how an object
61
70
is interpreted in the API, without representing the description of those effects
@@ -64,81 +73,110 @@ inside the spec of the object.
64
73
This document describes the ways we design objects to meet these two use cases,
65
74
and why you might choose one or the other.
66
75
67
- We use the term “metaresource” to describe both of these use cases, since the
68
- object is in both cases a superset of its settings and the settings of a wrapped
69
- object (or objects). “Meta” here is used in its Greek sense of “more comprehensive”
76
+ We use the term “metaresource” to describe the class of objects that _ only_ augment
77
+ the behavior of another Kubernetes object, regardless of what they are targeting.
78
+
79
+ “Meta” here is used in its Greek sense of “more comprehensive”
70
80
or “transcending”, and “resource” rather than “object” because “metaresource”
71
81
is more pronounceable than “metaobject”. Additionally, a single word is better
72
82
than a phrase like “wrapper object” or “wrapper resource” overall, although both
73
83
of those terms are effectively synonymous with “metaresource”.
74
84
75
- All ReferenceGrants are metaresources, and all objects that use Policy Attachment
76
- are metaresources, but metaresources can be more than just those two things.
77
-
78
- ### Targeted metaresources
79
-
80
- ReferenceGrant is an example of a targeted metaresource. It’s tightly bound to a
81
- particular Kind within a single namespace, and only modifies the behavior of the
82
- objects that match its binding (by allowing references to them from outside their
83
- namespace).
84
-
85
- We’ve been discussing the idea of having a new object that holds extra capabilities
86
- for a backend Service (something like BackendCapabilities or similar, name TBD),
87
- as a way to implement GEP-1282 (Backend Properties). A new resource here that
88
- referenced a single service and had extra properties that we can’t put into the
89
- Service object is also an example of a targeted metaresource. The intent is to
90
- augment the behavior of the bound Service object with the structured data in the
91
- Spec of BackendCapabilities, since it’s not easy to make changes to a GA upstream
92
- object like Service. (And arguably, Service is already a pretty overloaded
93
- resource, so there will need to be good justification for any changes).
94
-
95
- With these two examples in mind, here are some guidelines for when to consider
96
- using a targeted metaresource:
97
- * The number or scope of objects to be modified is limited or singular. Targeted
98
- metaresources should target one specific object (preferred), or a tightly-scoped
99
- set of objects (like ReferenceGrant).
85
+ A "Policy Attachment" is a metaresource that affects the fields in existing objects
86
+ (like Gateway or Routes), or influences the configuration that's generated in an
87
+ underlying data plane.
88
+
89
+ "Direct Policy Attachment" is when a Policy object references a single object _ only_ ,
90
+ and only modifies the fields of or the configuration associated with that object.
91
+
92
+ "Hierarchical Policy Attachment" is when a Policy object references a single object
93
+ _ and any child objects of that object_ (according to some defined hierarchy), and
94
+ modifies fields of the child objects, or configuration associated with the child
95
+ objects.
96
+
97
+ ### Direct Policy Attachment
98
+
99
+ A Direct Policy Attachment is tightly bound to one or more instances of a particular
100
+ Kind within a single namespace, and only modifies the behavior of the object or
101
+ objects that match its binding.
102
+
103
+ As an example, one use case that Gateway API currently does not support is how
104
+ to configure details of the TLS required to connect to a backend (in other words,
105
+ if the process running inside the backend workload expects TLS, not that some
106
+ automated infrastructure layer is provisioning TLS as in the Mesh case).
107
+
108
+ A hypothetical TLSConnectionPolicy that targets a Service could be used for this,
109
+ using the functionality of the Service as describing a set of endpoints. (It
110
+ should be also noted this is not the only way to solve this problem, just an
111
+ example to illustrate Direct Policy Attachment.)
112
+
113
+ The TLSConnectionPolicy would look something like this:
114
+
115
+ ``` yaml
116
+ apiVersion : gateway.networking.k8s.io/v1alpha2
117
+ kind : TLSConnectionPolicy
118
+ metadata :
119
+ name : tlsport8443
120
+ namespace : foo
121
+ spec :
122
+ targetRef : # This struct is defined as part of Gateway API
123
+ type : Direct
124
+ group : " " # Empty string means core - this is a standard convention
125
+ kind : Service
126
+ name : fooService
127
+ tls :
128
+ certificateAuthorityRefs :
129
+ - name : CAcert
130
+ port : 8443
131
+
132
+ ```
133
+
134
+ All this does is tell an implementation, that for connecting to port ` 8443 ` on the
135
+ Service ` fooService ` , it should assume that the connection is TLS, and expect the
136
+ service's certificate to be validated by the chain in the ` CAcert ` Secret.
137
+
138
+ Importantly, this would apply to _ every_ usage of that Service across any HTTPRoutes
139
+ in that namespace, which could be useful for a Service that is reused in a lot of
140
+ HTTPRoutes.
141
+
142
+ With this two examples in mind, here are some guidelines for when to consider
143
+ using Direct Policy Attachment:
144
+ * The number or scope of objects to be modified is limited or singular. Direct
145
+ Policy Attachments should target one specific object (preferred), or a tightly-scoped
146
+ set of objects (like all Services in a namespace).
100
147
* The modifications to be made to the objects don’t have any transitive information -
101
148
that is, the modifications only affect the single object that the targeted
102
149
metaresource is bound to, and don’t have ramifications that flow beyond that
103
- object. ReferenceGrant and BackendCapabilities are good examples here because
104
- they don’t expect the metaresource to modify the behavior of more than one
105
- object. (Even in the ReferenceGrant case, the ability to set a Kind rather
106
- than an individual object is syntactic sugar for having to prevent needing to
107
- have lots of ReferenceGrants if you have lots of wrapped objects).
150
+ object.
108
151
* In terms of status, it should be reasonably easy for a user to understand that
109
152
everything is working - basically, as long as the targeted object exists, and
110
153
the modifications are valid, the metaresource is valid, and this should be
111
154
straightforward to communicate in one or two Conditions. Note that at the time
112
155
of writing, this is * not* completed.
113
- * Be extremely careful in using metaresources to target things in other namespaces.
114
- In general, this is a big security problem, unless the referent resources have
115
- some way to decline. Most of the time, it’s better to have the resource target
116
- something in its own namespace (that is, the targeted resource describes what
117
- should have its behavior modified), with other, similar but distinct fields
118
- then describe what to target for further modifications. An example:
119
- * A metaresource that constrains client behavior when reaching out to other
120
- services should use a targetRef-like field to choose the clients, and have
121
- another field that sets what the external targets of the constrained behavior
122
- are. (The external targets may conceivably be “all external targets”).
123
- In general, metaresources that modify the behavior of things outside their own
124
- namespace should be avoided unless it uses a handshake of some sort, where the
125
- things outside the namespace can opt–out of the behavior. (Notably, this is the
126
- design that we used for ReferenceGrant).)
127
-
128
- ### Policy Attachment: It's all about the defaults and overrides
129
-
130
- Because a Policy is a metaresource, it targets some other resource and _ augments_
131
- its behavior.
132
-
133
- But why have this distinct from other types of metaresource? Because Policy
134
- resources are designed to have a way for settings to flow down a hierarchy.
156
+ * Direct Policy Attachment _ should_ only be used to target objects in the same
157
+ namespace as the Policy object. Allowing cross-namespace references brings in
158
+ significant security concerns, and/or difficulties about merging cross-namespace
159
+ policy objects. Notably, Mesh use cases may need to do something like this for
160
+ consumer policies, but in general, Policy objects that modify the behavior of
161
+ things outside their own namespace should be avoided unless it uses a handshake
162
+ of some sort, where the things outside the namespace can opt–out of the behavior.
163
+ (Notably, this is the design that we used for ReferenceGrant).)
164
+
165
+ ### Hierarchical Policy Attachment: It's all about the defaults and overrides
166
+
167
+ Because a Hierarchical Policy is a metaresource, it targets some other resource
168
+ and _ augments_ its behavior.
169
+
170
+ But why have this distinct from other types of metaresource? Because Hierarchical
171
+ Policy resources are designed to have a way for settings to flow down a hierarchy.
172
+
135
173
Defaults set the default value for something, and can be overridden by the
136
174
“lower” objects (like a connection timeout default policy on a Gateway being
137
175
overridable inside a HTTPRoute), and Overrides cannot be overridden by “lower”
138
176
objects (like setting a maximum client timeout to some non-infinite value at the
139
177
Gateway level to stop HTTPRoute owners from leaking connections over time).
140
178
141
- Here are some guidelines for when to consider using a Policy object:
179
+ Here are some guidelines for when to consider using a Hierarchical Policy object:
142
180
* The settings or configuration are bound to one containing object, but affect
143
181
other objects attached to that one (for example, affecting HTTPRoutes attached
144
182
to a single Gateway, or all HTTPRoutes in a GatewayClass).
@@ -153,7 +191,6 @@ Here are some guidelines for when to consider using a Policy object:
153
191
is not, and needs to be carefully designed to avoid fanout apiserver load.
154
192
(This is not built at all in the current design either).
155
193
156
-
157
194
## API
158
195
159
196
This approach is building on concepts from all of the alternatives discussed
@@ -162,16 +199,18 @@ but also borrows some concepts from the [ServicePolicy
162
199
proposal] ( https://github.com/kubernetes-sigs/gateway-api/issues/611 ) .
163
200
164
201
### Policy Attachment for Ingress
165
- Attaching policy to Gateway resources for ingress use cases is relatively
166
- straightforward. A policy can reference the resource it wants to apply to.
202
+ Attaching a Directly Attached Policy to Gateway resources for ingress use cases
203
+ is relatively straightforward. A policy can reference the resource it wants to
204
+ apply to.
205
+
167
206
Access is granted with RBAC - anyone that has access to create a RetryPolicy in
168
207
a given namespace can attach it to any resource within that namespace.
169
208
170
209
![ Simple Ingress Example] ( images/713-ingress-simple.png )
171
210
172
- To build on that example, it’s possible to attach policies to more resources.
173
- Each policy applies to the referenced resource and everything below it in terms
174
- of hierarchy. Although this example is likely more complex than many real world
211
+ A Hierarchical Policy can attach to a parent resource, and then each policy
212
+ applies to the referenced resource and everything below it in terms of hierarchy.
213
+ Although this example is likely more complex than many real world
175
214
use cases, it helps demonstrate how policy attachment can work across
176
215
namespaces.
177
216
@@ -216,6 +255,13 @@ The `targetRef` field MUST have the following structure:
216
255
``` go
217
256
// PolicyTargetReference identifies an API object to apply policy to.
218
257
type PolicyTargetReference struct {
258
+ // Type is the type of the policy attachment.
259
+ // This can be either Direct or Hierarchical.
260
+ //
261
+ // +kubebuilder:validation:MinLength=1
262
+ // +kubebuilder:validation:MaxLength=253
263
+ Type string ` json:"type"`
264
+
219
265
// Group is the group of the target resource.
220
266
//
221
267
// +kubebuilder:validation:MinLength=1
@@ -340,6 +386,7 @@ spec:
340
386
includeProtocol : true
341
387
includeQueryString : true
342
388
targetRef :
389
+ type : hierarchical
343
390
kind : Gateway
344
391
name : example
345
392
---
@@ -350,6 +397,7 @@ spec:
350
397
cachePolicy :
351
398
includeQueryString : false
352
399
targetRef :
400
+ type : direct
353
401
kind : HTTPRoute
354
402
name : example
355
403
` ` `
@@ -393,6 +441,7 @@ spec:
393
441
default :
394
442
maxRetries : 5
395
443
targetRef :
444
+ type : direct
396
445
group : networking.acme.io
397
446
kind : ExternalService
398
447
name : foo.com
@@ -405,6 +454,7 @@ the same resource _and_ have an identical field specified with different values,
405
454
precedence MUST be determined in order of the following criteria, continuing on
406
455
ties:
407
456
457
+ * Hierarchical Policies override Direct Policies.
408
458
* The oldest Policy based on creation timestamp. For example, a Policy with a
409
459
creation timestamp of "2021-07-15 01:02:03" is given precedence over a Policy
410
460
with a creation timestamp of "2021-07-15 01:02:04".
0 commit comments