28 jun

¿Cómo usar Marathon-lb en Apache Mesos?

marathon-lb

Voy a explicar como trabajar con Marathon-lb (sustituto de marathon-haproxy-bridge) para Apache Mesos, hay parte teórica y parte práctica :),  hace un tiempo expliqué qué era Apache-Mesos y cómo empezar a trabajar con uno de su Frameworks llamado Marathon, también comentamos como utilizar marathon-haproxy-bridge para balancear peticiones de los Dockers que tengamos esparcidos por todo el cluster.

Antes de empezar nos debemos poner un poco en contexto, os recomiendo que leáis las entradas anteriores, para entender el ecosistema.

Parte teórica 

¿Qué es marathon-lb?

Marathon-lb es una solución que nos da la gente de Mesosphere para poder balancear de forma sencilla los servicios que tenemos en nuestro cluster de Apache Mesos, como sabemos por norma general cuando vamos desplegando Dockers en Apache Mesos estos empezaran a correr en slaves de Mesos aleatorios y en puertos aleatorios, esta dinámica hace complicado que podamos en trabajar con esos Dockers a no se que tengamos algún punto de entrada. Eso exactamente es lo que nos da marathon-lb.

¿Qué nos ofrece?

  1. Integración directa con Marathon, dependencia únicamente del Framework de Marathon
  2. Punto de entrada a los Dockers que tengamos corriendo en Apache Mesos
  3. Escalabilidad horizontal
  4. Actualizaciones de configuracion en tiempo real, conectando marathon-lb a Martahon usando SSE
  5. HealthChecks, tanto del propio HAProxy como a través de  Marathon
  6. TLS/SSL
  7. HaProxy Templates (la configuracion de HAProxy se realiza a través de labels de Docker, sublime)
  8. Imagen Docker para correrlo en Apache Mesos

¿Cómo funciona?

El funcionamiento en si es de lo más sencillo, marathon-lb “solo” es un script hecho en python que una vez conectado a Marathon  a través de SSE, y va actualizando la configuración del HAProxy que lleva en su interior, por cada aplicación que lancemos en Apache Mesos marathon-lb hará la asociación entre el punto de entrada que le hayamos dicho y el los Dockers con sus respectivos puertos.

La asociación entre HAProxy y los Dockers lo podemos hacer por dos métodos, puerto o usando un virtual host.

En el caso de querer una asociación por puerto, o sea que la url de acceso sea del tipo lo

http://marathon-lb.company.com:10001

Deberemos lanzar el Docker definiendo un puerto de servicio que será utilizado por marathon-lb como puerta de entrada, en este caso el 10001

Otro caso de uso es la asociación por virtual host, en este caso la url de entrada podría ser algo como.

http://miservicio.company.com

Para usar esta opción deberemos lanzar el Docker con la label

HAPROXY_{n}_VHOST

Por ejemplo

HAPROXY_VHOST = "http://miservicio.company.com" 

Antes de pasar a la parte practica decir que

Parte práctica

Objetivos

  • Tener un único punto de entrada que nos de acceso a todos los Dockers de un servicio que estén corriendo en nuestro Apache Mesos, en este ejemplo será un Nginx

Características de práctica

  1. Utilizaremos el acceso por Virtual Host
  2. Conectaremos marathon-lb a Marathon usando SSE
  3. Lanzaremos el docker de marathon-lb en modo Host.

¿Como lanzamos marathon-lb en Apache Mesos ?

Como es lógico primero de todo deberemos montar el JSON para poder lanzar marathon-lb en nuestro Apache Mesos a través del Framework Marathon, el JSON tiene una pinta tal que así y explicamos cada punto más abajo

Campos:

“cmd” :

  •  /marathon-lb/run sse : Ejecucion de marathon-lb en modo sse
  • –marathon: Url de nuestro Marathon
  • –group : Con esta opcion estamos diciendo cuales son los dockers que queremos que se usen a través de marathon-lb, en nuestro caso aquello que lleven HAPROXY_0_GROUP: “qa“.
  • –health-check:  Con esta opcion estamos diciendo que HAProxy no active el docker hasta que el healthcheck de Marathon este ok. 

 “ports”:

  • Por seguridad al ejecutar el Docker en modo HOST, deberemos asegurar que los puertos que utiliza nuestro HAProxy están disponibles en el Slave de Mesos, junto con “requirePorts” : true, añadiendo los puertos tendremos  en PORT0-1-2 que los utilizaremos para hacer el healtcheck de HAProxy

“constraints”:

  • Con estas dos constraints nos aseguramos que no vayamos a tener dos Marathon-lb en el mismo host (puede ser redundante con la opción de ports) y decidimos en que datacenter queremos lanzadlos.

 “healthchecks”:

  • Con este COMMAND comprobamos que el servicio este levantado y Marathon pueda darnos información del estado de HAProxy

Lanzamos marathon-lb

curl -X POST -H "Content-Type: application/json"  --data @marathon-lb-test.json 'http://marathon.company.com:8080/v2/apps'

Veremos en Marathon:

marathon-lb

¿Cómo lanzamos Nginx para que trabaje con Marathon-lb?

Ejemplo de JSON que deberíamos lanzar para que trabajara con marathon-lb, la explicación mas abajo.

Aquí la parte más importante, los labels que hemos añadido en el JSON, a través de labels en nuestro Docker haremos la configuración de nuestro HAProxy, tenemos una lista bastante extensa de opciones, en este ejemplo explicare los que me parecieron más comunes de utilizar.

Podemos encontrar la lista en el github de Mesosphere

“labels”

  • “HAPROXY_BACKEND_WEIGHT”: Peso que tendrá esta backend en HAProxy respecto a otros.
  • “HAPROXY_MODE”: http o tcp
  • “HAPROXY_BALANCE”: Tipo de balance
  • “HAPROXY_GROUP”:  Grupo al que pertenece, con esta opcion asociaremos nuestro nginx al HAProxy que queramos.
  • “HAPROXY_BACKEND_STICKY_OPTIONS” :  Una sticky cookie 
  • “HAPROXY_VHOST”:  Pues lo más importante a que fqdn nuestro HAPoxy nos dará acceso 

Lanzamos nginx

curl -X POST -H "Content-Type: application/json"  --data @nginx.json 'http://marathon.company.com:8080/v2/apps'

Veremos en Marathon:

Apache Mesos Nginx Marathon

Escalamos a 5 nginx

Apche Mesos Marathon scale

Si nos fijamos tenemos, como esperábamos cada nginx en un puerto diferente.

Si comprobamos HAProxy veremos en el log interno qué es lo que hizo.

marathon_lb: received event of type deployment_success
marathon_lb: received event of type health_status_changed_event
marathon_lb: fetching apps
marathon_lb: received event of type deployment_step_success
marathon_lb: GET http://marathon.company.com:8080/v2/apps?embed=apps.tasks
marathon_lb: got apps ['/test/ha/nginx/nginx', '/tools/docker/registry', '/prova-logs','/test/ha/marathon-lb-test']
marathon_lb: generating config
marathon_lb: HAProxy dir is /marathon-lb
marathon_lb: configuring app /test/ha/nginx/nginx
marathon_lb: frontend at *:10001 with backend test_ha_nginx_nginx_10001
marathon_lb: adding virtual host for app with hostname miguel.haproxy.com
marathon_lb: adding virtual host for app with id /test/ha/nginx/nginx
marathon_lb: backend server 192.168.1.100:50071 on server
marathon_lb: backend server 192.168.1.101:58437 on server
marathon_lb: backend server 192.168.1.102:12213 on server
marathon_lb: backend server 192.168.1.103:45197 on server
marathon_lb: backend server 192.168.1.104:14673 on server
marathon_lb: reading running config from /marathon-lb/haproxy.cfg
marathon_lb: updating tasks finished, took 0.24720096588134766 seconds

Podemos ver como marathon-lb

  1. Detecto un nuevo deploy
  2. Comprobó las aplicaciones y únicamente se quedo con las que cumplen la opción –group que explicamos mas arriba
  3. Creo el backend para nuestro ngnix y asigno el virtul host miguel.haproxy.com
  4. Añade todos los dockers que tenemos en nuestro mesos slave en
  5. Actualiza la configuracion
  6. Todo esto en 0.2472 segundos.

Si  comprobamos la pagina de stats de HAProxy podremos ver .

Apache Mesos HAPoxy

Por último comprobamos que nos contesta

curl -H "Host: miguel.haproxy.com" http://192.168.1.10
Welcome to nginx!
Thank you for using nginx.

Todo funcionando!

 

 

9 thoughts on “¿Cómo usar Marathon-lb en Apache Mesos?

  1. Sabes si es posible utilizar marathon-lb sobre tasks levantadas directamente sobre la api de mesos, no con la API de marathon.

    Al levantar el scheduler de una app de mesos utilizando marathon, marathon solo es consciente del scheduler y por lo tanto las task que levante este scheduler, si atacan a la api de mesos, no son vistas por marathon.

    En este caso, entiendo que no es posible, ya que al no ser consciente marathon de esas tareas marathon-lb es incapaz de ver estas tareas.

    Un saludo

  2. Hola Miguel,
    Excelente post !!!
    Tengo unas preguntas recién estoy revisando DC/OS, estoy haciendo una demo, mis preguntas son muy básicas, pero estoy tratando de entender como funciona.
    Cuando lanzas marathon-lb en mesos ¿de donde saco el valor “”–marathon http://marathon.company.com:8080“?
    Para el balanceo de cargas he revisado la documentación de Mesos y según veo todo se define en los labels cuando se lanza la app, si agrego esto seria suficiente?:
    “HAPROXY_GROUP”:”external”
    “HAPROXY_0_VHOST”: “192.168.65.111”
    Por último para confirmar el balanceo sería suficiente con acceder curl -H http://192.168.65.111

    Muchas gracias.

    • Buenos días Gabriel, efectivamente la URL que tienes que poner es la de la api de marathon, y también es cierto que todo se configura con labels en el JSON de la aplicación que quieres lanzar, pero en la parte de VHOST, no es un ip sino el virtual host al cual quieres que conteste tu container, puedes ver un ejemplo en el artículo, tienes dos modos de balancear, capa 7 o capa 4. Espero haberte ayudado. Un saludo

Responder a paco Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>