annotations.md
June 15, 2026 ยท View on GitHub
HAProxy kubernetes ingress controller 3.2
This is autogenerated from doc.yaml. Description can be found in generator readme
Custom annotations
more info about custom annotations can be found in annotations-custom.md
Available annotations
:information_source: Ingress and service annotations can have
ingress.kubernetes.io,haproxy.organdhaproxy.comprefixesExample: haproxy.com/ssl-redirect
andhaproxy.org/ssl-redirect` are same annotation
| Annotation | Type | Default | Dependencies | Config map | Ingress | Service |
|---|---|---|---|---|---|---|
| auth-type | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| auth-secret | string | auth-type | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| auth-realm | string | "Protected Content" | auth-type, auth-secret | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| blacklist | IPs/CIDRs or pattern file | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| deny-list | IPs/CIDRs or pattern file | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| check | bool | "true" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| check-http | string | check | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| check-interval | time | check | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| clean-certs | bool | "true" | :large_blue_circle: | :white_circle: | :white_circle: | |
| client-ca | string | ssl-offloading | :large_blue_circle: | :white_circle: | :white_circle: | |
| client-crt-optional | bool | "false" | client-ca | :large_blue_circle: | :white_circle: | :white_circle: |
| client-strict-sni | bool | "false" | client-ca | :large_blue_circle: | :white_circle: | :white_circle: |
| generate-certificates-signer | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| cors-enable | bool | "false" | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| cors-allow-origin | string | "*" | cors-enable | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| cors-allow-methods | string | "*" | cors-enable | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| cors-allow-credentials | bool | "false" | cors-enable | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| cors-allow-headers | string | "*" | cors-enable | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| cors-max-age | time | "5s" | cors-enable | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| global-config-snippet | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| frontend-config-snippet | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| stats-config-snippet | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| backend-config-snippet | string | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| cookie-persistence | string | :large_blue_circle: | :white_circle: | :large_blue_circle: | ||
| cookie-persistence-no-dynamic | string | :large_blue_circle: | :white_circle: | :large_blue_circle: | ||
| dontlognull | bool | "true" | :large_blue_circle: | :white_circle: | :white_circle: | |
| src-ip-header | string | "null" | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| forwarded-for | bool | "true" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| hard-stop-after | time | "30m" | :large_blue_circle: | :white_circle: | :white_circle: | |
| http-connection-mode | string | "http-keep-alive" | :large_blue_circle: | :white_circle: | :white_circle: | |
| http-keep-alive | bool | "true" | :large_blue_circle: | :white_circle: | :white_circle: | |
| http-server-close | bool | "false" | :large_blue_circle: | :white_circle: | :white_circle: | |
| load-balance | string | "roundrobin" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| log-format | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| log-format-tcp | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| logasap | bool | "false" | :large_blue_circle: | :white_circle: | :white_circle: | |
| maxconn | number | :large_blue_circle: | :white_circle: | :white_circle: | ||
| nbthread | number | :large_blue_circle: | :white_circle: | :white_circle: | ||
| path-rewrite | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| pod-maxconn | number | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| proxy-protocol | IPs or CIDRs | :large_blue_circle: | :white_circle: | :white_circle: | ||
| quic-alt-svc-max-age | number | ssl-certificate | :large_blue_circle: | :white_circle: | :white_circle: | |
| rate-limit-period | time | "1s" | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| rate-limit-status-code | string | "403" | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| rate-limit-requests | number | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| rate-limit-size | string | "100k" | rate-limit | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| rate-limit-whitelist | IPs/CIDRs or pattern file | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| request-capture | sample expression | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| request-capture-len | number | 128 | :large_blue_circle: | :large_blue_circle: | :white_circle: | |
| request-set-header | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| request-redirect | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| request-redirect-code | number | 302 | request-redirect | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| response-set-header | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| route-acl | string | :white_circle: | :white_circle: | :large_blue_circle: | ||
| send-proxy-protocol | ["proxy", "proxy-v1", "proxy-v2", "proxy-v2-ssl", "proxy-v2-ssl-cn"] | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| server-ca | string | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| server-crt | string | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| server-proto | ["h2"] | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| server-ssl | bool | "false" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| set-host | string | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| scale-server-slots | number | 42 | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| ssl-certificate | string | :large_blue_circle: | :white_circle: | :white_circle: | ||
| ssl-passthrough | bool | "false" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| ssl-redirect | bool | "false" | https | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| ssl-redirect-code | [301, 302, 303] | "302" | ssl-redirect | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| ssl-redirect-port | number | 8443 | ssl-redirect | :large_blue_circle: | :large_blue_circle: | :white_circle: |
| syslog-server | syslog | "address:127.0.0.1, facility: local0, level: notice" | :large_blue_circle: | :white_circle: | :white_circle: | |
| standalone-backend | bool | :white_circle: | :large_blue_circle: | :large_blue_circle: | ||
| timeout-check | time | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | ||
| timeout-client | time | "50s" | :large_blue_circle: | :white_circle: | :white_circle: | |
| timeout-client-fin | time | :large_blue_circle: | :white_circle: | :white_circle: | ||
| timeout-connect | time | "5s" | :large_blue_circle: | :white_circle: | :white_circle: | |
| timeout-http-request | time | "5s" | :large_blue_circle: | :white_circle: | :white_circle: | |
| timeout-http-keep-alive | time | "1m" | :large_blue_circle: | :white_circle: | :white_circle: | |
| timeout-queue | time | "5s" | :large_blue_circle: | :white_circle: | :white_circle: | |
| timeout-server | time | "50s" | :large_blue_circle: | :large_blue_circle: | :large_blue_circle: | |
| timeout-server-fin | time | :large_blue_circle: | :white_circle: | :white_circle: | ||
| timeout-tunnel | time | "1h" | :large_blue_circle: | :white_circle: | :white_circle: | |
| whitelist | IPs/CIDRs or pattern file | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| allow-list | IPs/CIDRs or pattern file | :large_blue_circle: | :large_blue_circle: | :white_circle: | ||
| tls-alpn | string | "h2,http/1.1" | :large_blue_circle: | :white_circle: | :white_circle: |
:information_source: Annotations have hierarchy:
default<-Configmap<-Ingress<-ServiceService annotations have highest priority. If they are not defined, controller goes one level up until it finds value.
This is useful if we want, for instance, to change default behaviour, but want to keep default for some service. etc.
In general annotations follow the following rules:
- global annotations can only be used in Configmap
- ingress annotations can be used in Ingress and ConfigMap (to configure all ingress resources in use)
- service annotations can be used in Service, Ingress (to configure all services used in Ingress) and ConfigMap (to configure all services in use)
Options
Global Options
Global options are set via ConfigMap (--configmap) annotations. Depending on the option, it can be in Global or Default HAProxy section.
Cors
- Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. - Mozilla Docs
cors-enable
Enables CORS rules for corresponding Ingress traffic.
Available on: configmap ingress
Possible values:
- true
- false
default
Example:
cors-enable: "true"
cors-allow-origin
Sets the Access-Control-Allow-Origin response header to tell browsers which origin is allowed to access the requested resource.
Available on: configmap ingress
:information_source: With "regex" value, it is possible to allow a list of origins. If one of them matches the request Origin header it will be returned to the client.
Possible values:
- Wildcard
*, allow access form any origin. - Regex, regex should match an origin (request Origin header) in the format
<scheme> "://" <hostname> [ ":" <port> ]if the origin is matched then it will be the value ofAccess-Control-Allow-Origin.
Example:
cors-allow-origin: "*"
cors-allow-origin: "https://example.com"
cors-allow-origin: "^https://(.+\.)?(example-1\.com|example-2\.com)(:\d{1,5})?$"
cors-allow-methods
Sets the Access-Control-Allow-Methods response header to tell browsers the HTTP methods allowed when accessing the request resource.
Available on: configmap ingress
Possible values:
- Wildcard
*, allow access for all HTTP methods. - A comma-separated list of HTTP methods
Example:
cors-allow-methods: "*"
cors-allow-methods: "GET"
cors-allow-methods: "GET, POST"
cors-allow-credentials
Sets the Access-Control-Allow-Credentials response header to tell browsers if credentials can be used to access the requested resource.
Available on: configmap ingress
Possible values:
- true
- false
default
Example:
cors-allow-credentials: "true"
cors-allow-headers
Sets the Access-Control-Allow-Headers response header to tell browsers which HTTP headers can be used when accessing the request resource.
Available on: configmap ingress
Possible values:
- Wildcard
*, allow access for all HTTP headers. - A comma-separated list of HTTP headers
Example:
cors-allow-headers: "*"
cors-allow-headers: "X-Custom-Header"
cors-allow-headers: "X-Custom-Header, Upgrade-Insecure-Requests"
cors-max-age
Sets the Access-Control-Allow-Age response header to tell browsers how long the result of a preflight request can be cached.
Available on: configmap ingress
Possible values:
- A time duration
Example:
cors-max-age: "1m"
Access Control
- Access control is disabled by default
- Access control can be set for all traffic (annotation on configmap) or for a set of hosts (annotation on ingress)
blacklist
Deprecated, use deny-list instead.
Blocks given IP addresses and/or IP address ranges.
Available on: configmap ingress
:information_source: The value is treated as a pattern file (see --configmap-patternfiles) if it starts with patterns/. It should consist of a list of IPs or CIDRs, one per line.
Possible values:
- Comma-separated list of IP addresses and/or CIDR ranges
- Path to a pattern file, e.g.
pattern/ips
Example:
blacklist: "192.168.1.0/24, 192.168.2.100"
deny-list
Blocks given IP addresses and/or IP address ranges.
Available on: configmap ingress
:information_source: The value is treated as a pattern file (see --configmap-patternfiles) if it starts with patterns/. It should consist of a list of IPs or CIDRs, one per line.
Possible values:
- Comma-separated list of IP addresses and/or CIDR ranges
- Path to a pattern file, e.g.
pattern/ips
Example:
deny-list: "192.168.1.0/24, 192.168.2.100"
whitelist
Deprecated, use allow-list instead.
Blocks all IP addresses except the whitelisted ones (annotation value).
Available on: configmap ingress
:information_source: The value is treated as a pattern file (see --configmap-patternfiles) if it starts with patterns/. It should consist of a list of IPs or CIDRs, one per line.
Possible values:
- Comma-separated list of IP addresses and/or CIDR ranges
- Path to a pattern file, e.g.
pattern/ips
Example:
whitelist: "192.168.1.0/24, 192.168.2.100"
allow-list
Blocks all IP addresses except the whitelisted ones (annotation value).
Available on: configmap ingress
:information_source: The value is treated as a pattern file (see --configmap-patternfiles) if it starts with patterns/. It should consist of a list of IPs or CIDRs, one per line.
Possible values:
- Comma-separated list of IP addresses and/or CIDR ranges
- Path to a pattern file, e.g.
pattern/ips
Example:
allow-list: "192.168.1.0/24, 192.168.2.100"
Authentication
auth-type
Enables the selected HTTP authentication strategy.
Available on: configmap ingress
Possible values:
- basic-auth
Example:
auth-type: basic-auth
auth-secret: default/haproxy-credentials
auth-secret
Selects the Kubernetes Secret where authentication data can be found.
Available on: configmap ingress
:information_source: Encrypted passwords are evaluated using the crypt(3) function, so depending on the system's capabilities, different algorithms are supported.
:information_source: Unencrypted passwords (used with HAProxy insecure-password ) are not accepted.
Possible values:
- The annotation format is a secret path namespace/secretName. If the namespace is omitted (path is only secretName) then the ingress namespace will be used.
For Basic Authentication, the Secret data should contain user credentials in the form of
username: encrypted and base-64 encoded password. For example:
bob: JDEkYWJjJEJYQnFwYjlCWmNaaFhMZ2JlZS4wcy8=
Create the Kubernetes Secret resource in the following way:
kubectl create secret generic haproxy-credentials \
--from-literal=bob=$(openssl passwd -1 bobPassword) \
--from-literal=alice=$(openssl passwd -1 alicePassword)
# secret/haproxy-credentials created
Example:
auth-type: basic-auth
auth-secret: default/haproxy-credentials
auth-realm
Provides the HTTP Authentication Realm
Available on: configmap ingress
Possible values:
- Realm name
Example:
auth-realm: Admin Area
client-ca
Sets the client certificate authority enabling HAProxy to check clients certificate (TLS authentication), thus enabling client mTLS.
Available on: configmap
:information_source: NB, ssl-offloading should be enabled for TLS authentication to work.
Possible values:
- secret path in "namespace/name" format. Secret should contain the CA certificate in
tls.crtkey. Multiple CAs can be provided by concatenating them in the sametls.crtkey.
Example:
client-ca: exp/client-ca-secret
client-crt-optional
If enabled, certificate verification will be optional which means haproxy will still accept the client connection even if the certificate verification fails. If disabled haproxy will enforce verification of client certificates and only accepts client with valid certificate.
Available on: configmap
:information_source: NB, client-ca should be enabled for certificate verification to work.
Possible values:
- true
- false
default
Example:
client-crt-optional: true
server-ca
Sets the certificate authority for backend servers enabling HAProxy to check backend certificates (TLS authentication) when sending encrypted traffic to the kubernetes applications.
Available on: service configmap ingress
:information_source: When used with server-crt resulting configuration provides mutual TLS authentication (mTLS).
:information_source: The secret must use 'tls.crt' key.
Possible values:
- Secret path following namespace/secretname format.
Example:
server-ca: "ns1/ca"
Backend Checks
check
Enables TCP level health checks on pods and attempts a TCP connection periodically.
Available on: configmap ingress service
Possible values:
- true
default - false
Example:
check: "true"
check-http
Enables HTTP level health checks on pods and sends an HTTP request periodically. The check setting must be true.
Available on: configmap ingress service
Possible values:
- URI to make HTTP requests to, e.g.
/health - URI with method, e.g.
HEAD /health - URI, method and HTTP version, e.g.
HEAD /health HTTP/1.1
Example:
check: "true"
check-http: "/health"
check-interval
Sets the interval between health checks when check is enabled.
Available on: configmap ingress service
Possible values:
- Integer with time unit suffix (1m = 1 minute, 10s = 10 seconds)
Example:
check: "true"
check-interval: "1m"
Backend Scaling
scale-server-slots
Sets the number of server slots to provision in order for HAProxy to scale dynamically with no reload. If this number is greater than the available endpoints/addresses, the remaining slots will be disabled (put on stand-by) and ready to be used. If this number is lower, the remaining endpoints/addresses will be added after scaling the HAProxy backend with a reload.
Available on: configmap ingress service
:information_source: Equivalent old annotations are servers-increment and server-slots
Possible values:
- Integer value indicating the number of backend servers to provision. Defaults to 42.
Example:
scale-server-slots: "75"
Balance Algorithm
load-balance
Sets the load-balancing algorithm to use.
Available on: configmap ingress service
Possible values:
- roundrobin
default - static-rr
- leastconn
- first
- source
- uri [path-only] [whole] [len num] [depth num]
- url_param name [check_post num]
- hdr[(name)] [use_domain_only]
- random[(draws)]
- rdp-cookie[(name)]
Example:
load-balance: "leastconn"
Clean Certs
clean-certs
Switches certificates clean up. By default controller cleans up unused certificates in haproxy cert directory. In the case where certificates may be handled by a side-car container, it is useful not to remove certificates unkown to controller.
Available on: configmap
Possible values:
- true
default - false
Example:
clean-certs: "false"
Config Snippet
- Insert raw HAProxy configuration in specific HAProxy config sections.
- There is no data validation done by Ingress Controller. If input is incorrect, HAProxy will fail to apply new configuration.
- It is possible to use pattern files inside config snippets.
global-config-snippet
Defines a group of configuration directives to insert the HAProxy global section.
Available on: configmap
Possible values:
- One or more valid HAProxy directives
Example:
global-config-snippet: |
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
ssl-default-bind-ciphers TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20
tune.ssl.default-dh-param 2048
tune.bufsize 32768
frontend-config-snippet
Defines a group of configuration directives to insert in the main HTTP/HTTPS frontends.
Available on: configmap
:information_source: Because frontend-config-snippet is inserted in the main http/https frontends it will apply to all traffic. To apply configuration by Ingress, annotations should be privileged.
:information_source: Ingress Controller logic is inserted in the main frontends before any config-snippet configuration so controller configuration will be evaluated first.
:information_source: It is safer to privilege backend-config-snippet when possible to avoid conflicts with controller configuration.
Possible values:
- One or more valid HAProxy directives
Example:
frontend-config-snippet: |
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
unique-id-header X-Unique-ID
stats-config-snippet
Defines a group of configuration directives to insert in the stats frontend.
Available on: configmap
Possible values:
- One or more valid HAProxy directives
Example:
stats-config-snippet: |
stats auth foo:test
backend-config-snippet
Defines a group of configuration directives to add directly to a HAProxy backend section.
Available on: configmap ingress service
Possible values:
- One or more valid HAProxy directives
Example:
backend-config-snippet: |
http-send-name-header x-dst-server
stick-table type string len 32 size 100k expire 30m
stick on req.cook(sessionid)
Cookie Persistence
cookie-persistence
Enables persistent connections (sticky sessions) between a client and a pod by inserting a cookie into the client's browser that is used to remember which backend pod they connected to before. Dynamic cookies are used by default via a dynamic-cookie-key in order to support sticky sessions across multiple Ingress Controller instances/replicas.
Available on: configmap service
:information_source: This will insert the following cookie configuration in the corresponding backend cookie <cookie-name> insert indirect nocache dynamic with <cookie-name> the value of this annotation.
:information_source: This annotation is resolved at the service level, falling back to the configmap default. As the HAProxy backend is shared by every ingress referencing the same service, setting it on an ingress is ignored to avoid a non-deterministic backend configuration. The service value takes precedence over the configmap default.
Possible values:
- A name for the cookie
Example:
cookie-persistence: "mycookie"
Cookie Persistence No Dynamic
cookie-persistence-no-dynamic
Enables persistent connections (sticky sessions) between a client and a pod by inserting a cookie into the client's browser that is used to remember which backend pod they connected to before. Dynamic cookies are not used contrary to cookie-persistence annotation. The cookie will have the server name.
Available on: configmap service
:information_source: This will insert the following cookie configuration in the corresponding backend
cookie <cokkie-name> indirect nocache insert with <cookie-name> the value of this annotation.
The server line will have server <server-name> <server-address> enabled cookie <server-name>
:information_source: This annotation is resolved at the service level, falling back to the configmap default. As the HAProxy backend is shared by every ingress referencing the same service, setting it on an ingress is ignored to avoid a non-deterministic backend configuration. The service value takes precedence over the configmap default.
Possible values:
- A name for the cookie
Example:
cookie-persistence-no-dynamic: "mycookie"
Hard Stop After
hard-stop-after
Defines the maximum time allowed to perform a clean soft-stop.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour)
Example:
hard-stop-after: 30s
Http Options
http-connection-mode
Sets HAProxy connection mode
Available on: configmap
Possible values:
- http-keep-alive
default- Enables HTTP Keep-Alive both from the client to HAProxy and from HAProxy to the backend. - http-server-close - Disables HTTP Keep-Alive between HAProxy and the backend, while allowing it to stay enabled from the client to HAProxy.
- httpclose - HAProxy will close connections with the server and the client as soon as the request and the response are received
Example:
http-connection-mode: "http-server-close"
http-keep-alive
Deprecated, use http-connection-mode instead.
Enables HTTP Keep-Alive both from the client to HAProxy and from HAProxy to the backend.
Available on: configmap
Possible values:
- true
default - false
Example:
http-keep-alive: "true"
http-server-close
Deprecated, use http-connection-mode instead.
Disables HTTP Keep-Alive between HAProxy and the backend, while allowing it to stay enabled from the client to HAProxy.
Available on: configmap
Possible values:
- true
- false
default
Example:
http-server-close: "true"
Https
- SSL offloading/decryption will be automatically enabled if valid SSL certificates are provided.
ssl-passthrough
Passes SSL/TLS traffic through at Layer 4 directly to the backend service without Layer 7 inspection.
Available on: configmap ingress service
:information_source: Traffic is proxied in TCP mode which makes unavailable a number of the controller annotations (requiring HTTP mode).
:information_source: HTTPS frontend is conserved and still listening at port 8444 when previous HTTPS port is moved to SSL Frontend.
Possible values:
- true
- false
default
Example:
ssl-passthrough: "true"
ssl-redirect
Sets whether to redirect traffic from HTTP to HTTPS.
Available on: configmap ingress
:information_source: SSL redirection is enabled by default for any ingress resource defined with a TLS section spec.tls[].secretName.
:information_source: Automatic redirects for ingress resources with TLS enabled, can be disabled by setting annotation to "false" in configmap
Possible values:
- true
- false
default
Example:
ssl-redirect: "false"
ssl-certificate: "default/tls-secret"
ssl-redirect-code
Sets the HTTP status code to use when ssl-redirect is true.
Available on: configmap ingress
Possible values:
- 301
- 302
default - 303
Example:
ssl-redirect: "true"
ssl-certificate: "default/tls-secret"
ssl-redirect-code: "301"
ssl-redirect-port
Sets the HTTPS port to redirect to when HTTP to HTTPS traffic redirection is enabled when ssl-redirect is true.
Available on: configmap ingress
:information_source: When setting the HTTPS port value, keep in mind that this is the HTTPS port as seen by the client, not as set on the Ingress Controller. The reason for this distinction lies in the fact that there will probably be some middleware with its own ports mapping between the client and the Ingress Controller. As a consequence, it must be set with a distinct consideration of how the HTTPS port is set on Ingress Controller with the https-bind-port command line option.
Possible values:
- Integer HTTPS port number
Example:
ssl-redirect: "true"
ssl-redirect-port: "8443"
tls-alpn
Define the TLS ALPN extension advertisement. This will change the alpn advertisement for the https frontend when ssl is enabled.
Available on: configmap
:information_source: To disable HTTP/2 over https, simply use a value like "http/1.1" for this annotation
Possible values:
- Comma-separated list of protocol names to advertise as supported on top of ALPN
Example:
tls-alpn: http/1.1
Log Format
log-format
Sets the log format string to use for HTTP traffic.
Available on: configmap
:information_source: Default log-format is: %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\" Which will look like this: 10.244.0.1:5793 [10/Apr/2020:10:32:50.132] https~ test-echo1-8080/SRV_TFW8V 0/0/1/2/3 200 653 - - ---- 1/1/0/0/0 0/0 "GET test.k8s.local/ HTTP/2.0
Possible values:
- Log format string. More information in HAProxy documentation
Example:
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\""
log-format-tcp
Sets the log format string to use for TCP traffic.
Available on: configmap
:information_source: Default is option tcplog
:information_source: Applies only to TCP configmap defined by command line option --configmap-tcp-services
Possible values:
- Log format string. More information in HAProxy documentation
Example:
log-format-tcp: "%{+Q}o %t %s"
Logging
dontlognull
Do not log connections that sends no data, which can happen with monitoring systems.
Available on: configmap
Possible values:
- true
default - false
Example:
dontlognull: "true"
logasap
Logs request and response data as soon as the server returns a complete set of HTTP response headers, instead of waiting for the response to finish sending all data.
Available on: configmap
Possible values:
- true
- false
default
Example:
logasap: "true"
syslog-server
Sets one or more Syslog servers where logs should be forwarded. Each server is placed onto its own line. A line supports the following arguments, which are separated by commas
Available on: configmap
:information_source: More information can be found in the HAProxy documentation
Possible values:
- address - Required - IP address where the syslog server is listening.
- facility - Required - One of the 24 syslog facilities (kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, auth2, ftp, ntp, audit, alert, con2, local0, local1, local2, local3, local4, local5, local6, local7); In general, you will want to use one of the localX values, since the others are registered for specific types of applications.
- format - Syslog format, one of the following - rfc3164, rfc5424, short, raw. to rfc3164. HAProxy default is rfc3164
- length - Maximum syslog line length. HAProxy default is 1024.
- level - Maximum verbosity level to filter outgoing messages; Only messages with a severity at least as important as this level will be sent; Use one of the following (emerg, alert, crit, err, warning, notice, info, debug); Traffic logs are emitted at "info" or higher severity. Haproxy default is to send all messages.
- minlevel - Minimum verbosity level. Logs emitted with a more severe level than this one will be capped to this level. HAProxy default does not set a minlevel.
- port - Port number where the syslog server is listening. HAProxy default is 514.
Example:
# a single entry
syslog-server: "address:192.158.1.1, port:514, facility:local0"
# log to stdout
syslog-server: "address:stdout, format: raw, facility:daemon"
# multiple entries
syslog-server: |
address:127.0.0.1, port:514, facility:local0
address:192.168.1.1, port:514, facility:local1
Maximum Concurrent Backend Connections
pod-maxconn
Sets the maximum number of concurrent connections (maxconn) on a backend server (application pod).
Available on: service ingress configmap
:information_source: NB, If multiple HAProxy instances are running, the maxconn will be pod-maxconn number devided by the number of haproxy instances.
Possible values:
- An integer setting the maximum number of concurrent backend connections
Example:
pod-maxconn: "30"
Maximum Concurrent Connections
maxconn
Sets the maximum number of concurrent connections that HAProxy will accept.
Available on: configmap
Possible values:
- An integer setting the allowed number of concurrent connections
Example:
maxconn: "2000"
Number Of Threads
nbthread
Sets the number of worker threads that the HAProxy process will start. If not set, HAProxy will create a thread for each available processor.
Available on: configmap
Possible values:
- An integer setting the number of worker threads
Example:
nbthread: "8"
Path Rewrite
path-rewrite
Replaces the entire URL path with the given value.
Available on: configmap ingress
Possible values:
- A single path, such as "/", to turn any path into "/"
- Two parameters. A regular expression to match and a path to replace it with.
- Multiline annotation is split into more rewrite rules.
Example (configmap):
path-rewrite: "/" # replace all paths with /
path-rewrite: (.*) /foo\1 # add the prefix /foo... "/bar?q=1" into "/foo/bar?q=1"
path-rewrite: ([^?]*)(\?(.*))? \1/foo\2 # add the suffix /foo ... "/bar?q=1" into "/bar/foo?q=1"
path-rewrite: /foo/(.*) /\1 # strip /foo ... "/foo/bar?q=1" into "/bar?q=1"
# strip /foo ... "/foo/bar?q=1" into "/bar?q=1" and replace "/bar/*" with "/baz/*"
# with multiline (using `|`) annotation
path-rewrite: |
/foo/(.*) /\1
/bar/(.*) /baz/\1
Example (ingress):
haproxy.org/path-rewrite: "/" # replace all paths with /
haproxy.org/path-rewrite: (.*) /foo\1 # add the prefix /foo... "/bar?q=1" into "/foo/bar?q=1"
haproxy.org/path-rewrite: ([^?]*)(\?(.*))? \1/foo\2 # add the suffix /foo ... "/bar?q=1" into "/bar/foo?q=1"
haproxy.org/path-rewrite: /foo/(.*) /\1 # strip /foo ... "/foo/bar?q=1" into "/bar?q=1"
# strip /foo ... "/foo/bar?q=1" into "/bar?q=1" and replace "/bar/*" with "/baz/*"
# with multiline (using `|`) annotation
haproxy.org/path-rewrite: |
/foo/(.*) /\1
/bar/(.*) /baz/\1
Proxy Protocol
proxy-protocol
Enables Proxy Protocol on client side for a comma-delimited list of IP addresses and/or CIDR ranges.
The 0.0.0.0/0 CIDR will enable Proxy Protocol for all incoming traffic.
Available on: configmap
:information_source: Connection will fail with 400 Bad Request if source IP is in annotation list but no Proxy Protocol data is sent.
Possible values:
- A list of IP addresses and/or CIDR ranges
Example:
proxy-protocol: "192.168.1.0/24, 192.168.2.100"
Quic Alt Svc Max Age
quic-alt-svc-max-age
Sets the max age in seconds for the alt-svc header as defined by the standard.
Available on: configmap
:information_source: Too high a number can lead to issues. The clients could fail to connect because the services is no more available.
Possible values:
- number of seconds for cache retention.
Example:
quic-alt-svc-max-age: "900"
Rate Limit
rate-limit-period
Sets the period of time over which requests are tracked for a given source IP address.
Available on: configmap ingress
Possible values:
- Integer with unit of time (1s = 1 second, 1m = 1 minute); Defaults to 1 second
Example:
rate-limit-period: "1m"
rate-limit-status-code
Sets the status code to return when rate limiting has been triggered.
Available on: configmap ingress
Possible values:
- HTTP status codes; Defaults to 403.
Example:
rate-limit-status-code: "429"
rate-limit-requests
Sets the maximum number of requests that will be accepted from a source IP address during the rate-limit-period.
Available on: configmap ingress
:information_source: If this number is exceeded, HAProxy will deny requests with 403 status code.
:information_source: To track the http requests rate, a stick-table named "Ratelimit-rate-limit-period is set to 2s, the name of the table will be Ratelimit-2000.
Possible values:
- An integer representing the maximum number of requests to accept
Example:
rate-limit-requests: 15
rate-limit-size
Sets how many source IP addresses to track, after which older entries are replaced by new entries.
Available on: configmap ingress
:information_source: If this number is exceeded, older entries will be dropped as new ones come
Possible values:
- An integer defining how many IP addresses to track for rate limiting; Defaults to 100,000
Example:
rate-limit-size: 1000000
rate-limit-whitelist
Defines a list of IP addresses or CIDR ranges that should be excluded from rate limiting. IPs in the whitelist will never be rate limited.
Available on: configmap ingress
:information_source: When both rate limiting and a whitelist are configured, only clients NOT in the whitelist will be subject to rate limiting.
Possible values:
- Comma-separated list of IP addresses and/or CIDR ranges (e.g.,
10.0.0.0/8, 192.168.1.100) - Reference to a pattern file using
patterns/prefix (e.g.,patterns/whitelist)
Example:
rate-limit-period: "10s"
rate-limit-requests: 1200
rate-limit-status-code: "429"
rate-limit-whitelist: "10.0.0.0/8, 192.168.1.100"
Request Capture
request-capture
When you include %hr in the log-format string, which is included in the default log format, it captures custom information in the logs, which you define with this field. For example, you can capture specific cookie values or HTTP header values.
Available on: configmap ingress
:information_source: Captures samples of the request using sample expression and log them in HAProxy traffic logs.
:information_source: Important: When capturing headers that may contain commas (like User-Agent), use req.fhdr(header-name) instead of hdr(header-name). The hdr() function splits values on commas, which can result in truncated or malformed log entries. The req.fhdr() function returns the full header value without splitting on commas.
Possible values:
- A header value, e.g.
hdr(header-name)orreq.fhdr(header-name)for headers with commas - A cookie value, e.g.
cookie(cookie-name) - Multiple expressions by using a multiline YAML string
Example (configmap):
# capture a single value
request-capture: cookie(my-cookie)
# capture multiple values
request-capture: |
cookie(my-cookie)
hdr(Host)
req.fhdr(user-agent)
Example (ingress):
# capture a single value
haproxy.org/request-capture: cookie(my-cookie)
# capture multiple values
haproxy.org/request-capture: |
cookie(my-cookie)
hdr(Host)
req.fhdr(user-agent)
request-capture-len
Sets how many characters to allocate for fields captured by request-capture.
Available on: configmap ingress
Possible values:
- An integer representing the number of characters for captured fields; Defaults to 128
Example:
request-capture: cookie(my-cookie)
request-capture-len: 350
Request Redirect
request-redirect
Enables HTTP request redirection based on host and port substitution in original request.
Available on: configmap ingress
:information_source: HTTP redirection code is settable with request-redirect-code annotation.
:information_source: Port alone is not allowed.
Possible values:
- host
- host:port
Example:
request-redirect: example.com
request-redirect: example.com:8888
request-redirect-code
Defines the HTTP redirection code used in redirection set with request-redirect.
Available on: configmap ingress
Possible values:
- Integer value.
Example:
request-redirect-code: "303"
Request Set Header
request-set-header
Sets an HTTP header in the request before it is passed to the backend service.
Available on: configmap ingress
:information_source: This sets header before HAProxy does any service/backend dispatch. So in the case you want to change the Host header this will impact HAProxy decision on which service/backend to use (based on matching Host against ingress rules). In order to set the Host header after service selection, use set-host annotation.
Possible values:
- The name of the field, following by its value, e.g. Ingress-ID abcd123
- Multiple headers can be set using a multiline YAML string
Example (configmap):
# single header
request-set-header: Ingress-ID abcd123
# multiple headers
request-set-header: |
Ingress-ID abcd123
Another-Header 12345
Example (ingress):
# single header
haproxy.org/request-set-header: Ingress-ID abcd123
# multiple headers
haproxy.org/request-set-header: |
Ingress-ID abcd123
Another-Header 12345
Response Set Header
response-set-header
Sets an HTTP header in the response before it is passed to the client.
Available on: configmap ingress
Possible values:
- The name of the field, following by its value, e.g. Cache-Control "no-store,no-cache,private"
- Multiple headers can be set using a multiline YAML string
Example (configmap):
# single header
response-set-header: Cache-Control "no-store,no-cache,private"
# multiple headers
response-set-header: |
Cache-Control "no-store,no-cache,private"
Strict-Transport-Security "max-age=31536000"
Example (ingress):
# single header
haproxy.org/response-set-header: Cache-Control "no-store,no-cache,private"
# multiple headers
haproxy.org/response-set-header: |
Cache-Control "no-store,no-cache,private"
Strict-Transport-Security "max-age=31536000"
Route Acl
route-acl
Insert a custom route (use_backend rule) to route ingress traffic to the annotated service based on the provided ACL.
Available on: service
:information_source: In order for the service to be handled by the Ingress Controller, it is still mandatory to put it in an ingress rule. Using only route-acl won't be enough.
:information_source: Note that this annotation is not compatible with an Ingress having multiple paths that will match a request. Without this annotation, the precedence is given first to the longest matching path. But with the annotation, the first use_backend rule in the config that matches the request will be used.
Possible values:
- A string describing an in-line HAProxy ACL.
Example:
haproxy.org/route-acl: cookie(staging) -m found
Send Proxy Protocol
send-proxy-protocol
Uses the PROXY Protocol when connecting to backend servers.
Available on: service ingress configmap
Possible values:
- proxy - Uses PROXY v1
- proxy-v1 - Uses PROXY v1
- proxy-v2 - Uses PROXY v2
- proxy-v2-ssl Uses PROXY v2 with SSL information extension
- proxy-v2-ssl-cn Uses PROXY v2 with SSL and Common Name information extension
Example:
send-proxy-protocol: proxy-v2
Server Crt
server-crt
Specifies the path of a secret containing a certificate that HAProxy can provide during TLS communication with the backend servers.
Available on: service configmap ingress
:information_source: The secret must use 'tls.key' and 'tls.crt' keys.
:information_source: When used with server-ca resulting configuration provides mutual TLS authentication (mTLS).
Possible values:
- Secret path following namespace/secretname format.
Example:
server-crt: "ns1/client"
Server Proto
server-proto
HTTP/1.1 is the default protocol for backend servers communication. Currently, the server-proto annotation supports only "h2" as a value (supporting fcgi is also planned) which transmits HTTP/2 messages in the clear to the backend servers.
However, when SSL is enabled on the backend, server-proto is ignored and both HTTP/1.1 and HTTP/2 are advertised via ALPN and transmitted as encrypted messages.
Available on: service configmap ingress
Possible values:
- h2
Example:
server-proto: "h2"
Server Ssl
server-ssl
Enables SSL to pods.
Available on: configmap ingress service
:information_source: Enable HTTP/2 support for backend severs.
Possible values:
- true
- false
default
Example:
server-ssl: "true"
Set Host
set-host
Sets the Host header to send to backend services.
Available on: configmap ingress
Possible values:
- The value of the Host header
Example:
set-host: "example.local"
Src Ip Header
src-ip-header
Set the source IP from a header rather than the L3 connection.
Available on: configmap ingress
Possible values:
- any header name
Example:
src-ip-header: "True-Client-IP"
Ssl Offloading
- Controller will look into kubernetes secrets for valid SSL certificates to configure in HAProxy.
- A default certificate can be provided via controller argument
--default-ssl-certificate=<namespace>/<secret> or ConfigMap annotation ssl-certificate. - Certificates can be defined in Ingress object:
spec.tls[].secretName
client-strict-sni
If enabled, HAProxy will only accept TLS client connections where the provided SNI matchs an existing certificate. If disabled HAProxy will service the default certificate when the provided SNI does not match.
Available on: configmap
Possible values:
- true
- false
default
Example:
client-strict-sni: true
generate-certificates-signer
Specifies the Kubernetes kubernetes.io/tls type secret containing the CA certificate file used to sign automatically generated certificates. When this annotation is set, HAProxy's generate-certificates feature is automatically enabled on the HTTPS frontend bind line. This allows HAProxy to automatically generate certificates for incoming TLS connections using the provided CA for signing. The secret should contain the CA certificate and key in PEM format.
Available on: configmap
:information_source: The secret format should be namespace/secret-name or just secret-name.
:information_source: When this annotation is configured, the generate-certificates option is automatically added to the bind line in the HTTPS frontend when SSL offload is enabled.
:information_source: HAProxy will use this CA to sign certificates generated for incoming TLS connections.
Possible values:
- Name of Kubernetes secret in format namespace/secret-name
Example:
generate-certificates-signer: "default/ca-signing-cert"
ssl-certificate
Sets the name of the Kubernetes secret that contains both the TLS key and certificate.
Available on: configmap
:information_source: this replaces default certificate
:information_source: this is used as the certificate for quic binding
Possible values:
- Name of Kubernetes secret
Example:
ssl-certificate: "default/tls-secret"
- A secret can be of
tlstype (most common) created via :kubectl create secret tls my-secret --key=<key-path> --cert=<cert-path> - A secret can be of
generictype if we want to have a certificate in multiple formats:
The only possible keys are the following,kubectl create secret generic my-secret --from-file=rsa.key=<rsa-key-path> --from-file=rsa.crt=<rsa-cert-path> \ --from-file=ecdsa.key=<ecdsa-key-path> --from-file=ecdsa.crt=<ecdsa-cert-path>- rsa.key
- rsa.crt
- ecdsa.key
- ecdsa.crt
- dsa.key
- dsa.crt
Standalone Backend
standalone-backend
Creates a specific and separated backend for this ingress in case multiple ingresses refer to the same service.
Available on: service ingress
:information_source: With this annotation you can create your own separate backend whose configuration won't be impacted by others ingresses. As a reminder, all ingresses refering to the same service have their configuration inserted in the same backend which can cause some conflict.
Possible values:
- true
- false
Example:
haproxy.org/standalone-backend: "true"
Timeouts
timeout-check
Sets an additional check timeout, but only after a connection has been already established.
Available on: configmap ingress service
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour)
Example:
timeout-check: 5s
timeout-client
Set the maximum inactivity time on the client side.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 50s
Example:
timeout-client: 5s
timeout-client-fin
Sets the inactivity timeout on the client side for half-closed connections.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour)
Example:
timeout-client-fin: 5s
timeout-connect
Sets the maximum time to wait for a connection attempt to a server to succeed.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 5s
Example:
timeout-connect: 5s
timeout-http-request
Sets the maximum allowed time to wait for a complete HTTP request.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 5s
Example:
timeout-http-request: 5s
timeout-http-keep-alive
Sets the maximum allowed time to wait for a new HTTP request to appear.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 1m
Example:
timeout-http-keep-alive: 5s
timeout-queue
Sets the maximum time to wait in the queue for a connection slot to be free.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 5s
Example:
timeout-queue: 5s
timeout-server
Sets the maximum inactivity time on the server side. configmap available since version 1.4
Available on: configmap ingress service
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 50s
Example:
timeout-server: 5s
timeout-server-fin
Sets the inactivity timeout on the server side for half-closed connections.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour)
Example:
timeout-server-fin: 5s
timeout-tunnel
Set the maximum inactivity time on the client and server side for tunnels.
Available on: configmap
Possible values:
- An integer with a unit of time (1 second = 1s, 1 minute = 1m, 1h = 1 hour); Defaults to 1h
Example:
timeout-tunnel: 30m
X Forwarded For
forwarded-for
Adds the X-Forwarded-For HTTP header to requests to capture and relay the client's source IP address to backend pods.
Available on: configmap ingress service
Possible values:
- true
default - false
Example:
forwarded-for: "true"
Secrets
tls-secret
- define through pod arguments
--default-ssl-certificate=<namespace>/<secret>
- Annotation
ssl-certificatein config map- <namespace>/<secret>
- this replaces default certificate
- certificate can be defined in Ingress object:
spec.tls[].secretName - single certificate secret can contain two items:
- tls.key
- tls.crt
- certificate secret with
rsaandecdsacertificates:- :information_source: only one certificate is also acceptable setup
- rsa.key
- rsa.crt
- ecdsa.key
- ecdsa.crt
Data types
Port
- value between <0, 65535]
Sample expression
- Sample expressions/fetches are used to retrieve data from request/response buffer.
- Example:
- headers:
hdr(header-name) - cookies:
cookie(cookie-name) - Name of the cipher used to offload SSL:
ssl_fc_cipher
- headers:
- Sample expressions are covered in depth in HAProxy documentation, however many are out of the ingress controller's scope.
Time
- number + type
- in milliseconds, "s" suffix denotes seconds
- example: "1s"