Skip to content

maauso/docker-haproxy

Repository files navigation

HaProxy container - with Zero-Downtime Reloads and consul-template

Docker container for HAProxy with consul-template, zero-downtime reloads and consul-template using maauso/docker-consul-template

Zero-Downtime Reloads

When HAProxy reloads using its 'graceful reload' feature, there's a tiny amount of time where a number of packets might be dropped in the process. This is well documented elsewhere around the internet. This container uses the 'drop syn packets' technique to mitigate that. There are more sophisticated techniques available which lead to lower delays on a restart. If you'd like to implement one of those (for example, a variation of the Yelp qdisc technique that works for incoming traffic or the unbounce IP tableflip technique) in this container

Alt text

DNS balancing

If you are using DNS balancer with consul in front HaProxy, now we can upgrade to docker without loss connections, I added kill () funtion. For more information, see run.sh https://github.com/maauso/docker-haproxy/blob/master/run.sh

Zombies reaping

When running within isolated containers, you may have to care about reaping orphan child processes. Haproxy typicaly produce orphan processes because of it's two steps reload machanism. I added tini for this purpose. For more information, see https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

Run container

sudo docker run --dns=8.8.8.8 -p8080:8080 -p4444:4444  -e CONSUL_SERVER="$CONSUL_SERVER" maauso/haproxy:1.7.1

HAPROXY Configure options

Global variables that we can use it

HAPROXY_MAXCONN_GLOBAL=50000
HAPROXY_SPREAD_CHECKS=5
HAPROXY_MAX_SPREAD_CHECKS=15000
HAPROXY_SPREAD-CHECKS=5

This variable doesn't have default value

HAPROXY_DOM=maauso.com

Default variables that we can use it

HAPROXY_RETRIES=3
HAPROXY_BACKLOG=10000
HAPROXY_MAXCONN=10000
HAPROXY_TIMEOUT_CONNECT=3s
HAPROXY_TIMEOUT_CLIENT=30s
HAPROXY_TIMEOUT_SERVER=30s
HAPROXY_TIMEOUT_HTTP_KEEP_ALIVE=1s
HAPROXY_TIMEOUT_HTTP_REQUEST=15s
HAPROXY_TIMEOUT_QUEUE=30s

How to configure your application to work with HaProxy

Consul-Service-Name

SERVICE_NAME=www

It'll be Frontend / Backend name and DNS name before global domain, for exemple If we use `apache url will be www.maauso.com Frontend like

frontend app_http_in
  bind *:8080
  mode http
  acl host_www.maauso.com hdr(host) -i www.maauso.com
  use_backend www.maauso.com if host_wwww.maauso.com

You should use Consul Tags to configure it, consul-template only add services that have the follow tag

"SERVICE_8080_TAGS": "haproxy_enable"

Availables SERVICE_TAGS, you can change some backend options with :

HAPROXY.ENABLE=true
HAPROXY.PROTOCOL=http
HAPROXY.BACKEND.BALANCE=roundrobin
HAPROXY.BACKEND.MAXCONN=10000

In the end the backend will be

backend www.maauso.com
  balance roundrobin
  mode http
  option forwardfor
  option tcp-check
  default-server inter 10s fall 1
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }

How to run HaProxy in Marathon

{
  "id": "/services/haproxy-app",
  "cmd": null,
  "cpus": 0.1,
  "mem": 128,
  "disk": 0,
  "instances": 1,
  "container": {
    "type": "DOCKER",
    "volumes": [],
    "docker": {
      "image": "maauso/haproxy:1.7.1",
      "network": "HOST",
      "portMappings": null,
      "privileged": true,
      "parameters": [
        {
          "key": "publish",
          "value": "4444:4444"
        }
      ],
      "forcePullImage": true
    }
  },
  "env": {
    "SERVICE_8080_NAME": "lb-app",
    "CONSUL_SERVER": "127.0.0.1:8500",
    "SERVICE_4444_NAME": "lb-app"
  },
  "healthChecks": [
    {
      "protocol": "COMMAND",
      "command": {
        "value": "/bin/bash -c \\\"</dev/tcp/$HOST/$PORT1\\\""
      },
      "gracePeriodSeconds": 300,
      "intervalSeconds": 60,
      "timeoutSeconds": 20,
      "maxConsecutiveFailures": 3,
      "ignoreHttp1xx": false
    }
  ],
  "portDefinitions": [
    {
      "port": 8080,
      "protocol": "tcp",
      "labels": {}
    },
    {
      "port": 4444,
      "protocol": "tcp",
      "labels": {}
    }
  ],
  "backoffFactor": 1.5,
  "maxLaunchDelaySeconds": 60,
  "upgradeStrategy": {
    "minimumHealthCapacity": 0.75,
    "maximumOverCapacity": 0
  },
  "requirePorts": true
}