GKE Gateway API — GatewayClass, HTTPRoute, shared listeners
Ingress bundled the listener and the routes. Gateway API splits them so teams share one front door.
<!-- hal:authoritative:yaml -->
Ingress bundled the listener and the routes. Gateway API splits them so teams share one front door.
§I — Frame
On GKE, the Gateway API is the next L7 surface: a GatewayClass names the controller implementation, a Gateway owns listeners (ports, protocol, TLS, hostnames), and HTTPRoute (or GRPCRoute) objects attach routes to that Gateway. GKE ships a managed Gateway controller. You pick a class such as gke-l7-global-external-managed, gke-l7-regional-external-managed, or an internal class, then attach routes from one or many namespaces.
This is not Pod Security Admission (09-12), not NetworkPolicy (09-09), and not IRSA (09-06). It is also not the AKS Ingress / Application Gateway path from 09-03. Classic Ingress still works on GKE. Today is the split object model on GKE's managed classes.
§II — Three objects, one data plane
| Object | Owns |
|---|---|
| GatewayClass | Which controller implements the Gateway (cluster-scoped catalog). |
| Gateway | Listeners: port, protocol (HTTP/HTTPS), hostname, TLS certificateRefs. |
| HTTPRoute | Matches (host, path, headers) and backendRefs (Service + port). |
Ingress mixed listener config and routing rules in one resource. Gateway API separates them so platform teams own Gateways and app teams own HTTPRoutes. parentRefs on the HTTPRoute point at the Gateway (and optional sectionName for a specific listener).
§III — Worked GKE shape
Confirm classes exist:
kubectl get gatewayclass
# expect gke-l7-global-external-managed (and regional/internal variants on many clusters)
Platform Gateway (HTTPS listener, shared Secret):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: edge-gw
namespace: gateway-infra
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: app.example.com
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: app-tls
App HTTPRoute in another namespace (ReferenceGrant may be required for cross-namespace Secret or Service access, depending on policy):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: storefront
namespace: storefront
spec:
parentRefs:
- name: edge-gw
namespace: gateway-infra
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: storefront-svc
port: 80
GKE provisions (or attaches) a Google Cloud load balancer for external classes. Status on Gateway and HTTPRoute reports programmed addresses and accepted parents. Empty ADDRESS with Accepted=False is a class, permission, or certificate problem, not "YAML syntax alone."
§IV — Failure modes
- Wrong GatewayClass. A name that does not exist, or an internal class used when you needed global external, yields a Gateway that never programs a public VIP.
- HTTPRoute without Accepted parent. Typo in
parentRefs, missing listener hostname overlap, or cross-namespace attach blocked. Describe the HTTPRoute; readParentsconditions. - TLS Secret not reachable. CertificateRef Secret in the wrong namespace without a grant, or wrong key names (
tls.crt/tls.key). - Treating Gateway like Ingress. Putting path rules on the Gateway object, or expecting one Gateway per Service by default. Share listeners; attach many routes.
- Confusing with NetworkPolicy. Gateway API never replaces east-west allowlists. A route to a Service still needs NetworkPolicy if the cluster denies by default.
§V — How this differs from last K8s Ops
09-12 spent AKS PSA labels and PSS profiles. 09-09 spent VPC CNI NetworkPolicy. 09-06 spent OIDC issuer and IAM trust for ServiceAccounts. 09-03 spent AKS Ingress and Application Gateway paths. Today spends GKE GatewayClass + Gateway + HTTPRoute, with shared listeners as the operational win over classic Ingress-per-app.
§VI — Operator checklist
kubectl get gatewayclassand note which GKE classes are installed.- Inventory Gateways and their listener hostnames/ports.
- List HTTPRoutes and
parentRefs; flag routes with Accepted=False. - Confirm TLS Secrets and any ReferenceGrant objects for cross-namespace refs.
- Curl (or Load Balancer health) only after Gateway status shows a programmed address.
- Pair with Dev census before migrating fleets off Ingress.
§VII — Closing
Split the front door from the routes. Name the class, own the listener, attach the HTTPRoute. Leave PSA, NetworkPolicy, and cloud identity on their own shelves.
Related
- Dev - Python Gateway API HTTPRoute census
- Cert - CKA Gateway API migrate Ingress