From 72fea25d271b53601cbded03087adddc76950cdd Mon Sep 17 00:00:00 2001 From: Joao Morais Date: Sun, 17 Dec 2017 16:34:15 -0200 Subject: [PATCH] New reload strategy - reusesocket --- README.md | 1 + pkg/controller/controller.go | 4 ++-- rootfs/etc/haproxy/template/haproxy.tmpl | 2 +- rootfs/haproxy-reload.sh | 14 ++++++++++++++ rootfs/start.sh | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df01970eb..f512b3a1d 100644 --- a/README.md +++ b/README.md @@ -487,6 +487,7 @@ The `--reload-strategy` command-line argument is used to select which reload str HAProxy should use. The following options are available: * `native`: Uses native HAProxy reload option `-sf`. This is the default option. +* `reusesocket`: (starting on v0.6) Uses HAProxy `-x` command-line option to pass the listening sockets between old and new HAProxy process, allowing hitless reloads. * `multibinder`: Uses GitHub's [multibinder](https://github.com/github/multibinder). This [link](https://githubengineering.com/glb-part-2-haproxy-zero-downtime-zero-delay-reloads-with-multibinder/) describes how it works. diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 14035d530..9de6ccb83 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -102,7 +102,7 @@ func (haproxy *HAProxyController) UpdateIngressStatus(*extensions.Ingress) []api // command line arguments func (haproxy *HAProxyController) ConfigureFlags(flags *pflag.FlagSet) { haproxy.reloadStrategy = flags.String("reload-strategy", "native", - `Name of the reload strategy. Options are: native (default) or multibinder`) + `Name of the reload strategy. Options are: native (default), reusesocket or multibinder`) ingressClass := flags.Lookup("ingress-class") if ingressClass != nil { ingressClass.Value.Set("haproxy") @@ -112,7 +112,7 @@ func (haproxy *HAProxyController) ConfigureFlags(flags *pflag.FlagSet) { // OverrideFlags allows controller to override command line parameter flags func (haproxy *HAProxyController) OverrideFlags(flags *pflag.FlagSet) { - if *haproxy.reloadStrategy == "native" { + if *haproxy.reloadStrategy == "native" || *haproxy.reloadStrategy == "reusesocket" { haproxy.configFile = "/etc/haproxy/haproxy.cfg" haproxy.template = newTemplate("haproxy.tmpl", "/etc/haproxy/template/haproxy.tmpl") } else if *haproxy.reloadStrategy == "multibinder" { diff --git a/rootfs/etc/haproxy/template/haproxy.tmpl b/rootfs/etc/haproxy/template/haproxy.tmpl index abee2de26..7b6824851 100644 --- a/rootfs/etc/haproxy/template/haproxy.tmpl +++ b/rootfs/etc/haproxy/template/haproxy.tmpl @@ -2,7 +2,7 @@ {{- $cfg := .Cfg -}} global daemon - stats socket {{ $cfg.StatsSocket }} level admin + stats socket {{ $cfg.StatsSocket }} level admin expose-fd listeners {{- if $cfg.LoadServerState }} server-state-file state-global server-state-base /var/lib/haproxy/ diff --git a/rootfs/haproxy-reload.sh b/rootfs/haproxy-reload.sh index e2a389b72..f15e2730a 100755 --- a/rootfs/haproxy-reload.sh +++ b/rootfs/haproxy-reload.sh @@ -20,6 +20,9 @@ # native <.cfg> # Uses native HAProxy soft restart. Running it for the first time starts # HAProxy, each subsequent invocation will perform a soft-reload. +# reusesocket <.cfg> +# Pass the listening sockets to the new HAProxy process instead of +# rebinding them, allowing hitless reloads. # multibinder <.cfg.erb> # Used on multibinder deployment. Send USR2 to the # multibinder-haproxy-wrapper process. @@ -30,6 +33,7 @@ # -D run as daemon # -sf soft reload, wait for pids to finish handling requests # send pids a resume signal if reload of new config fails +# -x get the listening sockets from the old HAProxy process set -e @@ -47,6 +51,16 @@ case "$1" in HAPROXY_PID=/var/run/haproxy.pid haproxy -f "$CONFIG" -p "$HAPROXY_PID" -D -sf $(cat "$HAPROXY_PID" 2>/dev/null || :) ;; + reusesocket) + CONFIG="$2" + HAPROXY_PID=/var/run/haproxy.pid + OLD_PID=$(cat "$HAPROXY_PID" 2>/dev/null || :) + if [ -S "$HAPROXY_SOCKET" ]; then + haproxy -f "$CONFIG" -p "$HAPROXY_PID" -sf $OLD_PID -x "$HAPROXY_SOCKET" + else + haproxy -f "$CONFIG" -p "$HAPROXY_PID" -sf $OLD_PID + fi + ;; multibinder) HAPROXY=/usr/local/sbin/haproxy CONFIG="$2" diff --git a/rootfs/start.sh b/rootfs/start.sh index 33bad0cb0..a8431ab57 100755 --- a/rootfs/start.sh +++ b/rootfs/start.sh @@ -26,7 +26,7 @@ init() { ) reloadStrategy="${reloadStrategy:-native}" case "$reloadStrategy" in - native) + native|reusesocket) ;; multibinder) HAPROXY=/usr/local/sbin/haproxy