26 dic

HaProxy con Consul-Template y zero downtime reload

¿Por qué HaProxy con Consul-template?

HaProxy con Consul-template en Docker

HaProxy con Consul-template en Docker

Llevamos un tiempo trabajando en Docker con el dinamismo que ello nos supone, HaProxy con Consul-template nos ofrece una solucion muy similar a marathon-lb, el cual habíamos hablado en como usar marathon-lb para conectar nuestras aplicaciones dentro del cluster de Apache Mesos.

Marahon-lb es una maravilla, pero no dispone de algunas características que nos hacen falta, así que pensamos, bueno pues nos lo montamos nosotros.

Idea principal

La idea principal es utilizar la información que tenemos de nuestros servicios registrados en Consul, para poder generar la configuración de HaProxy con Consul-template. Fácil.

Lo haremos en docker así lo podremos lanzar en la plataforma de Apache Mesos, y claro esta si queremos que HaProxy tenga una configuración dinámica deberemos implementar el zero downtime reload

¿Qué es el Zero downtime reload HaProxy?

Cada vez que tengamos un cambio de configuración en HaProxy deberemos hacer una recarga del servicio, en el caso que tengamos conexiones establecidas esta recarga nos llevara a perderlas y claro, eso no es para nada deseable, ¿cómo solventamos este problema?

Pues seguiremos las indicaciones de Willy Tarreau CTO de HAPROXY,  lo que nos comenta es que podemos implementar una solución para descartar los paquetes SYN durante el reinicio de HaProxy, y aprovecharnos del funcionamiento de TCP para que se recupere automáticamente, añadiremos la solución en la imagen.

A esta solución hay una vuelta de tuerca mas, que lo explican maravillosamente bien la gente de Yelp, True Zero Downtime HAProxy Reloads.

Creación de los Dockers

Vamos a crear dos imágenes de Docker, por un lado la imagen con Consul-Templat y por otro la imagen de HaProxy que heredara de la primera imagen.

Toda la explicación y los ficheros necesarios están en mi github y la imagen de haproxy la podeis bajar de https://hub.docker.com/r/maauso/docker-consul-template/

Consul-template

Una de las partes mas importantes es entender el Consul-template que utilizaremos para HaProxy, gracias a Raul Fiestas por la creación del mismo :), podéis pasaros por su github, que tiene cosas muy interesantes https://github.com/rfiestas o su tumblr http://sudevops.tumblr.com/

La idea no es hacer una clase de consul-template, pero lo importante es saber las opciones que podemos usar, explicadas a continuación y que también podéis encontrar en https://github.com/maauso/docker-haproxy

¿Qué necesitamos para añadir un nuevo servicio a nuestro HaProxy?

Toda la información del servicio deberá estar en Consul, haremos un ejemplo con el servicio “www”

SERVICE_NAME=www

Este será en nombre de nuestro backend y frontend en la configuración de HaProxy, también será la url de acceso, que se concatenará al valor de HAPROXY_DOM, www.maauso.com

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_www.maauso.com

Deberemos usuar Consul Tags, para decidir que servicios de Consul queremos añadir a nuestro HaProxy

HAPROXY.ENABLE=true

Y tendremos otras opciones del backend usando tags.

HAPROXY.PROTOCOL=http
HAPROXY.BACKEND.BALANCE=roundrobin
HAPROXY.BACKEND.MAXCONN=10000
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 }
Opciones de configuración para HaProxy 

Variables Globales que podemos modificar

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

Variables que no tienen valor por defecto

HAPROXY_DOM=maauso.com

Variables por defecto que podemos cambiar

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
Por último zero downtime reload. 

Para conseguir el zero downtime reload consul-template enviará un SIGHUB al proceso que maneja a HaProxy, este proceso recibirá la señal con un trap y realizará el DROP de los paquetes SYN con iptables.

Acto seguido creara un nuevo proceso de HaProxy con la opción -sf $LATEST_HAPROXY_PID y eliminara la regla de iptables