Traefik 2 - Configuración avanzada con Docker Compose

23 February 2021 · 8 min lectura

Cuando se despliegan múltiples servicios en una máquina virtual será necesario incluir una pieza en la arquitectura que garantice exponer y redirigir el tráfico de forma fácil y segura.

Este artículo forma parte de la serie Taller de Microservicios donde se exponen los detalles de las tecnologías utilizadas en el caso de uso Cinema.

Traefik Proxy

Traefik Proxy es un Edge Router, un proxy inverso y balanceador de carga moderno pensado para desplegar microservicios de forma fácil y rápida. Entre las principales caraterísticas de Traefik está su velocidad y la facilidad para su configuración.

En el caso de uso Cinema el servicio de Traefik Proxy aparece con el nombre proxy. La descripción completa del mismo está en el fichero docker-compose.yml.

version: "3.8"
services:
  proxy:
    image: traefik:v2.4.2
    command:
      # - "--log.level=DEBUG"
      - "--api"
      - "--api.dashboard"
      - "--api.insecure" # Don't do that in production
      - "--providers.docker"
      - "--entrypoints.web.address=:80"
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
        read_only: true
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

En Traefik existen múltiples operadores (providers), p.je: Kubernetes Ingress, ECS, Rancher, entre otros. Cada uno tiene configuraciones específicas según sus necesidades. En este fragmento podrá identificar que ha sido utilizado el provider Docker.

Se ha definido el uso del puerto 80 como punto de entrada al resto de servicios y el socket de Docker como volumen /var/run/docker.sock para detectar dinámicamente los servicios.

Durante la puesta en marcha de Traefik será necesario estar atentos a los registros (logs) para saber si el sistema responde como se espera. Los logs en modo DEBUG podrán ser habilitados a través de la línea "--log.level=DEBUG". Luego utilice el siguiente comando de Docker Compose para darle seguimiento a los eventos.

$ docker-compose logs -f proxy
Attaching to microservices-docker-go-mongodb_proxy_1
proxy_1      | time="2021-02-16T10:34:51Z" level=info msg="Configuration loaded from flags."
proxy_1      | time="2021-02-16T10:34:51Z" level=info msg="Traefik version 2.4.2 built on 2021-02-02T17:20:41Z"
proxy_1      | time="2021-02-16T10:34:51Z" level=debug msg="Static configuration loaded {\"global\":{\"checkNewVersion\":true},\"serversTransport\":{\"maxIdleConnsPerHost\":200},\"entryPoints\":{\"traefik\":{\"address\":\":8080\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{},\"http\":{}},\"web\":{\"address\":\":80\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{},\"http\":{}}},\"providers\":{\"providersThrottleDuration\":2000000000,\"docker\":{\"watch\":true,\"endpoint\":\"unix:///var/run/docker.sock\",\"defaultRule\":\"Host(`{{ normalize .Name }}`)\",\"exposedByDefault\":true,\"swarmModeRefreshSeconds\":15000000000}},\"api\":{\"insecure\":true,\"dashboard\":true},\"log\":{\"level\":\"DEBUG\",\"format\":\"common\"}}"
...

¿Podrán consultarse los detalles de la configuración de Traefik a través de la UI?

Traefik Dashboard

Traefik Dashboard le permitirá visualizar de forma centralizada los componentes de cada servicio definido en el fichero Compose. Entrypoints, Routers, Middlewares y Services son algunos de los principales elementos que podrá identificar en el dashboard. Deberá prestar especial atención a estos componentes para lograr el tráfico correcto entre las piezas de software.

Podrá acceder al dashboard de Traefik una vez iniciados los procesos como se indican en el caso de uso Cinema. La siguiente imagen corresponde con el dashboard de Traefik desplegado.

Traefik Dashboard

Acceda a la sección Routers para que conozca las reglas de entrada habilitadas para los servicios.

Traefik Routers

Habilite el acceso a las APIs internas

Por motivos de seguridad el único servicio expuesto de la aplicación Cinema es el sitio web. El resto de microservicios están restringidos a la subred creada por Docker Compose.

Para mostrar los conceptos que verán a continuación será necesario habilitar el acceso a las APIs internas. Traefik permite realizar esta configuración de forma fácil a través de etiquetas (labels). Las siguientes dos etiquetas serán las responsables de definir la ruta y el puerto a un microservicios.

...
  labels:
    # Enable public access
    - "traefik.http.routers.movies.rule=PathPrefix(`/api/movies/`)"
    - "traefik.http.services.movies.loadbalancer.server.port=4000"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Habilite estas etiquetas en los servicios users, movies, showtimes y bookings. Luego utilice el siguiente comando para reiniciar los servicios.

$ docker-compose up -d

Acceda nuevamente al Dashboard de Traefik y observe las nuevas rutas incluidas en el listado.

Traefik Routers

Traefik Middlewares

¿Qué son los Middlewares y para qué los necesito?

Middleware (middle - software, software en el medio) le permitirá incluir funcionalidades y comportamientos a sus servicios a través de configuraciones. Traefik cuenta con el concepto Middleware, donde podrá concatenar múltiples piezas de software antes de que el tráfico llegue al servicio de destino. Ver documentación oficial.

Traefik Middlewares

Es importante que domine el concepto Middleware de Traefik porque le permitirá ahorrar tiempo de desarrollo y flexibilidad en sus configuraciones. Un primer paso para entenderlo será ir a la sección Middleware del dashboard. Los dos elementos que verá en la lista son creados por Traefik para garantizar el acceso al dashboard a través de la URL /dashboard.

Traefik Middlewares

¿Cómo incluir los middlewares disponibles de Traefik en los servicios definidos en Compose?

Para incluir un middleware en un servicio de Docker Compose será necesario definirlo y luego asignarlo. Es importante destacar que una definición puede ser asignada a múltiples servicios.

Definir Middlewares

La definición y asignación de middlewares se realiza a través de labels. En el fichero docker-compose.yml han sido adicionados tres elementos que podrán ser activados si elimina el comentario al inicio de cada línea. Cada etiqueta corresponde con un middleware existente en Traefik.

services:
  proxy:
    image: traefik:v2.4.2
    command:
      ...
    labels:
      # Create basics middlewares
      - "traefik.http.middlewares.my-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
      - "traefik.http.middlewares.my-compress.compress=true"
      - "traefik.http.middlewares.my-header.headers.customresponseheaders.X-Custom-Response-Header=cinema"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Reinicie el servicio proxy y vuelva a consultar el listado de elementos del dashboard.

$ docker-compose up -d
...
Recreating microservices-docker-go-mongodb_proxy_1 ...
Recreating microservices-docker-go-mongodb_proxy_1 ... done

Traefik Middlewares

Identifique los tres middlewares adicionados en el listado. Ahora estos nuevos componentes están listos para ser asignados a los servicios.

Asignar Middlewares a un servicio

La asignación de los middlewares a los servicios se realiza a través de labels. A continuación se muestra cómo incluir los nuevos middlewares en el flujo del servicio movies.

En estos momentos el servicio está definido de la siguiente forma:

  movies:
    image: ghcr.io/mmorejon/cinema-movies:v2.1.0
    command:
      - "-mongoURI"
      - "mongodb://db:27017/"
    labels:
      - "traefik.http.routers.movies.rule=PathPrefix(`/api/movies/`)"
      - "traefik.http.services.movies.loadbalancer.server.port=4000"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Las etiquetas que existen en este momento le indican a Traefik la URL y el puerto a utilizar para acceder al servicio. En la vista del servicio movies del dashboard podrá ver el flujo en uso. Podrá notar que no existen middlewares asignados.

Traefik Middlewares list

El próximo paso será incluir la etiqueta que permite asignar múltiples middlewares al Router del servicio movies.

  movies:
    image: ghcr.io/mmorejon/cinema-movies:v2.1.0
    command:
      - "-mongoURI"
      - "mongodb://db:27017/"
    labels:
      - "traefik.http.routers.movies.rule=PathPrefix(`/api/movies/`)"
      - "traefik.http.services.movies.loadbalancer.server.port=4000"
      # Apply the middleware
      - "traefik.http.routers.movies.middlewares=my-header,my-compress"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Reinicie el servicio movies para que sea incluida la nueva configuración.

$ docker-compose up -d
...
Recreating microservices-docker-go-mongodb_movies_1 ...
Recreating microservices-docker-go-mongodb_movies_1 ... done

Actualice la página del dashboard y podrá observar los middlewares como parte del flujo del servicio movies.

Traefik Middlewares Asigned

Compruebe su correcto funcionamiento utilizando el siguiente comando.

$ curl -X GET -I http://localhost/api/movies/

HTTP/1.1 200 OK
Content-Length: 783
Content-Type: application/json
Date: Tue, 16 Feb 2021 14:23:27 GMT
Vary: Accept-Encoding                  # <-- my-compress middleware
X-Custom-Response-Header: cinema       # <-- my-header middleware

Si lo desea, podrá asignar estas funcionalidades al resto de servicios que lo necesiten sin tener que definirlas nuevamente.

Las nuevas funcionalidades incluidas a través de los middlewares son de gran importancia para el tráfico entres servicios, pero todavía no se ha visto otro tema igual de importante: las métricas.

¿Es posible visualizar en el dashboard las métricas de los servicios desplegados?

Traefik Pilot

Traefik Pilot es una plataforma como servicio (SaaS) concebida para extender las funcionalidades de Traefik e incluir visibilidad a través de métricas (Observability).

Para conectar el dashboard con esta plataforma deberá dar clic al botón Connect with Traefik Pilot ubicado en la esquina superior derecha de la pantalla. Luego seleccione una de las alternativas que aparecen para completar el registro.

Para realizar este ejemplo se ha utilizado la opción de GitHub.

Traefik Middlewares Asigned

Una vez registrado se mostrará una pantalla donde aparece su usuario junto con las instrucciones para incluir la instancia que está utilizando. En este caso la instancia es el servicio proxy definido en el fichero docker-compose.yml.

Traefik Middlewares Asigned

El próximo paso será utilizar el botón Register Current Traefik Instance para obtener el token que permitirá asociar el serivio proxy como instancia de la plataforma Pilot.

Busque en el serivico proxy del fichero docker-compose.yml la línea --pilot.token= y reemplace el valor con el token generado por Pilot.

  proxy:
    image: traefik:v2.4.2
    command:
      - "--log.level=DEBUG"
      - "--api=true"
      - "--api.dashboard=true"
      - "--api.insecure=true" # Don't do that in production
      - "--providers.docker"
      - "--entrypoints.web.address=:80"
      # add pilot token service
      - "--pilot.token=3d1bd97f-cb9d-4cde-8112-77ce2f5abc92"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Luego reinicie el servicio proxy con el comando docker-compose up -d y acceda nuevamente al panel para que pueda conocer las métricas de la aplicación Cinema.

Traefik Middlewares Asigned

Habrá notado la existencia de una pestaña Plugins a continuación de Metrics, por lo que seguramente se preguntará:

¿Qué son los Plugins en Traefik y cómo puedo utilizarlos?

Traefik Plugins

Los Plugins son funcionalidades externas al core de Traefik que permiten enriquecer el sistema con nuevos comportamientos. La mayoría son desarrollados por la comunidad, lo que significa que puedes utilizar los existentes o crear uno nuevo.

En este momento existen múltiples plugins que pueden ser incluidos de forma rápida y sencilla.

Traefik Middlewares Asigned

El plugin seleccionado para usar como ejemplo es Rewrite Body. La misión de este plugin es modificar el contenido de la respuesta del mensaje.

Lo primero que deberá hacer es incluir el plugin en la configuración del servicio proxy para que descargue esta funcionalidad durante el inicio del sistema. Luego pasará a registrar el plugin como un middleware a través de las etiquetas de Docker Compose. El siguiente fragmento muestra cómo queda el servicio proxy:

  proxy:
    image: traefik:v2.4.2
    command:
      ...
      # add pilot token service
      - "--pilot.token=3d1bd97f-cb9d-4cde-8112-77ce2f5abc92"
      # install plugin rewrite body
      - "--experimental.plugins.plugin-rewrite.modulename=github.com/traefik/plugin-rewritebody"
      - "--experimental.plugins.plugin-rewrite.version=v0.3.1"
    labels:
      # Create basics middlewares
      - "traefik.http.middlewares.my-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
      - "traefik.http.middlewares.my-compress.compress=true"
      - "traefik.http.middlewares.my-header.headers.customresponseheaders.X-Custom-Response-Header=cinema"
      # Create middlewares for plugins
      - "traefik.http.middlewares.my-rewrite.plugin.plugin-rewrite.lastModified=true"
      - "traefik.http.middlewares.my-rewrite.plugin.plugin-rewrite.rewrites[0].regex=ID"           # <-- valor a modificar
      - "traefik.http.middlewares.my-rewrite.plugin.plugin-rewrite.rewrites[0].replacement=MY-ID"  # <-- nuevo valor
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Reinicie este servicio y compruebe que el plugin ha quedado registrado como middleware correctamente.

Traefik Middlewares Asigned

El último paso será asignar el middleware del plugin a un servicio, pero antes de hacerlo liste los datos sin modificaciones.

$ curl -X GET http://localhost/api/movies/

[{"ID":"6002130f0f646161d37f7960","Title":"The Lighthouse","Director":"Robert Eggers","Rating":4.4,"CreatedOn":"0001-01-01T00:00:00Z"},..

Nota: Si la información que obtiene es vacía [ ] deberá restaurar los datos en la aplicación Cinema.

Ahora incluya el nuevo middleware en el listado existente del servicio movies.

      ...
      # Apply the middleware
      - "traefik.http.routers.movies.middlewares=my-header,my-compress,my-rewrite"
...
# ver el código completo en https://github.com/mmorejon/microservices-docker-go-mongodb

Reinicie el servicio movies y vuelva a realizar la consulta. Podrá notar que ha sido sustituido ID por MY-ID.

$ curl -X GET http://localhost/api/movies/

[{"MY-ID":"6002130f0f646161d37f7960","Title":"The Lighthouse","Director":"Robert Eggers","Rating":4.4,"CreatedOn":"0001-01-01T00:00:00Z"},...

Conclusiones

Traefik Labs se mantiene evolucionando constantemente y adaptándose a las nuevas necesidades de la industria. En este artículo se han mostrado las opciones que brinda Traefik para incluir visibilidad, métricas y funcionalidades a los servicios gestionados desde Docker Compose.

Recuerde profundizar en los conceptos Middleware, Pilot y Plugins para obtener el mayor beneficio posible de la plataforma.

comments powered by Disqus