diff --git a/CHANGELOG.md b/CHANGELOG.md index a0dabf1..94a7ecb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2022-08-25 +- Add `MAXCONN` environment variable to limit max connection among backends (default to `0` - unlimited) [sauzher] +- Add `STATS_REFRESH` environment variable to enable auto refresh. (default to `0` - no refresh) [sauzher] +- Add optional weight parameter for remote backends `host:port:weight` (default to `1` - all same weight) [sauzher] + ## 2021-06-14 (1.8-1.7) - Upgrade HAProxy to 1.8.30 diff --git a/haproxy/Readme.md b/haproxy/Readme.md index 8cdef42..a062128 100644 --- a/haproxy/Readme.md +++ b/haproxy/Readme.md @@ -74,6 +74,9 @@ that served the page changes, as HAProxy switches between them. The stats page can be accessed at http://localhost:1936 where you have to log in using the `STATS_AUTH` authentication details (default `admin:admin`). +You may want to set `STATS_REFRESH` option to let the statistics page auto update +i.e `STATS_REFRESH="5s"` to update every five seconds (default `0s`: no refresh) + Note that it may take **up to one minute** until backends are plugged-in due to the minimum possible `DNS_TTL`. @@ -81,12 +84,14 @@ minimum possible `DNS_TTL`. ### Run with backends specified as environment variable $ docker run --env BACKENDS="192.168.1.5:80 192.168.1.6:80" eeacms/haproxy +or + $ docker run --env BACKENDS="192.168.1.5:80:4 192.168.1.6:80:1" eeacms/haproxy Using the `BACKENDS` variable is a way to quick-start the container. -The servers are written as `server_ip:server_listening_port`, +The servers are written as `server_ip:server_listening_port:weight`, separated by spaces (and enclosed in quotes, to avoid issues). The contents of the variable are evaluated in a python script that writes -the HAProxy configuration file automatically. +the HAProxy configuration file automatically. `weight` is optional and defaulted to `1` If there are multiple DNS records for one or more of your `BACKENDS` (e.g. when deployed using rancher-compose), you can use `DNS_ENABLED` environment variable. This way, haproxy will load-balance @@ -128,6 +133,7 @@ either when running the container or in a `docker-compose.yml` file. * `STATS_PORT` The port to bind statistics to - default `1936` * `STATS_AUTH` The authentication details (written as `user:password` for the statistics page - default `admin:admin` + * `STATS_REFRESH` Refresh timing for the statistics page - default `0s` (no refresh) * `FRONTEND_NAME` The label of the frontend - default `http-frontend` * `FRONTEND_PORT` The port to bind the frontend to - default `5000` * `FRONTEND_MODE` Frontend mode - default `http` or `BACKENDS_MODE` if declared @@ -136,7 +142,7 @@ either when running the container or in a `docker-compose.yml` file. * `COOKIES_NAME` Will be added on cookie declaration - default `SRV_ID` * `COOKIES_PARAMS` Will be added on cookie declaration - example `indirect nocache maxidle 30m maxlife 8h` or `maxlife 24h` - documentation https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-cookie * `BACKEND_NAME` The label of the backend - default `http-backend` - * `BACKENDS` The list of `server_ip:server_listening_port` to be load-balanced by HAProxy, separated by space - by default it is not set + * `BACKENDS` The list of `server_ip:server_listening_port:weight` to be load-balanced by HAProxy, separated by space - by default it is not set - by default weight is 1 * `BACKENDS_PORT` Port to use when auto-discovering backends, or when `BACKENDS` are specified without port - by default `80` * `BACKENDS_MODE` Backends mode - default `http` or `FRONTEND_MODE` if declared * `BALANCE` The algorithm used for load-balancing - default `roundrobin` @@ -151,12 +157,12 @@ either when running the container or in a `docker-compose.yml` file. * `HTTPCHK` The HTTP method and uri used to check on the servers health - default `HEAD /` * `HTTPCHK_HOST` Host Header override on http Health Check - default `localhost` * `INTER` parameter sets the interval between two consecutive health checks. If not specified, the default value is `2s` + * `MAXCONN` parameter sets the maximum number of connection that each backend will accept and, by default, is set to `0` (no limit) * `FAST_INTER` parameter sets the interval between two consecutive health checks when the server is any of the transition state (read above): UP - transitionally DOWN or DOWN - transitionally UP. If not set, then `INTER` is used. * `DOWN_INTER` parameter sets the interval between two consecutive health checks when the server is in the DOWN state. If not set, then `INTER` is used. * `RISE` number of consecutive valid health checks before considering the server as UP. Default value is `2` * `FALL` number of consecutive invalid health checks before considering the server as DOWN. Default value is `3` - ## Logging By default the logs from haproxy are present in the docker log, by using the rsyslog inside the container (UDP port 514). No access logs are present by default, but this can be changed by setting the log level. diff --git a/haproxy/docker-entrypoint.sh b/haproxy/docker-entrypoint.sh index 16b957b..2192dad 100755 --- a/haproxy/docker-entrypoint.sh +++ b/haproxy/docker-entrypoint.sh @@ -51,9 +51,11 @@ if ! test -e /usr/local/etc/haproxy/haproxy.cfg; then if [ -n "$LOG_LEVEL" ]; then echo "export LOG_LEVEL=\"$LOG_LEVEL\"" >> /etc/environment; fi if [ -n "$PROXY_PROTOCOL_ENABLED" ]; then echo "export PROXY_PROTOCOL_ENABLED=\"$PROXY_PROTOCOL_ENABLED\"" >> /etc/environment; fi if [ -n "$RISE" ]; then echo "export RISE=\"$RISE\"" >> /etc/environment; fi + if [ -n "$MAXCONN" ]; then echo "export MAXCONN=\"$MAXCONN\"" >> /etc/environment; fi if [ -n "$SERVICE_NAMES" ]; then echo "export SERVICE_NAMES=\"$SERVICE_NAMES\"" >> /etc/environment; fi if [ -n "$STATS_AUTH" ]; then echo "export STATS_AUTH=\"$STATS_AUTH\"" >> /etc/environment; fi if [ -n "$STATS_PORT" ]; then echo "export STATS_PORT=\"$STATS_PORT\"" >> /etc/environment; fi + if [ -n "$STATS_REFRESH" ]; then echo "export STATS_REFRESH=\"$STATS_REFRESH\"" >> /etc/environment; fi if [ -n "$TIMEOUT_CLIENT" ]; then echo "export TIMEOUT_CLIENT=\"$TIMEOUT_CLIENT\"" >> /etc/environment; fi if [ -n "$TIMEOUT_CONNECT" ]; then echo "export TIMEOUT_CONNECT=\"$TIMEOUT_CONNECT\"" >> /etc/environment; fi if [ -n "$TIMEOUT_SERVER" ]; then echo "export TIMEOUT_SERVER=\"$TIMEOUT_SERVER\"" >> /etc/environment; fi diff --git a/haproxy/src/configure.py b/haproxy/src/configure.py index aec0c80..5ca4fdd 100644 --- a/haproxy/src/configure.py +++ b/haproxy/src/configure.py @@ -20,6 +20,7 @@ PROXY_PROTOCOL_ENABLED = (os.environ.get('PROXY_PROTOCOL_ENABLED', 'false').lower() == "true") STATS_PORT = os.environ.get('STATS_PORT', '1936') STATS_AUTH = os.environ.get('STATS_AUTH', 'admin:admin') +STATS_REFRESH = os.environ.get('STATS_REFRESH', '0s') BACKENDS = os.environ.get('BACKENDS', '').split(' ') BACKENDS_PORT = os.environ.get('BACKENDS_PORT', '80') BACKENDS_MODE = os.environ.get('BACKENDS_MODE', FRONTEND_MODE) @@ -35,6 +36,7 @@ DOWN_INTER = os.environ.get('DOWN_INTER', INTER) RISE = os.environ.get('RISE', '2') FALL = os.environ.get('FALL', '3') +MAXCONN = os.environ.get('MAXCONN', '2') listen_conf = Template(""" @@ -44,6 +46,7 @@ stats uri / stats hide-version stats auth $auth + stats refresh $refresh """) frontend_conf = Template(""" @@ -62,7 +65,7 @@ backend $backend mode $mode balance $balance - default-server inter $inter fastinter $fastinter downinter $downinter fall $fall rise $rise + default-server inter $inter fastinter $fastinter downinter $downinter fall $fall rise $rise maxconn $maxconn cookie $cookies_name insert $cookies_params """) cookies = "cookie \\\"@@value@@\\\"" @@ -74,7 +77,7 @@ backend $backend mode $mode balance $balance - default-server inter $inter fastinter $fastinter downinter $downinter fall $fall rise $rise + default-server inter $inter fastinter $fastinter downinter $downinter fall $fall rise $rise maxconn $maxconn cookie $cookies_name prefix $cookies_params """) cookies = "" @@ -87,7 +90,7 @@ """) backend_conf_plus = Template(""" - server $name-$index $host:$port $cookies check + server $name-$index $host:$port $cookies check weight $weight """) health_conf = """ @@ -105,7 +108,8 @@ fall=FALL, rise=RISE, cookies_name=COOKIES_NAME, - cookies_params=COOKIES_PARAMS + cookies_params=COOKIES_PARAMS, + maxconn=MAXCONN ) if BACKENDS_MODE == 'http': @@ -142,6 +146,7 @@ index=ip.replace(".", "-"), host=ip, port=port, + weight=1, cookies=cookies.replace('@@value@@', ip)) ################################################################################ @@ -153,11 +158,13 @@ server_port = backend_server.split(':') host = server_port[0] port = server_port[1] if len(server_port) > 1 else BACKENDS_PORT + weight = server_port[2] if len(server_port) > 2 else 1 backend_conf += backend_conf_plus.substitute( name=host.replace(".", "-"), index=index, host=host, port=port, + weight=weight, cookies=cookies.replace('@@value@@', host)) ################################################################################ @@ -208,6 +215,7 @@ index=index, host=host_ip, port=host_port, + weight=1, cookies=cookies.replace('@@value@@', host_ip) ) index += 1 @@ -235,7 +243,9 @@ configuration.write( listen_conf.substitute( - port=STATS_PORT, auth=STATS_AUTH + port=STATS_PORT, + auth=STATS_AUTH, + refresh=STATS_REFRESH ) )