Gateway API

Gateway API examples with HTTPRoute

Expose apps with HTTPRoute while keeping image, Service, and probes in the same values file.

Chart fidelity

Examples below match Universal Helm Chart application 0.4.3 keys from values.yaml and docs/configuration.md. Replace ghcr.io/example-org/* images and hostnames with your own.

Chart 0.4.3 — args / multi-port / service.enabled

From application 0.4.3: main container args (default []); Deployment revisionHistoryLimit (default 10); multi-port via containerPorts and service.ports; optional chart-managed Service via service.enabled (default true). When service.ports is set, Ingress / simple HTTPRoute / NOTES use the first entry (templates/_helpers.tpl application.servicePort). Legacy single-port service.name / service.port / service.protocol / service.appProtocol remain supported. Set service.enabled: false when the workload does not need a chart-managed Service. Do not invent other port keys.

Chart 0.4.3 — route.spec

From application 0.4.3, set route.spec to a complete HTTPRoute.spec (parentRefs, hostnames, rules, filters, multi-backendRefs). When route.spec is non-empty, the chart renders it unchanged and ignores the simple route.hostname / route.path / route.gateway generator. Simple route.* remains the default path; route.gateway is required only when route.enabled: true and route.spec is empty. Do not invent shorthand keys like route.headers or route.cors.

Chart 0.4.3 — service.appProtocol

Optional service.appProtocol (default "") sets Service.spec.ports[].appProtocol on the chart-managed Service (templates/7_service.yaml). For Services created by ingressPlain paths with createService: true, set paths[].service.appProtocol (since 0.4.0). Leave empty when you do not need a protocol hint (for example grpc). Do not invent other service.* protocol keys.

Prerequisites

Minimal route values

Defaults in chart values: route.enabled: false, hostname: chart-example.local, path: /, pathMatchType: PathPrefix, backendWeight: 1. When enabled: true and route.spec is empty, route.gateway is required.

service:
  port: 8080
route:
  enabled: true
  gateway: external
  gatewayNamespace: gateway-system
  sectionName: https
  hostname: api.example.com
  path: /
  pathMatchType: PathPrefix
  backendWeight: 1
  timeouts:
    request: 75s
    backendRequest: 75s

Rendered object: apiVersion: gateway.networking.k8s.io/v1, kind: HTTPRoute. parentRefs point at the Gateway; backendRefs target the chart Service fullname on service.port.

Two services, hostname routing

Deploy two releases; only hostnames differ:

# values-orders.yaml
image: ghcr.io/example-org/orders
imageTag: "1.0.0"
imagePullPolicy: IfNotPresent
service:
  port: 8080
route:
  enabled: true
  gateway: external
  gatewayNamespace: gateway-system
  sectionName: https
  hostname: orders.example.com
# values-payments.yaml — same chart, different hostname
image: ghcr.io/example-org/payments
imageTag: "1.0.0"
imagePullPolicy: IfNotPresent
service:
  port: 8080
route:
  enabled: true
  gateway: external
  gatewayNamespace: gateway-system
  sectionName: https
  hostname: payments.example.com
helm upgrade --install orders universal/application --version 0.4.3 -n apps --create-namespace -f values-orders.yaml
helm upgrade --install payments universal/application --version 0.4.3 -n apps --create-namespace -f values-payments.yaml
kubectl get httproute -n apps
kubectl describe httproute -n apps orders

Inspect status.parents / Accepted conditions on each HTTPRoute after the controller reconciles.

Path-based routing on one hostname

Simple mode models a single path match per release (route.path + route.pathMatchType). For path splitting under one hostname, either:

route:
  enabled: true
  gateway: external
  gatewayNamespace: gateway-system
  sectionName: https
  hostname: apps.example.com
  path: /orders
  pathMatchType: PathPrefix

Advanced: complete HTTPRoute.spec via route.spec

When route.spec is non-empty, metadata still comes from route.name / route.labels / route.annotations, but the generated simple spec is skipped. Example shape from chart docs (sanitize names/hosts before apply):

fullnameOverride: clustersentinel
service:
  port: 8080
route:
  enabled: true
  name: clustersentinel
  spec:
    parentRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: external
        namespace: kgateway-system
        sectionName: https-wildcard
    hostnames:
      - clustersentinel.example.com
    rules:
      - matches:
          - path:
              type: Exact
              value: /health
          - path:
              type: PathPrefix
              value: /mcp
        backendRefs:
          - group: ""
            kind: Service
            name: clustersentinel
            port: 8080
            weight: 1

Ingress still available

Classic Ingress remains under ingress.enabled (default false). Prefer one exposure path per service—HTTPRoute or Ingress—unless you intentionally dual-publish.

Full parameter table: configuration.md § Gateway API Route.

FastAPI example with route → · Why one chart is enough → · Install →