@@ -6,10 +6,20 @@ Everything you wanted to know about building a Gateway API implementation
66but were too afraid to ask.
77
88This document is a place to collect tips and tricks for _ writing a Gateway API
9- implementation_ . It's intended to be a place to write down some guidelines to
10- help implementers of this API to skip making common mistakes. It may not be
11- very relevant if you are intending to _ use_ this API as an end user as opposed
12- to _ building_ something that uses it.
9+ implementation_ that have no straightforward place within the godoc fields of the
10+ underlying types.
11+
12+ It's also intended to be a place to write down some guidelines to
13+ help implementers of this API to skip making common mistakes.
14+
15+ It may not be very relevant if you are intending to _ use_ this API as an end
16+ user as opposed to _ building_ something that uses it.
17+
18+ !!! note
19+ This document is officially a part of the Gateway API specification.
20+ Requirements in this document labelled as MUST, SHOULD, or MAY must be treated
21+ the same as in the detailed specification page. (That is, the words MUST, SHOULD,
22+ and MAY must be interpreted as described in RFC 2119.)
1323
1424This is a living document, if you see something missing, PRs welcomed!
1525
@@ -18,7 +28,7 @@ This is a living document, if you see something missing, PRs welcomed!
1828Hopefully most of these are not surprising, but they sometimes have non-obvious
1929implications that we'll try and lay out here.
2030
21- ### Gateway API is ` kubernetes.io ` API
31+ ### Gateway API is a ` kubernetes.io ` API
2232
2333Gateway API uses the ` gateway.networking.k8s.io ` API group. This means that,
2434like APIs delivered in the core Kubernetes binaries, each time a release happens,
@@ -28,7 +38,7 @@ delivered in the core binaries.
2838### Gateway API is delivered using CRDs
2939
3040Gateway API is supplied as a set of CRDs, version controlled using our [ versioning
31- policy] ( /concepts/ versioning) .
41+ policy] [ versioning ] .
3242
3343The most important part of that versioning policy is that what _ appears to be_
3444the same object (that is, it has the same ` group ` ,` version ` , and ` kind ` ) may have
@@ -41,15 +51,312 @@ get, list, watch, etc) Gateway API objects when the CRDs have _not_ been install
4151then it's likely that your Kubernetes client code will return serious errors.
4252Tips to deal with this are also detailed below.
4353
44- ## Implementation Guidelines
54+ The CRD definitions for Gateway API objects all contain two specific
55+ annotations:
56+
57+ - ` gateway.networking.k8s.io/bundle-version: <semver-release-version> `
58+ - ` gateway.networking.k8s.io/channel: <channel-name> `
59+
60+ The concepts of "bundle version" and "channel" (short for "release channel") are
61+ explained in our [ versioning] [ versioning ] documentation.
62+
63+ Implementations may use these to determine what schema versions are installed in
64+ the cluster, if any.
65+
66+ [ versioning ] : /concepts/versioning
67+
68+ ### Changes to the Gateway API CRDs are backwards compatible
69+
70+ Part of the contract for Gateway API CRDs is that changes _ within an API version_
71+ must be _ compatible_ .
72+
73+ "Within an API Version" means changes to a CRD that occur while the same API version
74+ (` v1alpha2 ` or ` v1 ` for example) is in use, and "compatible" means that any new
75+ fields, values, or validation will be added to ensure that _ previous_
76+ objects _ will still be valid objects_ after the change.
77+
78+ This means that once Gateway API objects move to the ` v1 ` API version, then _ all_
79+ changes must be compatible.
80+
81+ This contract also means that an implementation will not fail with a higher version
82+ of the API than the version it was written with, because the newer schema being
83+ stored by Kubernetes will definitely be able to be serialized into the older version
84+ used in code by the implementation.
85+
86+ Similarly, if an implementation was written with a _ higher_ version, the newer
87+ values that it understands will simply _ never be used_ , as they are not present
88+ in the older version.
89+
90+ A similar guarantee occurs between the "experimental" and "standard" channels for
91+ objects in the same API version, so an implementation may be written with the
92+ experimental API definitions, but work just fine with having only the standard
93+ definitions installed - there will be fields or values that will never be used.
94+ The same applies for an implementation written using the standard API definitions
95+ running in a cluster with the experimental definitions installed.
96+
97+ ## Implementation Rules and Guidelines
4598
4699### CRD Management
47100
48- ### Version compatibility and conformance
101+ For a Gateway API implementation to work, the Gateway API CRDs must be installed
102+ in the Kubernetes cluster the implementation is watching.
103+
104+ Implementations have two options: automatically installing CRDs or requiring
105+ installation before working. Both have tradeoffs.
106+
107+ Either way has certain things that SHOULD be true, however:
108+
109+ Whatever method is used, cluster admins SHOULD attempt to ensure that
110+ the Bundle version of the CRDs is not _ downgraded_ . Although we ensure that
111+ API changes are backwards compatible, changing CRD definitions can change the
112+ storage version of the resource, which could have unforseen effects. Most of the
113+ time, things will probably work, but if it doesn't work, it will most likely
114+ break in weird ways.
115+
116+ Try your best to ensure that the bundle version doesn't roll backwards. It's safer.
117+
118+ Implementations SHOULD also handle the Gateway API CRDs _ not_ being present in
119+ the cluster without crashing or panicing. Exiting with a clear fatal error is
120+ acceptable in this case, as is disabling Gateway API support even if enabled in
121+ configuration.
122+
123+ Practically, for implementations using tools like ` controller-runtime ` or
124+ similar tooling, they may need to check for the _ presence_ of the CRDs by
125+ getting the list of installed CRDs before attempting to watch those resources.
126+ (Note that this will require the implementation to have ` read ` access to those
127+ resources though.)
128+
129+ #### Automatic CRD installation
130+
131+ Automatic CRD installation also includes automatic installation mechanisms such
132+ as Helm, if the CRDs are included in a Helm chart with the implementation's
133+ installation.
134+
135+ CRD definitions MAY be installed automatically by implementations, and if they do,
136+ they MUST have a way to ensure:
137+
138+ - there are no other Gateway API CRDs installed in the cluster before starting, or
139+ - that the CRD definitions are only installed if they are a higher bundle version
140+ than any existing Gateway API CRDs
141+
142+ This avoids problems if another implementation is also installed in the cluster
143+ and expects a higher version of the CRDs to be installed.
144+
145+ If the implementation can guarantee that no other implementation will interact
146+ with the cluster, then it MAY automatically install a relevant version of the CRDs.
147+
148+ The ideal method for an automatic installation would require the implementation
149+ to:
150+
151+ - Check if there are any Gateway API CRDs installed in the cluster.
152+ - If not, install its most compatible version of the CRDs.
153+ - If so, only install its version of the CRDs if the bundle version is higher
154+ than the existing one.
155+
156+
157+ Because of our backwards compatibility guarantees, it's also safe for a controller
158+ to flip the install channel between "standard" and "experimental", although
159+ implementations MUST NOT do this without consulting the implementation owner.
160+
161+ Automatic CRD installation has the advantage that there is less for the
162+ implementation user to do; any required version checking can be performed by
163+ code instead of by the cluster admin.
164+
165+ #### Manual CRD installation
166+
167+ Manual CRD installation has the advantage that the implementer needs to maintain
168+ less code; however, it pushes the responsibility for correctly managing the
169+ Gateway API CRDs back to the cluster admin, who may not have as much context
170+ as is provided here.
171+
172+ Implementations MAY require the installation to be done manually; if so, the
173+ installation instructions SHOULD include commands to check if there are any other
174+ CRDs installed already and verify that the installation will not be a downgrade.
175+
176+ ### Conformance and Version compatibility
177+
178+ A conformant Gateway API implementation is one that passes the conformance tests
179+ that are included in each Gateway API bundle version release.
180+
181+ An implementation MUST pass the conformance suite with _ no_ skipped tests to be
182+ conformant. Tests may be skipped during development, but a version you want to
183+ be conformant MUST have no skipped tests.
184+
185+ Extended features may, as per the contract for Extended status, be disabled.
186+
187+ Gateway API conformance is version-specific. An implementation that passes
188+ conformance for version N may not pass conformance for version N+1 without changes.
189+
190+ Implementations SHOULD submit a report from the conformance testing suite back
191+ to the Gateway API Github repo containing details of their testing.
192+
193+ The conformance suite output includes the Gateway API version supported.
194+
195+ #### Version compatibility
196+
197+ Once v1.0 is released, for implementations supporting Gateway and GatewayClass,
198+ they MUST set a new Condition, ` SupportedVersion ` , with ` status: true ` meaning
199+ that the installed CRD version is supported, and ` status: false ` meaning that it
200+ is not.
201+
202+ ### Standard Status fields and Conditions
203+
204+ Gateway API has many resources, but when designing this, we've worked to keep
205+ the status experience as consistent as possible across objects, using the
206+ Condition type and the ` status.conditions ` field.
207+
208+ Most resources have a ` status.conditions ` field, but some also have a namespaced
209+ field that _ contains_ a ` conditions ` field.
210+
211+ For the latter, Gateway's ` status.listeners ` and the Route ` status.parents `
212+ fields are examples where each item in the slice identifies the Conditions
213+ associated with some subset of configuration.
214+
215+ For the Gateway case, it's to allow Conditions per _ Listener_ , and in the Route
216+ case, it's to allow Conditions per _ implementation_ (since Route objects can
217+ be used in multiple Gateways, and those Gateways can be reconciled by different
218+ implementations).
219+
220+ In all of these cases, there are some relatively-common Condition types that have
221+ similar meanings:
222+ - ` Accepted ` - the resource or part thereof contains acceptable config that will
223+ produce some configuration in the underlying data plane that the implementation
224+ controls. This does not mean that the _ whole_ configuration is valid, just that
225+ _ enough_ is valid to produce some effect.
226+ - ` Programmed ` - this represents a later phase of operation, after ` Accepted ` ,
227+ when the resource or part thereof has been Accepted and programmed into the
228+ underlying dataplane. Users should expect the configuration to be ready for
229+ traffic to flow _ at some point in the near future_ . This Condition does _ not_
230+ say that the dataplane is ready _ when it's set_ , just that everything is valid
231+ and it _ will become ready soon_ . "Soon" may have different meanings depending
232+ on the implementation.
233+ - ` ResolvedRefs ` - this Condition indicates that all references in the resource
234+ or part thereof were valid and pointed to an object that both exists and allows
235+ that reference. If this Condition is set to ` status: false ` , then _ at least one_
236+ reference in the resource or part thereof is invalid for some reason, and the
237+ ` message ` field should indicate which one are invalid.
238+
239+ Implementers should check the godoc for each type to see the exact details of
240+ these Conditions on each resource or part thereof.
241+
242+ Additionally, the upstream ` Conditions ` struct contains an optional
243+ ` observedGeneration ` field - implementations MUST use this field and set it to
244+ the ` metadata.generation ` field of the object at the time the status is generated.
245+ This allows users of the API to determine if the status is relevant to the current
246+ version of the object.
247+
248+
249+ ### Resources details
250+
251+ For each currently available conformance profile, there are a set of resources
252+ that implementations are expected to reconcile.
253+
254+ The following section goes through each Gateway API object, indicates expected
255+ behaviors, and which conformance profiles that object is included in.
256+
257+ #### GatewayClass
258+
259+ GatewayClass has one main ` spec ` field - ` controllerName ` . Each implementation
260+ is expected to claim a domain-prefixed string value (like
261+ ` example.com/example-ingress ` ) as its ` controllerName ` .
262+
263+ Implementations MUST watch _ all_ GatewayClasses, and reconcile GatewayClasses
264+ that have a matching ` controllerName ` . The implementation must choose at least
265+ one compatible GatewayClass out of the set of GatewayClasses that have a matching
266+ ` controllerName ` , and indicate that it accepts processing of that GatewayClass
267+ by setting an ` Accepted ` Condition to ` status: true ` in each. Any GatewayClasses
268+ that have a matching ` controllerName ` but are _ not_ Accepted must have the
269+ ` Accepted ` Condition sett to ` status: false ` .
270+
271+ Implementations MAY choose only one GatewayClass out of the pool of otherwise
272+ acceptable GatewayClasses if they can only reconcile one, or, if they are capable
273+ of reconciling multiple GatewayClasses, they may also choose as many as they like.
274+
275+ If something in the GatewayClass renders it incompatibie (at the time of writing,
276+ the only possible reason for this is that there is a pointer to a ` paramsRef `
277+ object that is not supported by the implementation), then the implementation
278+ SHOULD mark the incompatible GatewayClass as not ` Accepted ` .
279+
280+ Watched in profiles:
281+ - HTTP
282+ - TLS
283+
284+ #### Gateway
285+
286+ Gateway objects MUST refer in the ` spec.gatewayClassName ` field to a GatewayClass
287+ that exists and is ` Accepted ` by an implementation for that implementation to
288+ reconcile them.
289+
290+ Gateway objects that fall out of scope (for example, because the GatewayClass
291+ they reference was deleted) for reconciliation MAY have their status removed by
292+ the implementation as part of the delete process, but this is not required.
293+
294+ Watched in profiles:
295+ - HTTP
296+ - TLS
297+
298+ #### General Route information
299+
300+ All Route objects share some properties:
301+
302+ - They MUST be attached to an in-scope parent for the implementation to consider
303+ them reconcilable.
304+ - The implementation MUST update the status for each in-scope Route with the
305+ relevant Conditions, using the namespaced ` parents ` field. See the specific Route
306+ types for details, but this usually includes ` Accepted ` , ` Programmed ` and
307+ ` ResovledRefs ` Conditions.
308+ - Routes that fall out of scope SHOULD NOT have status updated, since it's possible
309+ that these updates may overwrite any new owners. The ` observedGeneration ` field
310+ will indicate that any remaining status is out of date.
311+
312+
313+ #### HTTPRoute
314+
315+ HTTPRoutes route HTTP traffic that is _ unencrypted_ and available for inspection.
316+ This allows the HTTPRoute to use HTTP properties, like path, method, or headers
317+ in its routing directives.
318+
319+ Watched in profiles:
320+ - HTTP
321+ - MESH
322+
323+ #### TLSRoute
324+
325+ TLSRoutes route encrypted TLS traffic using the SNI header, _ without decrypting
326+ the traffic stream_ , to the relevant backends.
327+
328+ Watched in profiles:
329+ - TLS
330+
331+ #### TCPRoute
332+
333+ TCPRoutes route a TCP stream that arrives at a Listener to one of the given
334+ backends.
335+
336+ Not currently included in any conformance profiles.
337+
338+ #### UDPRoute
339+
340+ UDPRoutes route UDP packets that arrive at a Listener to one of the given
341+ backends.
342+
343+ Not currently included in any conformance profiles.
49344
50- ### Resources to reconcile
345+ #### ReferenceGrant
51346
52- ### Listener traffic matching
347+ ReferenceGrant is a special resource that is used by resource owners in one
348+ namespace to _ selectively_ allow references from Gateway API objects in other
349+ namespaces.
53350
351+ A ReferenceGrant is created in the same namespace as the thing it's granting
352+ reference access to, and allows access from other namespaces, from other Kinds,
353+ or both.
54354
355+ Implementations that support cross-namespace references MUST watch ReferenceGrant
356+ and reconcile any ReferenceGrant that points to an object that's referred to by
357+ an in-scope Gateway API object.
55358
359+ Watched in profiles:
360+ - HTTP
361+ - TLS
362+ - MESH
0 commit comments