Gateway API tutorials

Enable the Gateway API

Available since

version 1.10

In this section, you will learn how to enable Gateway API in by installing GatewayClasses, Gateways, and Routes.

The Gateway API is a new way to define network routing in Kubernetes. HAProxy Kubernetes Ingress Controller implements this API alongside its support for the older and established Ingress API.

With objects meant to promote a separation of concerns between platform engineers, cluster operators, and application developers, Gateway API can improve workflows and access control, whereas those lines are more blurred in Ingress API.

For example, in Ingress API, the same person will often choose which ingress controllers to use and then deploy them into the cluster. In Gateway API, one person in the organization can handle choosing which Gateway API implementations to make available, and then someone else can pick which ones to use from that list.

Deploy Gateway API resources Jump to heading

Install the resources that enable Gateway API functionality in your cluster:

  • Deploy the Gateway API custom resource definitions:

    nix
    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.1/experimental-install.yaml
    nix
    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.1/experimental-install.yaml

Update your ingress controller Jump to heading

Update your HAProxy Kubernetes Ingress Controller deployment to support Gateway API.

  • Set the --gateway-controller-name startup argument.
  • Add any TCP ports at which you will accept traffic to the ingress controller’s Service definition.

Update with Helm Jump to heading

If using Helm, create an override.yaml file that creates the necessary ClusterRoleBinding object and update the ingress controller Deployment to have the --gateway-controller-name argument. You will also need to add any ports at which you will listen for TCP traffic.

  1. Create an override.yaml file that enables Gateway API and sets TCP ports where the controller should listen.

    override.yaml
    yaml
    controller:
    kubernetesGateway:
    enabled: true
    gatewayControllerName: haproxy.org/gateway-controller
    service:
    tcpPorts:
    - name: listener1
    protocol: TCP
    port: 8000
    targetPort: 8000
    override.yaml
    yaml
    controller:
    kubernetesGateway:
    enabled: true
    gatewayControllerName: haproxy.org/gateway-controller
    service:
    tcpPorts:
    - name: listener1
    protocol: TCP
    port: 8000
    targetPort: 8000
  2. Use helm upgrade to make the changes.

    nix
    helm upgrade haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
    --namespace haproxy-controller \
    -f override.yaml
    nix
    helm upgrade haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
    --namespace haproxy-controller \
    -f override.yaml
    nix
    helm upgrade haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
    --create-namespace \
    --namespace haproxy-controller \
    --set controller.imageCredentials.registry=kubernetes-registry.haproxy.com \
    --set controller.imageCredentials.username=<KEY> \
    --set controller.imageCredentials.password=<KEY> \
    --set controller.image.repository=kubernetes-registry.haproxy.com/hapee-ingress \
    --set controller.image.tag=v1.11 \
    -f override.yaml
    nix
    helm upgrade haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
    --create-namespace \
    --namespace haproxy-controller \
    --set controller.imageCredentials.registry=kubernetes-registry.haproxy.com \
    --set controller.imageCredentials.username=<KEY> \
    --set controller.imageCredentials.password=<KEY> \
    --set controller.image.repository=kubernetes-registry.haproxy.com/hapee-ingress \
    --set controller.image.tag=v1.11 \
    -f override.yaml

Update with kubectl Jump to heading

To enable Gateway API features with kubectl:

  1. Download the deployment YAML file.

    Product Link
    Community version Deployment YAML (v1.11)
    Enterprise version Deployment YAML file (v1.11)
  2. Edit the YAML file’s Deployment object to have the --gateway-controller-name argument:

    haproxy-ingress.yaml
    yaml
    args:
    - --gateway-controller-name=haproxy.org/gateway-controller
    haproxy-ingress.yaml
    yaml
    args:
    - --gateway-controller-name=haproxy.org/gateway-controller
  3. Also update the haproxy-kubernetes-ingress Service object to list listening ports. In the example below, we add listener1:

    haproxy-ingress.yaml
    yaml
    spec:
    selector:
    run: haproxy-ingress
    type: NodePort
    ports:
    - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    - name: stat
    port: 1024
    protocol: TCP
    targetPort: 1024
    - name: listener1
    protocol: TCP
    port: 8000
    targetPort: 8000
    haproxy-ingress.yaml
    yaml
    spec:
    selector:
    run: haproxy-ingress
    type: NodePort
    ports:
    - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    - name: stat
    port: 1024
    protocol: TCP
    targetPort: 1024
    - name: listener1
    protocol: TCP
    port: 8000
    targetPort: 8000

    Apply the changes with kubectl apply:

    nix
    kubectl apply -f haproxy-ingress.yaml
    nix
    kubectl apply -f haproxy-ingress.yaml
  4. Deploy the HAProxy Kubernetes Ingress Controller RBAC resources, which give the haproxy-kubernetes-ingress ServiceAccount permissions to use the Gateway API resource types:

    nix
    kubectl apply -f https://raw.githubusercontent.com/haproxytech/kubernetes-ingress/master/deploy/tests/config/experimental/gwapi-rbac.yaml
    nix
    kubectl apply -f https://raw.githubusercontent.com/haproxytech/kubernetes-ingress/master/deploy/tests/config/experimental/gwapi-rbac.yaml

Define a GatewayClass Jump to heading

A GatewayClass makes a Gateway API implementation available so that cluster operators can use it. Platform engineers can be responsible for this, defining GatewayClass objects that are available in the cluster.

To deploy a GatewayClass for HAProxy Kubernetes Ingress Controller:

  • Create a file named haproxy-ingress-gatewayclass.yaml to define a GatewayClass:

    haproxy-ingress-gatewayclass.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: GatewayClass
    metadata:
    namespace: default
    name: haproxy-ingress-gatewayclass
    spec:
    controllerName: haproxy.org/gateway-controller
    haproxy-ingress-gatewayclass.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: GatewayClass
    metadata:
    namespace: default
    name: haproxy-ingress-gatewayclass
    spec:
    controllerName: haproxy.org/gateway-controller

    From this snippet:

    • The name attribute will uniquely identify this GatewayClass in the cluster.
    • The controllerName attribute refers to the name you set with --gateway-controller-name.

    Apply the changes with kubectl:

    nix
    kubectl apply -f haproxy-ingress-gatewayclass.yaml
    nix
    kubectl apply -f haproxy-ingress-gatewayclass.yaml

Define a Gateway Jump to heading

With Gateway objects, cluster operators can choose which Gateway API implementations to use.

To create a Gateway that listens on port 8000 and handles routing for applications in the default namespace:

  • Create a file that defines a Gateway object.

    Below, in a file named example-gateway.yaml, we define a Gateway that uses the ingress controller referred to by the haproxy-ingress-gatewayclass GatewayClass:

    example-gateway.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: Gateway
    metadata:
    name: example-gateway
    namespace: default
    spec:
    gatewayClassName: haproxy-ingress-gatewayclass
    listeners:
    - allowedRoutes:
    kinds:
    - group: gateway.networking.k8s.io
    kind: TCPRoute
    namespaces:
    from: All
    name: listener1
    port: 8000
    protocol: TCP
    example-gateway.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: Gateway
    metadata:
    name: example-gateway
    namespace: default
    spec:
    gatewayClassName: haproxy-ingress-gatewayclass
    listeners:
    - allowedRoutes:
    kinds:
    - group: gateway.networking.k8s.io
    kind: TCPRoute
    namespaces:
    from: All
    name: listener1
    port: 8000
    protocol: TCP

    In this example, the Gateway is deployed to the default namespace, and it will accept routes from all namespaces. Cluster operators can also deploy Gateways that accept routes from only the same namespace or specific namespaces by changing the allowedRoutes.namespaces section to have a from attribute of either:

    Value Description
    All Matches routes from any namespace.
    Same Matches routes from the same namespace where the Gateway is deployed.
    Selector Matches routes from namespaces matching the selector attribute. In this case, add a selector attribute to define the match criteria.

    Apply the changes with kubectl:

    nix
    kubectl apply -f example-gateway.yaml
    nix
    kubectl apply -f example-gateway.yaml

Define routes Jump to heading

After platform engineers have deployed the Gateway API resources, HAProxy Kubernetes Ingress Controller, and a GatewayClass, and after cluster operators have defined a Gateway that uses that GatewayClass, then application developers can define routes that make use of the Gateway.

Setting allowed routes

Earlier when defining the Gateway, we set allowedRoutes to accept routes of kind TCPRoute. This means that only those types of routes will be handled by that Gateway.

To define routing for TCP traffic to an application named example-service:

  1. Create a file named example-route.yaml with the following contents:

    example-route.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: TCPRoute
    metadata:
    name: example-route
    namespace: default
    spec:
    parentRefs:
    - group: gateway.networking.k8s.io
    kind: Gateway
    name: example-gateway
    namespace: default
    rules:
    - backendRefs:
    - group: ''
    kind: Service
    name: example-service
    port: 80
    weight: 10
    example-route.yaml
    yaml
    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: TCPRoute
    metadata:
    name: example-route
    namespace: default
    spec:
    parentRefs:
    - group: gateway.networking.k8s.io
    kind: Gateway
    name: example-gateway
    namespace: default
    rules:
    - backendRefs:
    - group: ''
    kind: Service
    name: example-service
    port: 80
    weight: 10

    Apply the changes with kubectl:

    nix
    kubectl apply -f example-route.yaml
    nix
    kubectl apply -f example-route.yaml
  2. Create a file named example-service.yaml to define an example application for the route:

    example-service.yaml
    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    namespace: default
    labels:
    run: app
    name: app
    spec:
    replicas: 1
    selector:
    matchLabels:
    run: app
    template:
    metadata:
    labels:
    run: app
    spec:
    containers:
    - name: app
    image: jmalloc/echo-server
    ports:
    - containerPort: 8080
    readinessProbe:
    httpGet:
    path: /
    port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5
    successThreshold: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
    namespace: default
    name: example-service
    spec:
    selector:
    run: app
    ports:
    - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
    example-service.yaml
    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    namespace: default
    labels:
    run: app
    name: app
    spec:
    replicas: 1
    selector:
    matchLabels:
    run: app
    template:
    metadata:
    labels:
    run: app
    spec:
    containers:
    - name: app
    image: jmalloc/echo-server
    ports:
    - containerPort: 8080
    readinessProbe:
    httpGet:
    path: /
    port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5
    successThreshold: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
    namespace: default
    name: example-service
    spec:
    selector:
    run: app
    ports:
    - name: http
    protocol: TCP
    port: 80
    targetPort: 8080

    Apply the changes with kubectl:

    nix
    kubectl apply -f example-service.yaml
    nix
    kubectl apply -f example-service.yaml

Do you have any suggestions on how we can improve the content of this page?