Skip to content

Commit 634da66

Browse files
committed
Add more detail to implementers guide
Signed-off-by: Nick Young <[email protected]>
1 parent 265bf1d commit 634da66

File tree

3 files changed

+327
-10
lines changed

3 files changed

+327
-10
lines changed

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ nav:
7676
- TCP routing: guides/tcp.md
7777
- gRPC Routing: guides/grpc-routing.md
7878
- Migrating from Ingress: guides/migrating-from-ingress.md
79+
- Implementer's Guide: guides/implementers-guide.md
7980
- Reference:
8081
- API Types:
8182
GatewayClass: api-types/gatewayclass.md

site-src/guides/implementers-guide.md

Lines changed: 317 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ Everything you wanted to know about building a Gateway API implementation
66
but were too afraid to ask.
77

88
This 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

1424
This 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!
1828
Hopefully most of these are not surprising, but they sometimes have non-obvious
1929
implications 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

2333
Gateway API uses the `gateway.networking.k8s.io` API group. This means that,
2434
like 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

3040
Gateway API is supplied as a set of CRDs, version controlled using our [versioning
31-
policy](/concepts/versioning).
41+
policy][versioning].
3242

3343
The most important part of that versioning policy is that what _appears to be_
3444
the 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
4151
then it's likely that your Kubernetes client code will return serious errors.
4252
Tips 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

site-src/references/spec.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
# API Specification
22

3+
This page contains the API field specification for Gateway API.
4+
5+
However, the [Implementer's Guide][implguide] also contains requirements for implementers
6+
that don't fit cleanly into a single field's documentation here. The API spec
7+
as a whole must be considered to be represented by both documents.
8+
9+
[implguide]: /guides/implementers-guide
10+
11+
312
REPLACE_WITH_GENERATED_CONTENT

0 commit comments

Comments
 (0)