Traefik: Proxy inverso y balanceador de carga para Docker

Cloud, Seguridad, Tecnología de sistemas

Trevenque Group » Blog » Soluciones Empresariales » Traefik: Proxy inverso y balanceador de carga para Docker

Traefik es un proxy inverso y balanceador de carga que se integra nativamente con Docker y Kubernetes, así como con otras tecnologías de cluster como Mesos o Amazon ECS.

En este post vamos a utilizar Traefik como proxy inverso hasta una instalación de WordPress realizada mediante Docker y docker-compose . Utilizaremos el dominio canonigos.me  que apuntará mediante un wildcard DNS a una instancia EC2 en AWS.

Prerrequisitos

Partimos de una instancia con direccionamiento público y sistema operativo Debian 10 64bits.

Instalación de docker  y docker-compose

Vamos a instalar Docker y la herramienta docker-compose  en nuestro host:

# Actualizamos los paquetes del sistema e instalamos la key del repositorio de docker
sudo apt update
sudo apt -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# Agregamos repositorio de docker para Debian y actualizamos fuentes.
sudo add-apt-repository \
"deb  https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
sudo apt update

# Instalamos docker-ce y agregamos nuestro usuario al grupo docker.
# De esta forma no necesitaremos ejecutar el comando docker mediante sudo.
sudo apt install docker-ce
sudo usermod -aG docker ${USER}

# Podemos comprobar tras cerrar sesión y volver a entrar que ya tenemos docker instalado.
admin@ip-10-0-3-96:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

# Descargamos docker-compose y lo hacemos ejecutable
sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Comprobamos la versión instalada
admin@ip-10-0-3-96:~$ docker-compose --version
docker-compose version 1.27.4, build 40524192

Configurando Traefik por primera vez: Accediendo al Dashboard

Una vez tenemos el entorno preparado para instalar contenedores docker, vamos a configurar una carpeta en nuestro directorio de usuario para poder desplegar Traefik.

# Creamos el directorio que albegará las configuraciones de Traefik y el docker-compose.yml
mkdir ~/traefik && cd traefik
mkdir -p data/configurations
touch docker-compose.yml
# Creamos el fichero de configuración estática
touch data/traefik.yml
# Creamos el fichero de configuración dinámica.
touch data/configurations/dynamic.yml
# Creamos el fichero que albergará las respuestas de Let's Encrypt
touch data/acme.json
chmod 600 data/acme.json

El siguiente paso será editar el fichero docker-compose.yml . En él definiremos la versión del contenedor a utilizar, en este caso la etiqueta será latest . También definiremos que los puertos que expondrá serán 80  y 443 . Definiremos volúmenes y ficheros a importar dentro del contenedor (configuración estática, dinámica y fichero para letsencrypt). También usaremos una red llamada proxy  que daremos de alta más adelante para usarla con los contenedores.

Por último, una parte importante son las etiquetas con las que configuraremos este despliegue. Éstas definirán el dominio a usar (traefik.canonigos.me ), el entrypoint  que hemos llamado websecure y que irá dirigido contra el Dashboard de Traefik (service=api@internal ) y la red que tendrá agregada el contenedor (proxy ).

# docker-compose.yml
version: '3.7'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    security_opt:
      - no-new-privileges:true
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
      - ./data/configurations:/configurations
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.traefik-secure.entrypoints=websecure"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.canonigos.me`)"
      - "traefik.http.routers.traefik-secure.middlewares=user-auth@file"
      - "traefik.http.routers.traefik-secure.service=api@internal"

networks:
  proxy:
    external: true

Una vez configurado el fichero docker-compose.yml , pasamos a editar la configuración estática de Traefik:

# data/traefik.yml
api:
  dashboard: true

# Definición de los entrypoints
entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure

  websecure:
    address: :443
    http:
      middlewares:
        - secureHeaders@file
      tls:
        certResolver: letsencrypt

# Proveedores: Docker y configuración dinámica mediante provider de tipo file.
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: /configurations/dynamic.yml

# Configuración Let's Encrypt que usaremos en el entrypoint websecure
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@canonigos.me
      storage: acme.json
      keyType: EC384
      httpChallenge:
        entryPoint: web

Y, por último, editaremos la configuración dinámica. En ella, definiremos las cabeceras por defecto para las conexiones SSL hasta nuestro middleware, la capa de autenticación mediante basic-auth y los ciphers, así como la versión que usará nuestra capa TLS.

Para la autenticación hemos utilizado el paquete apache2-utils , solicitando una clave de la siguiente forma:

htpasswd -nb admin PasswordSuperSegura
admin:$apr1$NQlSR6h1$lQnllz9cQhXHK8gFdP0yf0
# data/configurations/dynamic.yml
http:
  middlewares:
    secureHeaders:
      headers:
        sslRedirect: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000

    user-auth:
      basicAuth:
        users:
          - "admin:$apr1$NQlSR6h1$lQnllz9cQhXHK8gFdP0yf0"

tls:
  options:
    default:
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
      minVersion: VersionTLS12

Antes de terminar, debemos recordar crear la red proxy  que hemos definido en los distintos ficheros de configuración:

admin@ip-10-0-3-96:~/traefik$ docker network create proxy
bfcdd1d7fd978120d2f1589102704f944f856027ddf9995dd985b92754ff9481

Arrancando Traefik por primera vez

Y llegó el momento esperado, vamos a levantar Traefik mediante docker-compose . En nuestro caso hemos configurado un Wildcard DNS para que cualquier host del dominio canonigos.me  vaya a la IP de nuestra instancia EC2 en Amazon.

También hemos habilitado Let’s Encrypt y Traefik se encargará mediante los resolvers configurados de generar un certificado válido de forma automática para el hostname elegido, en nuestro caso traefik.canonigos.me .

# Ejecutamos el stack de docker-compose creado
admin@ip-10-0-3-96:~/traefik$ docker-compose up -d
Pulling traefik (traefik:latest)...
latest: Pulling from library/traefik
0a6724ff3fcd: Pull complete
64d0c2f48fed: Pull complete
ce56bf94d075: Pull complete
4de49a0677f6: Pull complete
Digest: sha256:dec15c406c554e6319a497003f2428f06146e15c7a08016c4565dc5a1711ecdb
Status: Downloaded newer image for traefik:latest
Creating traefik ... done

# Verificamos que está corriendo
admin@ip-10-0-3-96:~/traefik$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
807285307a14 traefik:latest "/entrypoint.sh trae…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp traefik

Para comprobar el buen funcionamiento de nuestra configuración, si accedemos a http://traefik.canonigos.me  debería redirigirnos a la url asegurada mediante el certificado. De igual forma, nos solicitará el par usuario/contraseña configurado mediante el basic-auth.

Para comprobarlo en consola, usaremos mi querido amigo httpie :

# Consultamos la url traefik.canonigos.me sin https, obtenemos solo cabeceras
# Vemos el 301 hasta https://traefik.canonigos.me
admin@ip-10-0-3-96:~/traefik$ http -h traefik.canonigos.me
HTTP/1.1 301 Moved Permanently
Content-Length: 17
Content-Type: text/plain; charset=utf-8
Date: Mon, 28 Dec 2020 19:30:13 GMT
Location: https://traefik.canonigos.me/

# Consultamos la url asegurada con certificado
# Nos devuelve un 401 Unauthorized
admin@ip-10-0-3-96:~/traefik$ http -h https://traefik.canonigos.me
HTTP/1.1 401 Unauthorized
Content-Length: 17
Content-Type: text/plain
Date: Mon, 28 Dec 2020 19:30:20 GMT
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Www-Authenticate: Basic realm="traefik"

# Consultamos la url asegurada en el path del DashBoard utilizando las credenciales de autenticación basic-auth configuradas
# Obtenemos un 200 - Bingo
admin@ip-10-0-3-96:~/traefik$ http -h -a admin:PasswordSuperSegura https://traefik.canonigos.me/dashboard/
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 3026
Content-Type: text/html; charset=utf-8
Date: Mon, 28 Dec 2020 19:37:56 GMT
Last-Modified: Thu, 17 Dec 2020 16:34:23 GMT
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Por si no te lo crees, aquí te dejo una captura del Dashboard de nuestro Traefik recién instalado.

Traefik: Qué es, cómo configurarlo y ponerlo en marcha

En el siguiente post desplegaremos un WordPress mediante Docker y lo enrutaremos automáticamente mediante labels  a través de Traefik, dotándolo de certificado de seguridad Let’s Encrypt.

¿Te ha gustado? ¡Compártelo!

Logo Trevenque

trevenque group

Ofrecemos un conjunto de servicios completos para que puedas desarrollar tu negocio, gestionar tus datos de manera inteligente y tomar decisiones rentables.

Deja un comentario

Artículos similares

Sigue de cerca la actualidad de Grupo Trevenque y las últimas tendencias tecnológicas y de Business Intelligence.

Ver todas las noticias