consul-haproxy-dyconf is a Docker container that runs HAProxy and dynamically updates its configuration with data from Consul using dyconf.
Logs from HAProxy are routed so you can see them with the docker logs
command or collect them with logspout.
usage: -host=HOSTNAME [-port=PORT] -tag=TAGNAME
-host Consul host
-port Consul port, default 8500
-tag tag of the docker containers to include
-config path to the template configuration
-dump dumps the generated template to the console
-q quiet, no logs
See https://github.com/laktak/dyconf for details.
You would usually run the container with
docker run -d -p 5900:80 laktak/consul-haproxy-dyconf -host=10.1.1.1 -tag=rest
This collects all nodes that are tagged with rest
from Consul (10.1.1.1 in this sample) and sets up HAProxy to route to them.
E.g. if you have a container running that is named foo
you can curl http://HAPROXY/foo/
.
FYI tags can be set manually or by using env SERVICE_TAGS=...
in combination with registrator.
If you have other requirements you can either fork this repo or supply your own configuraton with docker run -v $PWD/yourConfig.hjson:/app/config.hjson ...
.
#hjson (go to http://hjson.org for details)
{
# define the controller that fetches the configuration and produces the content for outputFile
controller: controller.js
outputFile: /etc/haproxy/haproxy.cfg
# refresh interval in seconds
refreshInterval: 5
# start a syslog server listening on port 514
# to redirect logs for Docker
syslog: true
# run on start/restart to configure rsyslog and launch haproxy
startup:
'''
# launch haproxy (will log to syslog from which it's printed to the console)
haproxy -f /etc/haproxy/haproxy.cfg
'''
# to reload a new configuration with minimal service impact and without breaking existing sessions
reload: haproxy -f /etc/haproxy/haproxy.cfg -sf $(cat /var/run/haproxy.pid)
# kill haproxy on shutdown
shutdown:
'''
PID=$(cat /var/run/haproxy.pid)
kill -9 $PID
wait $PID
'''
# define the template to generate the haproxy.cfg
/*
services was generated by the code in controller.js and contains data in
the following format:
[ {
name: 'MyService',
tags: [ 'rest' ],
nodes: [ {
node: 'hostname',
address: '10.1.1.2',
serviceID: 'hostname:foo:80',
serviceName: 'foo-bar-80',
serviceTags: [],
serviceAddress: '10.0.0.42',
servicePort: 80,
}, ... ]
}, ... ]
*/
template:
'''
global
daemon
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
log 127.0.0.1 format rfc5424 local0 info
defaults
mode http
log global
option httplog
option dontlognull
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend http-in
bind *:80
<% services.forEach(svc => {
%> acl app_<%=svc.name%> path_beg -i /<%=svc.name%>/
use_backend svr_<%=svc.name%> if app_<%=svc.name%>
<% }); %>
<% services.forEach(svc => {
%>backend svr_<%=svc.name%>
mode http
balance roundrobin
option forwardfor
option httpchk HEAD /health HTTP/1.1\r\nHost:localhost
reqrep ^([^\ ]*\ /)<%=svc.name%>[/]?(.*) \1\2
<% svc.nodes.forEach(node => {
%> server <%=node.node%>_<%=node.servicePort%> <%=node.serviceAddress%>:<%=node.servicePort%> check
<% }); %>
<% });
%>
listen stats
bind *:1936
mode http
stats enable
stats uri /
stats hide-version
stats auth stat:view
'''
}