Skip to content
This repository has been archived by the owner on Jul 28, 2020. It is now read-only.

Docker container running HAProxy, dynamically updates from Consul using dyconf

License

Notifications You must be signed in to change notification settings

laktak/consul-haproxy-dyconf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

consul-haproxy-dyconf

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

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 ....

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
    '''
}

About

Docker container running HAProxy, dynamically updates from Consul using dyconf

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published