Gateway API

Configure HAProxy using Gateway API resources.

Gateway API is a collection of Kubernetes resources that can be installed as Custom Resource Definitions. Just like Ingress resources, Gateway API resources are used to configure incoming HTTP/s, TLS and TCP requests to the in cluster applications.

Installation

The following steps configure the Kubernetes cluster and HAProxy Ingress to read and parse Gateway API resources:

  • Manually install the Gateway API CRDs, see instructions in the Gateway API documentation

    Use the experimental channel if need the TCPRoute API, all the other APIs are on the standard channel

  • Install or restart the controller

See below the getting started steps.

Command-line tool

Gateway API has also a command-line tool, see how it works and installation instructions: https://github.com/kubernetes-sigs/gwctl

Conformance

HAProxy Ingress is a Gateway API conformant implementation. The following APIs have all their core features implemented:

  • Gateway
  • HTTPRoute
  • TLSRoute
  • TCPRoute
  • ReferenceGrant

The following APIs are currently unsupported:

  • GRPCRoute
  • UDPRoute (*)
  • BackendTLSPolicy

(*) HAProxy does not support UDP routing, so the UDPRoute API will continue to be unsupported on future releases.

Gateway API resources don’t support annotations, this should continue to be unsupported. Extensions to the Gateway API spec will be added in the extension points of the API. However, target Services can be annotated with Backend or Path scoped configuration keys, this will continue to be supported.

Ingress API support

A single HAProxy Ingress deployment can manage Ingress, and all versions of the supported Gateway API resources in the same Kubernetes cluster. If the same hostname and path with the same path type is declared in the Gateway API and Ingress, the Gateway API wins and a warning is logged. Ingress resources will continue to be supported in future controller versions, without side effects, and without the need to install the Gateway API CRDs.

Getting started

Follow the steps below to expose the echoserver service from the Getting Started guide using the Gateway API.

  • Manually install the Gateway API CRDs

  • Install or restart HAProxy Ingress so it can find the just installed APIs:

    $ kubectl --namespace ingress-controller delete pod -lapp.kubernetes.io/name=haproxy-ingress
    
  • Create a GatewayClass with the following content:

    GatewayClass enables Gateways to be read and parsed by HAProxy Ingress.

    apiVersion: gateway.networking.k8s.io/v1
    kind: GatewayClass
    metadata:
      name: haproxy
    spec:
      controllerName: haproxy-ingress.github.io/controller
    

Deploy HTTP workload

  • Add the following deployment and service if echoserver isn’t running yet:

    $ kubectl --namespace default create deployment echoserver --image k8s.gcr.io/echoserver:1.3
    $ kubectl --namespace default expose deployment echoserver --port=8080
    
  • Create a Gateway with the following content:

    Gateways create listeners and allow to configure hostnames for HTTP workloads.

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: echoserver
      namespace: default
    spec:
      gatewayClassName: haproxy
      listeners:
      - name: echoserver-gw
        port: 80
        protocol: HTTP
    
  • Create a HTTPRoute with the following content, changing echoserver-from-gateway.local to a hostname that resolves to a HAProxy Ingress node:

    HTTPRoutes configure the hostnames and target services.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: echoserver
      namespace: default
    spec:
      parentRefs:
      - name: echoserver
      hostnames:
      - echoserver-from-gateway.local
      rules:
      - backendRefs:
        - name: echoserver
          port: 8080
    
  • Send a request to our just configured route:

    $ curl http://echoserver-from-gateway.local
    $ wget -qO- http://echoserver-from-gateway.local
    

Deploy TCP workload

  • Add the following deployment and service:

    $ kubectl --namespace default create deployment redis --image docker.io/redis
    $ kubectl --namespace default expose deployment redis --port=6379
    
  • A new port need to be added if HAProxy Ingress is not configured in the host network. If so, add the following snippet in values.yaml and apply it using Helm:

    controller:
      ...
      service:
        ...
        extraPorts:
        - port: 6379
          targetPort: 6379
    
  • Create a Gateway with the following content:

    Gateways create listeners and allow to configure the listening port for TCP workloads.

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: redis
      namespace: default
    spec:
      gatewayClassName: haproxy
      listeners:
      - name: redis-gw
        port: 6379
        protocol: TCP
    
  • Create a TCPRoute with the following content:

    TCPRoutes configure the target services.

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: TCPRoute
    metadata:
      name: redis
      namespace: default
    spec:
      parentRefs:
      - name: redis
      rules:
      - backendRefs:
        - name: redis
          port: 6379
    
  • Send a ping to the Redis server using curl. Change 192.168.106.2 below to the IP address of HAProxy Ingress:

    Type ping and see a +PONG response. Press ^C to close the connection.

    $ curl -v telnet://192.168.106.2:6379
    *   Trying 192.168.106.2:6379...
    * Connected to 192.168.106.2 (192.168.106.2) port 6379
    ping
    +PONG
    ^C
    

What’s next

See also the Gateway API documentation

Last modified March 9, 2026: improve gateway api doc (#1409) (d759d008)