HAProxy sysext
This sysext ships HAProxy, a reliable high-performance TCP/HTTP load balancer.
The sysext is built from upstream source inside an ephemeral Alpine container as a statically linked musl binary with OpenSSL (incl. QUIC compat for HTTP/3), PCRE2 (JIT), Lua 5.4, zlib, threading, Linux capabilities, transparent proxy, network namespaces, TCP Fast Open and the Prometheus exporter enabled. The binary has no runtime library dependencies on the host and lands at /usr/bin/haproxy. Alongside it the sysext ships:
haproxy.servicebased on the upstreamadmin/systemd/haproxy.service.in, with sandboxing/ProtectSystemoptions enabledsysusers.dentry to create thehaproxysystem user the service runs astmpfiles.dentry that seeds/etc/haproxy/haproxy.cfgfrom a minimal default on first boot, exposing the stats page at127.0.0.1:8404
Custom configuration
The sysext ships a default config at /usr/share/haproxy/haproxy.cfg. The tmpfiles.d rule uses C /etc/haproxy/haproxy.cfg semantics, so it copies the default in only when /etc/haproxy/haproxy.cfg does not already exist. Any file placed there by Ignition, Terraform, config-management, or by hand wins — the default is not applied on top of it and later sysext updates will not overwrite it.
Two common patterns:
- Provisioning-time config. Write
/etc/haproxy/haproxy.cfgfrom the Ignition/butane snippet (as in the Usage example below). The seed default is skipped and the service starts on your config on first boot. - Runtime-managed config. Leave
/etc/haproxy/haproxy.cfgoff the snippet, let the default seed in, then have your config-management tool (or a dataplane API) rewrite it andsystemctl reload haproxy.service. The unit’sExecReloadrunshaproxy -cfirst, so a syntactically bad rewrite will not take effect.
The unit also honours EnvironmentFile=-/etc/default/haproxy and EnvironmentFile=-/etc/sysconfig/haproxy (both optional). Override CONFIG there to point -f at a different file, or EXTRAOPTS to add flags without editing the unit.
Usage
Download and merge the sysext at provisioning time using the below butane snippet.
The snippet includes automated updates via systemd-sysupdate. Sysupdate will stage updates and request a reboot by creating a flag file at /run/reboot-required. You can deactivate updates by changing enabled: true to enabled: false in systemd-sysupdate.timer.
Note that the snippet is for the x86-64 version of HAProxy 3.2.5.
Check out the metadata release at https://github.com/flatcar/sysext-bakery/releases/tag/haproxy for a list of all versions available in the bakery.
variant: flatcar
version: 1.0.0
storage:
files:
- path: /opt/extensions/haproxy/haproxy-3.2.5-x86-64.raw
mode: 0644
contents:
source: https://extensions.flatcar.org/extensions/haproxy-3.2.5-x86-64.raw
- path: /etc/sysupdate.haproxy.d/haproxy.conf
contents:
source: https://extensions.flatcar.org/extensions/haproxy.conf
- path: /etc/sysupdate.d/noop.conf
contents:
source: https://extensions.flatcar.org/extensions/noop.conf
- path: /etc/haproxy/haproxy.cfg
mode: 0644
contents:
inline: |
global
log stdout format raw local0
user haproxy
group haproxy
maxconn 4096
defaults
log global
mode http
option httplog
timeout connect 5s
timeout client 50s
timeout server 50s
frontend http-in
bind *:80
default_backend servers
backend servers
server srv1 127.0.0.1:8080 check
links:
- target: /opt/extensions/haproxy/haproxy-3.2.5-x86-64.raw
path: /etc/extensions/haproxy.raw
hard: false
systemd:
units:
- name: haproxy.service
enabled: true
- name: systemd-sysupdate.timer
enabled: true
- name: systemd-sysupdate.service
dropins:
- name: haproxy.conf
contents: |
[Service]
ExecStartPre=/usr/bin/sh -c "readlink --canonicalize /etc/extensions/haproxy.raw > /run/haproxy-sysext"
ExecStartPre=/usr/lib/systemd/systemd-sysupdate -C haproxy update
ExecStartPost=/usr/bin/sh -c "readlink --canonicalize /etc/extensions/haproxy.raw > /run/haproxy-sysext-new"
ExecStartPost=/usr/bin/sh -c "if ! cmp --silent /run/haproxy-sysext /run/haproxy-sysext-new; then touch /run/reboot-required; fi"