design/20230601.gateway-route-hostnames.md
This checklist contains actions which must be completed before a PR implementing this design can be merged.
For generating Gateway API certificates, use hostnames present in, e.g., GRPCRoute, HTTPRoute, and TLSRoute resources in addition to the Gateway listener hostnames.
This reduces configuration duplication, and allows the cluster owner to delegate permission to site owners to add hostnames.
Currently, the gateway-shim only looks at the hostname in Listener.
This field is optional, and its purpose is to filter which hostnames routes are allowed to match.
This double-configuration allows the cluster owner to set allowed hostnames in GatewaySpec, while individual site owners update their HTTPRouteSpec.
In cases where this permission model is unnecessary (either because all hostnames are allowed, or because the cluster and site owners are the same team), this leads to awkward duplication.
As with any configuration duplication, it is easy to miss an update in one place, causing difficult-to-find bugs, and requiring teams to maintain more internal documentation.
E.g. Envoy Gateway already supports running a Gateway without hostnames in the Listener.
Another drawback inherent in using Listener.hostname is that it is a singleton.
To add another hostname, the entire Listener object must be duplicated, including port, protocol and tls fields.
This adds yet another source of duplication.
N/A
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: tls-basic
spec:
gatewayClassName: acme-lb
listeners:
- name: https-1
hostname: 1.example.com
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: default-cert
- name: https-2
hostname: 2.example.com
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: default-cert
---
# An HTTPRoute that uses the two hosts.
Compare this with the following HTTPRoute and Gateway:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: example-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "1.example.com"
- "2.example.com"
rules:
- backendRefs:
- name: example-svc
port: 10080
Note that HTTPRouteSpec.hostnames is a list, avoiding duplication.
As long as there are no hostnames in the Listener, this allows the hostnames as if they were present there.
If there are hostnames in the Listener, the spec says the Listener only deals with the intersection.
Hostnames make more sense in Route resources than in Listeners, as a single route may be used for both HTTP and HTTPS.
See the Gateway API spec on GatewaySpec.listeners for more information.
HTTPRoute with two new hostnames, but doesn't change the Gateway.Gateway.Ultimately, this is nothing new, it's just about following the Gateway API spec.
This is based on the proof-of-concept in tommie/cert-manager.
The easiest way to implement this is to generate synthetic listeners early in gateway-shim, and let the main controller logic stay the same.
Listeners with hostnames are not affected, since the intersection of routes and listeners determines the listener's capabilities.
A listener without hostname matches any hostname in attached routes, and they can simply be copied once for each route hostname.
I.e. the second example under Proposal would be translated to the first.
Some glue data types are needed to support all routes that can carry hostnames. At the moment, these are:
Since this code deals with how cert-manager reacts to changes in CRDs, it is enough to focus on unit tests.
For a given set of Gateways and Routes, it should generate a given synthetic Gateway.
N/A
Downgrading to a cert-manager that does not support looking up hostnames in Routes may lead to unavailability.
The change is upgrade-compatible, if all Gateways already specify hostnames in Listeners.
However, if a Gateway does not specify hostnames in Listeners, upgrading may cause certificates to be issued for hostnames not previously seen.
In terms of security, this is not an issue, as the Routes have always existed; they simply didn't have a valid certificate.
Since this can be implemented as an input transform, that transform could be behind a feature flag.
Indeed, the entire Gateway API support is already behind a feature flag: ExperimentalGatewayAPISupport
It probably does not need a specific one.
It requires Gateway API CRDs, but nothing more than is already required for gateway-shim.
It will subscribe to HTTPRoute, TLSRoute, and similar resources, beyond the previously subscribed Gateway resources.
It will not write new objects.
Enabling the feature may cause cert-manager to recognize hostnames it wasn't aware of before, and therefore issue new Certificates on upgrade.
No. Route resources are small.
None? cert-manager should follow the Gateway API spec.
N/A