HAProxy Kubernetes Ingress Controller Documentation 1.10

Enable the Gateway API

In this section, you will learn how to enable Gateway API in HAProxy Kubernetes Ingress Controller 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

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

  • Deploy the Gateway API custom resource definitions:

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

Update your ingress controller

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

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

    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.

    Enterprise edition

    Coming soon

    Community edition

    $  helm upgrade haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
        --namespace haproxy-controller \
        -f override.yaml

Update with kubectl

To enable Gateway API features with kubectl:

Enterprise edition

Coming soon

Community edition

  1. Download the ingress controller's Deployment manifest.

  2. Edit the haproxy-kubernetes-ingress Deployment object to have the --gateway-controller-name argument:

    spec:
      serviceAccountName: haproxy-kubernetes-ingress
      containers:
      - name: haproxy-ingress
        image: haproxytech/kubernetes-ingress
        args:
          - --configmap=haproxy-controller/haproxy-kubernetes-ingress
          - --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:

    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:

    $ 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:

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

Define a GatewayClass

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:

    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:

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

Define a Gateway

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:

    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:

    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:

    $ kubectl apply -f example-gateway.yaml

Define routes

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.

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

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

    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:

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

    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:

    $ kubectl apply -f example-service.yaml

Next up

Use TCPRoute