Checking out HAProxy Ingress Controller
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.
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.