Custom Resources

December 18, 2025 ยท View on GitHub

  • In order to use custom resources, you will need to apply/update resource definitions
  • Custom Resources are used by Ingress Controller to implement HAProxy concepts like (backend, frontend, http rules, etc) which are all available under the ingress.v1.haproxy.org or ingress.v3.haproxy.org API.
  • Current implementation relies on the client-native library and its models to configure HAProxy.
  • Custom resources are meant to replace annotations when possible. So they will have precedance when used. Example: if the backend resource is used no backend annotation will be processed which means a backend cannot be configured by mixing both the backend resource and backend annotations.
  • For the Custom Resource to define TCP service, refer to Custom resource definition for TCP service

HAProxy concepts

  • Only HAProxy directives available in the resource definitions are supported, contributions and github requests to support new directives are welcome.
  • All timeout fields are integer input interpreted as time in ms.

Global

The Global resource is used to configure the HAProxy global section by referencing the resouce via the cr-global annotation in the Ingress Controller ConfigMap.

Example:

  1. Define a global resource
apiVersion: "ingress.v1.haproxy.org/v1"
kind: Global
metadata:
  name: myglobal
  namespace: haproxy-controller
spec:
  config:
    maxconn: 1000
    stats_timeout: 36000
    tune_ssl_default_dh_param: 2048
    ssl_default_bind_options: "no-sslv3 no-tls-tickets no-tlsv10"
    ssl_default_bind_ciphers:
    ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES
    hard_stop_after: 30000
    server_state_base: /tmp/haproxy-ingress/state
    runtime_apis:
      - address: "0.0.0.0:31024"
  1. Apply it:
$ kubectl apply -f myglobal.yaml
  1. Update the ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: kubernetes-ingress
  namespace: haproxy-controller
data:
  cr-global: haproxy-controller/myglobal

Global CRD: Note of versions compatibility between CRD and haproxy

The ingress.v1.haproxy.org/Global CRD version v1 is using client-native v5 that contains `haproxy 2.9`` keywords.

An annototation in the CRD is available to specify the version of client-native used: haproxy.org/client-native

Defaults

The Defaults resource is used to configure the HAProxy defaults section by referencing the resouce via the cr-defaults annotation in the Ingress Controller ConfigMap.

Example:

  1. Define a defaults resource
apiVersion: "ingress.v1.haproxy.org/v1"
kind: Defaults
metadata:
  name: mydefaults
  namespace: default
spec:
  config:
    log_format: "'%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs \"%HM %[var(txn.base)] %HV\"'"
    redispatch:
      enabled: enabled
      interval: 0
    dontlognull: enabled
    http_connection_mode: http-keep-alive
    http_request_timeout: 5000
    connect_timeout: 5000
    client_timeout: 50000
    queue_timeout: 5000
    server_timeout: 50000
    tunnel_timeout: 3600000
    http_keep_alive_timeout: 60000
  1. Apply it:
$ kubectl apply -f mydefaults.yml
  1. Update the ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: kubernetes-ingress
  namespace: haproxy-controller
data:
  cr-global: haproxy-controller/myglobal
  cr-defaults: haproxy-controller/mydefaults

Backend

The Backend resource is used to configure the HAProxy backend section by referencing the resouce via the cr-backend annotation in corresponding backend service. cr-backend annotation can be used also at the ConfigMap level (as default backend config for all services) or Ingress level (as a default backend config for the underlying services)

Example:

  1. Define a backend resource
apiVersion: "ingress.v1.haproxy.org/v1"
kind: Backend
metadata:
  name: mybackend
  namespace: haproxy-controller
spec:
  config:
    mode: http
    balance:
      algorithm: "leastconn"
    abortonclose: disabled
    default_server:
      verify: none
      resolve-prefer: ipv4
      check-sni: example.com
      sni: str(example.com)
  1. Apply it:
$ kubectl apply -f mybackend.yaml
  1. Annotate the corresponding service
apiVersion: v1
kind: Service
metadata:
  name: example
  namespace: external
  annotations:
    cr-backend: haproxy-controller/mybackend
spec:
  type: ExternalName
  externalName: example.com
  ports:
  - protocol: TCP
    port: 443
    name: https
    targetPort: 8443

Frontend

The frontend custom resource can be used to configure the three principal frontends http, https and stats. Caution, the frontends are the very interface of your load balancer. Any misconfiguration can shut down all of your services. Please, test in any preproduction environment before applying anything in your production environment. Be aware that the original configuration can only be amended not replaced. The three frontends aforementioned are addressable by creating a Frontend custom resource and then assign it to the target frontend in the configmap with these three annotations:

  • cr-frontend-http
  • cr-frontend-https
  • cr-frontend-stats
  1. Define a frontend resource
apiVersion: ingress.v3.haproxy.org/v3
kind: Frontend
metadata:
  name: test
spec:
  accept_invalid_http_request: enabled
  binds:
    test:
      address: 127.0.0.1
      port: 1234
      name: test
  name: test
  1. Apply it:
$ kubectl apply -f myfrontend.yaml
  1. Associate your target frontend with this frontend custom resource in the controller configmap
data:
  cr-frontend-http: default/test