Træfik es una herramienta muy interesante para utilizar como proxy inverso. Es muy sencillo el desplegarlo y la configuración de este es casi automática. Es capaz de interactuar con diferentes backends como; Kubernetes, docker, mesos, swarm… además de esto, puede generar certificados válidos con let’s encrypt al vuelo. Y es capaz de crear balanceos de carga de una manera autónoma. Incluye opciones interesantes como; HTTP/2, HA en modo cluster, actualización de la configuración en caliente…
En definitiva, es una herramienta muy útil si se quiere tener varios servicios docker que requieran del mismo puerto. La arquitectura de træfik, sería la siguiente:
Las peticiones mediante SNI entran en træfik y este se encarga de redirigirlas al servicio que toque.
Aquí va el proceso de como desplegar træfik con docker y configurarlo para poder usarlo.
Despliegue
Crear el directorio de træfik
mkdir traefik && cd traefik
Descargar el archivo de configuración
Nota: revisar el archivo de configuración para adecuarlo a las necesidades. Este archivo está preparado únicamente para realizar conexiones por el puerto 80. Más adelante se explicará como hacer para conexiones cifradas.
wget https://raw.githubusercontent.com/ichasco/traefik/master/traefik.toml
Crear la red específica para træfik. Este paso es importante hacerlo, para que luego todos los contenedores que quieran hacer uso de træfik poder agregarlos a esta red
docker network create traefik
Una vez hecho esto, hay 2 formas de desplegar træfik, con docker run o con docker-compose
Docker run
docker run -d -p 8080:8080 -p 80:80 --network traefik --name traefik -v $PWD/traefik.toml:/etc/traefik/traefik.toml -v /var/run/docker.sock:/var/run/docker.sock traefik
Docker-compose
wget https://raw.githubusercontent.com/ichasco/traefik/master/docker-compose.yml
Lanzar el docker
docker-compose up -d
Una vez hecho esto, ya tenemos træfik levantado. Para acceder a el para revisar el status de los servicios, se hace mediante la web
http://dockerserver:8080
Ahora solo queda el desplegar servicios. Para la prueba, vamos a desplegar un wordpress.
Para empezar crear la carpeta
mkdir wordpress
Descargar el docker-compose de wordpress (editar lo que se necesite)
wget -O docker-compose.yml https://raw.githubusercontent.com/ichasco/traefik/master/traefik-wordpress.yml
La parte importante de este docker-compose, es la parte de labels que es donde se declaran las acciones de træfik
Para los servicios que no se quieran publicar:
labels: - "traefik.enable=false"
Para los servicios que se quieran publicar:
labels: - "traefik.backend=wp" - "traefik.frontend.rule=Host:wp.ichasco.com" - "traefik.docker.network=traefik" networks: - traefik networks: traefik: external: name: traefik
Træfik tiene muchas mas opciones para definir. Mas info aquí
Ahora levantamos el wordpress
docker-compose up -d
Y automágicamente, una vez desplegado el wordpress, aparecerá en træfik
Ahora para acceder a el, necesitamos una entrada DNS que sea de la siguiente forma:
wp.ichasco.com --> dockerserver
Ya sea un CNAME o un registro A o incluso se puede poner en el /etc/hosts de nuestra máquina.
Una vez hecho esto, podemos acceder a nuestra página de la siguiente manera
http://wp.ichasco.com
Con la configuración actual de træfik, solo se puede acceder por el puerto 80. Si se quisiese acceder por el puerto 443 habría que hacer lo siguiente
HTTPS con Let’s Encrypt
Træfik tiene una opción muy interesante, que es crear certificados al vuelo con let’s encrypt. Para quien no conozca let’s encrypt, es una entidad certificadora gratuita y conocida por todos los navegadores. Con esta opción, una vez levantado el docker con el servicio, træfik crea automáticamente un certificado y puede llegar a forzar las conexiones por el puerto 443 para garantizar la seguridad de estas.
Para hacer esto, lo único que hay que hacer es editar el traefik.toml y añadir lo siguiente:
defaultEntryPoints = ["http", "https"] [acme] email = "info@ichasco.com" storageFile = "/etc/traefik/acme/acme.json" entryPoint = "https" acmeLogging = true onDemand = true OnHostRule = true [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls]
Y añadir al docker-compose.yml
ports: - "443:443" volumes: - $PWD/acme:/etc/traefik/acme
Para que træfik coja la configuración, hay que reiniciarlo
docker restart traefik_proxy_1
Escalado y balanceo
Además de todo lo comentado anteriormente, træfik es capaz de realizar balanceos round-robin automáticamente. Simplemente, escalando el servicio de docker que estemos usando con el mismo backend, træfik lo identifica y balancea las peticiones. Para hacer una prueba, vamos a escalar el wordpress
docker-compose scale wordpress=2
Si vemos los contenedores activos de docker
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce01dad912ca wordpress:latest "docker-entrypoint..." 5 seconds ago Up 3 seconds 80/tcp wordpress_wordpress_2 6b5dfa900823 traefik "/traefik" 45 hours ago Up 42 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp traefik_proxy_1 9463783ed428 wordpress:latest "docker-entrypoint..." 2 days ago Up 41 seconds 80/tcp wordpress_wordpress_1 8ec790b31890 mysql:5.7 "docker-entrypoint..." 2 days ago Up 41 seconds 3306/tcp wordpress_db_1
Como se puede apreciar hay ahora 2 instancias de wordpress que esto visto en træfik sería de la siguiente manera:
Y si se cayese o saturase uno de los wordpress, las conexiones se seguirían realizando por el otro contenedor.
Y esto es todo amigos 😉
Buen Post!, gracias por compartirlo!
lo he intentado hacer pero no me queda claro como `dockerserver` termina siendo la direccion a tu servidor. es algo automatico o es una configuracion que ya tenias?
Buenas,
correcto, dockerserver sería un registro DNS previamente creado que apunta al Host donde está instalado docker con Traefik. Traefik al funcionar con SNI tienes que tener un registro DNS ya sea en tu archivo hosts o en un servidor DNS, apuntando a la IP del host donde esté instalado.
Si tienes alguna duda mas coméntame.
Un saludo,
kaixo
Traefik tiene alguna manera de hacer un filtrado de ips distinto en cada container?
Buenas,
Con filtrado de IPs a que te refieres?
Un saludo
en la documentación he encontrado que puedes hacer un whitelist para todos los contenedores, el problema es cuando quieres poner la whitelist en un solo container. Lo he intentado con htaccess el problema es que las peticiones vienen desde el container de traefik con lo cual o las puedo filtrar asi
Buenas Ismael,
Muy buen post!. He estado realizando un laboratorio con tus ejemplos y me han salido salvo el Let´s Encrypt, pero eso lo miraré bien. La duda que tenía es sobre el balanceador de carga y su contenido. Desconozco como podría sincronizar el contenido que hay de ambos wordpress.
Gracias por la ayuda
Buenas, los wordpress los tienes desplegados con docker-compose? es el mismo contenedor escalado? son contenedores diferentes?
Lo ideal sería que el wordpress estuviese escalado y compartiera almacenamiento. De este modo, los datos van a ser los mismos en ambos.
Un saludo
Pues serían en diferentes contenedores sin escalar. No he caído en eso de ponerlo en el mismo volumen ¡y la cosa más sencilla!. Muchas gracias!
Un saludo