Skip to content

feat: Kubernetes Gateway API backend (experimental)#65

Merged
danieloliveira079 merged 7 commits intomainfrom
feature/gateway-api-support
Mar 27, 2026
Merged

feat: Kubernetes Gateway API backend (experimental)#65
danieloliveira079 merged 7 commits intomainfrom
feature/gateway-api-support

Conversation

@danieloliveira079
Copy link
Copy Markdown
Contributor

Summary

  • Adds octops.io/router-backend: gateway as an opt-in alternative to the default Ingress backend
  • When set, the controller creates one HTTPRoute per GameServer (instead of Ingress), attaching it to a pre-provisioned shared Gateway
  • TLS is terminated at the Gateway listener using a single wildcard/hostname certificate — no per-server cert-manager requests, no Let's Encrypt rate limits
  • Both domain and path routing modes are supported, matching the existing Ingress behaviour
  • Ingress backend is unchanged; the two backends can run in the same cluster with separate Contour installations

Changes

  • pkg/: GatewayReconciler, gatewayStore, functional options, GetRouterBackend() helper, RecordWarning event method
  • deploy/install.yaml: added httproutes RBAC to the controller ClusterRole
  • deploy/gateway/gatewayclass.yaml: GatewayClass for Contour Gateway Provisioner
  • examples/gateway/: gateway.yaml, certificate.yaml, fleet-domain.yaml, fleet-path.yaml
  • hack/: setup-infra.sh and teardown-infra.sh updated to install Gateway API CRDs, Contour Gateway Provisioner, and apply the required CRD patches for Contour v1.32.1 compatibility
  • README.md: new Gateway API section with prerequisites, setup, annotation reference, and experimental notice
  • AGENTS.md: local dev workflow, gateway sharp edges, updated deploy layout

Validation

Tested end-to-end on a local Docker Desktop cluster:

# Domain mode — each game server on its own subdomain
curl -H "Host: octops-gateway-domain-mhzh7-948k5.game.example.com" http://localhost:8080/
{"Name":"octops-gateway-domain-mhzh7-948k5","Address":"172.18.0.2:7265",...}

# Path mode — shared hostname, per-server path
curl -H "Host: game.example.com" http://localhost:8080/octops-gateway-path-8vvj4-jl6bs
{"Name":"octops-gateway-path-8vvj4-jl6bs","Address":"172.18.0.2:7643",...}

Gateway status: PROGRAMMED: True. All HTTPRoutes: Accepted=True, ResolvedRefs=True. Envoy routes each request to the correct game server.

Experimental — validated but not production-tested. Please report bugs at https://github.com/Octops/gameserver-ingress-controller/issues.

Test plan

  • hack/setup-infra.sh runs clean on a fresh cluster
  • Deploy examples/gateway/fleet-domain.yaml — verify one HTTPRoute per GameServer, Accepted=True
  • Deploy examples/gateway/fleet-path.yaml — verify path-based HTTPRoute per GameServer
  • curl with correct Host header reaches the right game server in both modes
  • Deleting a GameServer cascades to HTTPRoute and Service cleanup via owner references
  • Ingress backend fleets are unaffected when deployed alongside gateway fleets

🤖 Generated with Claude Code

danieloliveira079 and others added 7 commits March 27, 2026 12:17
Adds octops.io/router-backend: gateway as an opt-in alternative to the
default Ingress backend. When set, the controller creates one HTTPRoute
per GameServer instead of an Ingress, attaching it to a pre-provisioned
shared Gateway. TLS is terminated at the Gateway listener, avoiding
per-server cert-manager certificates and Let's Encrypt rate limits.

- pkg/gameserver: RouterBackend type, GetRouterBackend(), and new
  gateway-related annotation constants
- pkg/record: HTTPRouteKind constant and RecordWarning for no-op
  annotation warnings in gateway mode
- pkg/reconcilers: GatewayReconciler + functional options
  (WithHTTPRouteParentRef, WithHTTPRouteRules for domain/path modes,
  WithCustomHTTPRouteAnnotations*)
- pkg/stores: gatewayStore wrapping gateway-api client + informer;
  wired into composite Store via rest.Config
- pkg/handlers: dispatch to GatewayReconciler when router-backend=gateway
- go.mod: add sigs.k8s.io/gateway-api v1.5.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The gateway backend requires list/get/create/delete/watch on
gateway.networking.k8s.io/httproutes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- examples/gateway/fleet-{domain,path}.yaml: opt-in gateway backend
  with octops/gameserver-http:latest (containerPort 8088) and http
  section name for HTTP-only Gateway listeners
- examples/gateway/gateway.yaml: shared Gateway resource with http and
  https listeners; gatewayClassName updated to contour (provisioner)
- examples/fleet-{domain,path}.yaml: switch default image to
  octops/gameserver-http:latest

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setup-infra.sh:
- cert-manager v1.17.1 → v1.20.0
- install Gateway API CRDs (experimental channel, server-side apply)
- patch TLSRoute/v1alpha2 and BackendTLSPolicy/v1alpha3 for Contour
  v1.32.1 compatibility
- install Contour Gateway Provisioner alongside standard Contour
- apply GatewayClass and an HTTP Gateway in the default namespace

teardown-infra.sh:
- delete Gateway resources and HTTPRoutes before namespace teardown
- remove Gateway Provisioner and Gateway API CRDs
- force-finalize stuck Terminating namespaces (load-balancer finalizer
  on Docker Desktop causes hangs without this)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
README.md:
- Gateway API section with prerequisites, Contour setup (ingress vs
  gateway, side-by-side operation), annotation reference, HTTPRoute
  output examples, and experimental status notice
- cert-manager version updated to v1.20.0
- Contour install section split by backend with explicit commands

AGENTS.md:
- Gateway API Backend section: design decisions, known CRD compatibility
  workarounds for Contour v1.32.1 + Gateway API v1.5.1, full install
  steps with required flags
- Local Development section: make run workflow, hack script overview
- Gateway API Experimental Status section: sharp edges for future agents
  (containerPort 8088, Docker Desktop port-forward, CRD patches)
- deploy/ layout updated to show gateway/ and cert-manager/ split

docs/gateway-api-support-plan.md: updated plan reflecting final design

Makefile: fix make run to mount config.yml (was k3s.yaml)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Contour Gateway Provisioner creates Contour+Envoy pods in the same
namespace as the Gateway resource. Placing the Gateway in `default`
pollutes the application namespace with infrastructure pods.

- hack/setup-infra.sh: create octops-gateway namespace; deploy Gateway
  there with allowedRoutes.namespaces.from: All so HTTPRoutes in default
  can still attach
- hack/teardown-infra.sh: include octops-gateway in namespace cleanup
- examples/gateway/gateway.yaml: namespace octops-gateway, allowedRoutes
  from: All on both listeners
- examples/gateway/fleet-{domain,path}.yaml: add
  octops.io/gateway-namespace: octops-gateway annotation so the
  controller sets the correct parentRef namespace in each HTTPRoute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@danieloliveira079 danieloliveira079 merged commit 172c62b into main Mar 27, 2026
1 check passed
@danieloliveira079 danieloliveira079 deleted the feature/gateway-api-support branch March 27, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant