# haproxy kubernetes-ingress: HAProxy as the cluster front door

> The HAProxy Kubernetes Ingress Controller is an Apache 2.0 licensed Go controller that turns Ingress resources into HAProxy configuration, shipped as a Docker image, as a plain YAML apply, and as official Helm charts. The judgement is that this is the controller to look at if HAProxy is already your edge, and that its power comes from the annotation surface rather than from the routing itself.

**haproxytech/kubernetes-ingress** — HAProxy Ingress Controller for Kubernetes https://www.haproxy.com/blog/announcing-haproxy-kubernetes-ingress-controller-3-2

- Repository: https://github.com/haproxytech/kubernetes-ingress
- Website: https://www.haproxy.com/documentation/kubernetes/
- Stars: 870 · Forks: 234
- Language: Go
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/haproxytech-kubernetes-ingress

## The controller's job, and the layer above it

The definition in the README is short and it fixes the scope. An ingress controller is a Kubernetes resource that routes traffic from outside your cluster to services within the cluster. What this repository adds is the HAProxy implementation of that idea, and the mechanism is that the controller watches Ingress objects and drives an HAProxy instance to match them. The interesting surface is not the routing, which any controller does, but the configuration vocabulary around it. The repository carries a list of all available Ingress annotations, which is where the fine tuning lives, and the detailed documentation is published by HAProxy Technologies rather than in the repository itself. For an operator, the practical sequence is that the controller turns your Ingress objects into a running HAProxy, and the annotations are how you tell it what that HAProxy should do beyond the basics.

## Three ways to get it running

The deployment options cover the three common situations. The first is the published image, haproxytech/kubernetes-ingress on Docker Hub, which is what most clusters use. The second is building from source, and the Makefile target is a docker build against build/Dockerfile:

```bash
make build
```

That defaults to the linux/amd64 platform, and the target platform is a variable, so a different architecture is a one line change:

```bash
make build TARGETPLATFORM=linux/arm/v6
```

The third is the plain manifest route, which the README points at for a basic setup, and it is a single apply:

```bash
kubectl apply -f deploy/haproxy-ingress.yaml
```

For local work there is also a make example target, which creates a working example environment, and a set of variants around it that rebuild or remove that environment from the scripts under deploy/tests. The controller image's own arguments are documented separately in documentation/controller.md, and that file is the reference to read when you want to change how the controller itself behaves.

## Helm charts are a separate repository

One thing to know before you plan the deployment is that the Helm charts are not in this repository. Official HAProxy Technologies Helm Charts for deploying on Kubernetes live in the haproxytech/helm-charts repository, and the README links to them rather than shipping them here. That split is sensible in principle, since a chart is a packaging artefact with its own release cycle, and it keeps the controller repository focused on the controller. In practice it means one more repository to pull and to version, and one more place where a version mismatch between chart and controller can appear. If you deploy from the YAML manifest you avoid that entirely, and if you deploy from the chart you need to keep the chart's controller image tag aligned with the release you actually intend to run.

## What the Go dependencies reveal about the design

The go.mod file is a good map of how the controller talks to the world, and a few entries deserve attention. The module is github.com/haproxytech/kubernetes-ingress and it declares go 1.27, so the build needs a current toolchain. The client-native libraries from HAProxy appear twice, v5 at 5.1.28 and v6 at 6.4.3, which is how the controller speaks to HAProxy over its runtime API in both the older and the newer protocol version. The Kubernetes libraries are pinned together at version 0.37.1 for api, apiextensions-apiserver, apimachinery and client-go, and controller-tools at 0.18.0 for the custom resource definitions. Beyond that there is prometheus/client_golang, so metrics are a first class output rather than an afterthought, pires/go-proxyproto for the PROXY protocol, cel-go for expression evaluation in configuration, Masterminds/semver for version comparison, go.uber.org/automaxprocs for CPU limits in containers, and the usual yaml and protobuf libraries. The tree also holds a crs directory with a code generator, which is where the custom resource definitions come from.

## The Makefile is the real documentation of the workflow

The Makefile shows how the project expects developers to work, and read it before contributing. Tests run through gotestsum with a testdox format, and the unit test target deliberately excludes the end to end tests under deploy/tests/e2e. Those have their own targets, and they are split by design, with a parallel phase tagged e2e_parallel and e2e_https and a sequential phase run with -p 1 so that the cases which need exclusive access do not collide. A third variant sets CRD_VERSION=v1, which tests the older custom resource definition version against the same suite. There is also a tidy target running go mod tidy, a doc target that runs the generator under cmd/docs, a lint target that installs the go-task tool and runs task lint, a commit message check pinned to version 5.8.1 of the checker, and a yaml-lint target that runs the cytopia yamllint image against the tree. The build-dev target is the one to know about, because it compiles the controller binary locally with CGO disabled and then bakes it into the development Dockerfile, which is how you test a local change against the real image.

## Support, contribution and where the work happens

The project has a clear division between discussion, code and community. A GitHub issue is the right place to discuss feature requests, bug reports or anything else that needs tracking, and questions and informal conversation belong in the ingress-controller channel of the HAProxy Community Slack. For code, pull requests are welcome, and the guidance is to follow the haproxy project's own contributing guide for commit messages and general style where that applies, which is a sensible convention since this controller shares engineering culture with the proxy itself. The lint task is the one to run before sending a change. The repository also points at the HAProxy blog post announcing the 3.2 series of the controller, which is the best short introduction to what changed in the version line most people are running now, and the tree shows a mixed CI setup with GitLab CI configuration alongside GitHub workflows and a goreleaser configuration for the publish step.

## Patch releases every couple of weeks, and an Apache licence

The licence is Apache 2.0, which is the permissive choice and the same one HAProxy itself uses, so there is no friction in mixing them. On the release side, the tags move quickly and only on the patch line, with v3.2.15 on 2026-09-11, v3.2.16 on 2026-10-07 and v3.2.17 on 2026-10-15, which is a rhythm of roughly one patch every two weeks inside a single minor series. The last push to the master branch was on 2026-10-19 and the repository is not archived. The top level of the tree gives you the shape of the project, with cmd and pkg holding the Go code, deploy holding the manifests and the test scripts, documentation holding the annotation list and the controller arguments, crs holding the custom resource definition generator, fs, test, build, bin, a workspace folder holding a test informers project, assets, and the tooling files such as taskfile.yml, revive.toml for the linter configuration, the goreleaser configuration and the aspell and commit message check configurations. The last of these, the spell check and the commit message checker, are small signs of a project that is fussy about housekeeping.

## Conclusion

haproxytech kubernetes-ingress fits a team that has chosen HAProxy as its ingress layer and wants a controller that speaks its native configuration language, including the PROXY protocol for client IPs and Prometheus metrics out of the box. It is the wrong choice if your edge is already an ingress controller you have standardised on, since the value here is HAProxy specific, and it is a poor fit for a cluster that needs a gateway API implementation, because the repository documents Ingress annotations rather than that resource. Before you deploy, read the annotation list in documentation/README.md to see whether the behaviour you need is configurable, and check the controller arguments in documentation/controller.md, since that is where the image's behaviour is actually set.

## FAQ

### How do I deploy the HAProxy Kubernetes Ingress Controller?

The quickest route is the manifest in the repository, kubectl apply -f deploy/haproxy-ingress.yaml. The controller image is published on Docker Hub as haproxytech/kubernetes-ingress, and official Helm charts live in the separate haproxytech/helm-charts repository. All available arguments for the controller image are listed in documentation/controller.md.

### How do I build the HAProxy ingress controller from source?

Run make build, which uses a Docker build against build/Dockerfile and defaults to the linux/amd64 platform. For a different architecture pass the target platform as a variable, such as make build TARGETPLATFORM=linux/arm/v6. There is also a make example target that creates a local example environment.

### Where are the available ingress annotations documented?

The repository contains a list of all available Ingress annotations under the documentation directory, in documentation/README.md. The same documentation directory holds controller.md, which covers the arguments of the controller image itself, while the fuller narrative documentation is published by HAProxy Technologies.

## Sources

- [haproxytech/kubernetes-ingress on GitHub](https://github.com/haproxytech/kubernetes-ingress)
- [License: Apache-2.0](https://github.com/haproxytech/kubernetes-ingress/blob/master/LICENSE)
- [Project website](https://www.haproxy.com/documentation/kubernetes/)
- [README](https://github.com/haproxytech/kubernetes-ingress/blob/master/README.md)
- [Releases](https://github.com/haproxytech/kubernetes-ingress/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/haproxytech-kubernetes-ingress
