GatewayClass: A Contract With the Implementation
- date
- category
- Networking
- also in
- Containers
- reading
- 2 min / 335 words
GatewayClass is easy to mistake for a label.
gatewayClassName: public
It looks like:
use the public gateway
But GatewayClass is more important than that.
It is the resource that says which controller handles a class of Gateways.
Minimal model
The relationship looks like this:
GatewayClass
|
v
Gateway
|
v
HTTPRoute
HTTPRoute attaches to Gateway.
Gateway points to GatewayClass.
GatewayClass points to the implementation through controllerName.
Example:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: public
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
This does not create a traffic entry point yet.
It says:
Gateways with gatewayClassName: public
are handled by the Envoy Gateway controller
GatewayClass belongs to the platform
An application team usually should not create its own GatewayClass.
This is a platform decision:
which implementations do we allow?
which ones are public?
which ones are private?
which ones have Internet access?
which ones are internal only?
which ones have shared security policies?
A small cluster may have one class:
public
A larger environment may have separate classes:
public
internal
mesh
edge
regional
Those names are not part of the standard. The standard defines the mechanism, not the organization's vocabulary.
A class does not guarantee identical features everywhere
Gateway API is a specification.
The implementation decides how it handles a feature and which extensions it exposes.
So two classes can look similar:
public-nginx
public-envoy
but differ in behavior:
regex path matching
timeouts
body size
header manipulation
TLS options
observability
custom filters
With Ingress, these differences often hid in annotations.
With Gateway API, they should be more visible: through standard fields, policies, or implementation extensions.
Practical GatewayClass types
There are no official GatewayClass kinds like:
PublicGatewayClass
PrivateGatewayClass
MeshGatewayClass
There is one GatewayClass resource.
The types come from platform decisions.
Example split:
public
Internet-facing entry point
TLS required
restricted namespaces
internal
private-network entry point
no public address
different DNS rules
mesh
service mesh integration
service identity policies
experimental
new implementation
no production traffic
That is the role of GatewayClass: name an allowed variant of infrastructure.
Not per application.
Per way of delivering traffic.
Why this matters in migration
During an ingress-nginx migration, it is tempting to start with:
how do I rewrite Ingress as HTTPRoute?
That is too late.
First you need to know:
which GatewayClass replaces ingressClassName: nginx?
If the old object had:
spec:
ingressClassName: nginx
the new model needs an answer:
spec:
gatewayClassName: public
or:
spec:
gatewayClassName: nginx
or something else, depending on the implementation and platform policy.
That is not cosmetic naming.
It decides which controller programs the real traffic path.
A good class name tells the truth
Weak name:
gateway
Better name:
public
internal
edge
mesh
Even better if the organization has several implementations:
public-envoy
internal-nginx
mesh-istio
The name should help an application team choose the correct variant without reading implementation details.
But it should not pretend the implementation does not exist.
It always comes back during debugging:
manifest
|
v
controller
|
v
proxy or cloud load balancer
|
v
request
GatewayClass is where that chain becomes concrete.