Checking out HAProxy Ingress Controller

Srujan ReddySrujan Reddy
4 min read

Introduction

For me HAProxy is reminiscent of the days when I am still figuring out my way around software world. I started my career while working with HAProxy load-balancer. Back then we used to use automated shell scripts to dynamically configure backends for load-balancing. Both of us have came long way since then ๐Ÿ˜€

Yet another Ingress Controller

In the eco-system over crowded with multiple Ingress controllers, HAProxy comes with an enterprise focused approach and innovative approaches like rootless containers and QUIC protocol. Coming from a legacy of LBing in VMs, all the existing features are extended to the Ingress Controller as well. Here is the list of all config map options that are available.

Installation

The HAProxy Ingress controller installation is straightforward. Here I have created a simple EKS cluster and installed HAProxy using Helm

## Cluster
โžœ  ~ k get nodes
NAME                                       STATUS   ROLES    AGE     VERSION
ip-10-0-1-221.us-east-2.compute.internal   Ready    <none>   2m15s   v1.27.9-eks-5e0fdde
ip-10-0-2-143.us-east-2.compute.internal   Ready    <none>   2m21s   v1.27.9-eks-5e0fdde

## HAProxy installation
โžœ  ~ helm install haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \
  --create-namespace \
  --namespace haproxy-controller
NAME: haproxy-kubernetes-ingress
LAST DEPLOYED: Tue Mar 26 16:31:10 2024
NAMESPACE: haproxy-controller
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
HAProxy Kubernetes Ingress Controller has been successfully installed.

Controller image deployed is: "haproxytech/kubernetes-ingress:1.11.2".
Your controller is of a "Deployment" kind. Your controller service is running as a "NodePort" type.
RBAC authorization is enabled.
Controller ingress.class is set to "haproxy" so make sure to use same annotation for
Ingress resource.

Service ports mapped are:
  - name: http
    containerPort: 8080
    protocol: TCP
  - name: https
    containerPort: 8443
    protocol: TCP
  - name: stat
    containerPort: 1024
    protocol: TCP
  - name: quic
    containerPort: 8443
    protocol: UDP

## Components Installed

โžœ  learn_haproxy_ingress k get all -n haproxy-controller                                         
NAME                                              READY   STATUS      RESTARTS   AGE
pod/haproxy-kubernetes-ingress-6b9d5f976c-bvqfd   1/1     Running     0          18s
pod/haproxy-kubernetes-ingress-6b9d5f976c-v2lb4   1/1     Running     0          18s
pod/haproxy-kubernetes-ingress-crdjob-1-qzr5p     0/1     Completed   0          18s

NAME                                 TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                  AGE
service/haproxy-kubernetes-ingress   NodePort   10.110.187.218   <none>        80:32563/TCP,443:30875/TCP,443:30875/UDP,1024:32400/TCP,6060:31395/TCP   18s

NAME                                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/haproxy-kubernetes-ingress   2/2     2            2           18s

NAME                                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/haproxy-kubernetes-ingress-6b9d5f976c   2         2         2       18s

Testing with sample application

On a side note, I am trying the ingress controller in minikube so Ingress runs as a nodePort service. I have to portforward these ports using command

โžœ  learn_haproxy_ingress minikube service haproxy-kubernetes-ingress -n haproxy-controller --url
http://127.0.0.1:50314
http://127.0.0.1:50315
http://127.0.0.1:50316
http://127.0.0.1:50317
http://127.0.0.1:50318

Now you have to figure out which host port forwards to which service port in ingress. I found 50317 is HTTP(80) and 50315 is HTTPS(443). If you are trying this out, it may be same for you or might be different

For trying the Ingress, I have followed their book "HAProxy in Kubernetes - Supercharge Your Ingress Routing".

I have deployed sample application using below definition

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: app
  name: app
spec:
  replicas: 2
  selector:
    matchLabels:
      run: app
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: jmalloc/echo-server
        ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: app
  name: app
  annotations:
    haproxy.org/check: "enabled"
    haproxy.org/forwarded-for: "enabled"
    haproxy.org/load-balance: "roundrobin"
spec:
  selector:
    run: app
  ports:
  - name: port-1
    port: 80
    protocol: TCP
    targetPort: 8080

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  namespace: default
spec:
  rules:
  - host: foo.bar
  - http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: app
              port: 
                number: 80

Features

HAProxy Ingress Controller comes with all the features HAProxy has. It also has support to create TLS certs on the go for induvidual services as required.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    # add an annotation indicating the issuer to
use
    cert-manager.io/cluster-issuer:
letsencrypt-staging
  name: mysite-ingress
  namespace: default
spec: rules:
  - host: mysite.com
    http:
      paths:
      - path: /
        backend:
          serviceName: mysite-service
          servicePort: 80
  tls:
  - secretName: mysite-cert
    hosts:
    - mysite.com

It will allow you to define backend, global and default groups to have fine-grained access controls like setting up algorithm keep-alive and forwardfor etc.

Conclusion

HAProxy ingress is a compelling choice for the companies looking for enterprise supported tooling for safety and compliance and for companies who already uses HAProxy LB for their legacy systems.

0
Subscribe to my newsletter

Read articles from Srujan Reddy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Srujan Reddy
Srujan Reddy

I am a Kubernetes Engineer passionate about leveraging Cloud Native ecosystem to run secure, efficient and effective workloads.