Cómo utilizar Traefik v2 como proxy inverso para contenedores Docker en Ubuntu 20.04

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: configuración y ejecución de Traefik
  • Paso 2: Ejecución del contenedor Traefik
  • Paso 3: Registro de contenedores con Traefik
  • Conclusión
  • El autor seleccionó a Girls Who Code para recibir una donación como parte del programa Write for DOnations.

    Introducción

    Docker puede ser una forma eficiente de ejecutar aplicaciones web en producción, pero es posible que desee ejecutar varias aplicaciones en el mismo host de Docker. En esta situación, deberá configurar un proxy inverso. Esto se debe a que solo desea exponer los puertos 80al 443resto del mundo.

    Traefik es un proxy inverso compatible con Docker que incluye un panel de control de monitoreo. Traefik v1 se ha utilizado ampliamente durante un tiempo y puedes seguir este tutorial anterior para instalar Traefik v1. Pero en este tutorial, instalarás y configurarás Traefik v2, que incluye algunas diferencias.

    La mayor diferencia entre Traefik v1 y v2 es que se eliminaron los frontends y backends y su funcionalidad combinada se distribuyó entre enrutadores, middlewares y servicios. Anteriormente, un backend se encargaba de realizar modificaciones a las solicitudes y hacer que esas solicitudes llegaran a lo que se suponía que debía manejarlas. Traefik v2 proporciona una mayor separación de preocupaciones al introducir middlewares que pueden modificar las solicitudes antes de enviarlas a un servicio. Los middlewares facilitan la especificación de un único paso de modificación que puede ser utilizado por muchas rutas diferentes para que puedan reutilizarse (como la autenticación básica HTTP, que verá más adelante). Un enrutador también puede utilizar muchos middlewares diferentes.

    En este tutorial, configurará Traefik v2 para enrutar solicitudes a dos contenedores de aplicaciones web diferentes: un contenedor de WordPress y un contenedor de Adminer, cada uno de los cuales se comunica con una base de datos MySQL. Configurará Traefik para que sirva todo a través de HTTPS usando Let's Encrypt.

    Prerrequisitos

    Para completar este tutorial, necesitará lo siguiente:

    • Un servidor Ubuntu 20.04 con un usuario sudo que no sea root y un firewall. Puedes configurarlo siguiendo nuestra guía de configuración inicial del servidor Ubuntu 20.04.
    • Docker instalado en su servidor, lo cual puede lograr siguiendo los pasos 1 y 2 de Cómo instalar y usar Docker en Ubuntu 20.04.
    • Docker Compose se instaló siguiendo las instrucciones del Paso 1 de Cómo instalar Docker Compose en Ubuntu 20.04.
    • Un dominio y tres registros A, , y . Cada uno debe apuntar a la dirección IP de su servidor. Puede aprender a apuntar dominios a Droplets de DigitalOcean leyendo la documentación de Dominios y DNS de DigitalOcean. A lo largo de este tutorial, sustituya su dominio por en los archivos de configuración y los ejemplos.db-admin.your_domainblog.your_domainmonitor.your_domainyour_domain

    Paso 1: configuración y ejecución de Traefik

    El proyecto Traefik tiene una imagen oficial de Docker, por lo que la usará para ejecutar Traefik en un contenedor Docker.

    Pero antes de poner en funcionamiento su contenedor Traefik, debe crear un archivo de configuración y configurar una contraseña cifrada para poder acceder al panel de monitoreo.

    Usarás la htpasswdutilidad para crear esta contraseña cifrada. Primero, instala la utilidad, que está incluida en el apache2-utilspaquete:

    1. sudo apt-get install apache2-utils

    Luego, genere la contraseña con htpasswd. Reemplace secure_passwordcon la contraseña que desea utilizar para el usuario administrador de Traefik:

    1. htpasswd -nb admin secure_password

    La salida del programa se verá así:

    Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

    Utilizará este resultado en el archivo de configuración de Traefik para configurar la autenticación básica HTTP para el panel de control y verificación de estado de Traefik. Copie la línea de resultado completa para poder pegarla más tarde.

    Para configurar el servidor Traefik, creará dos nuevos archivos de configuración llamados traefik.tomly traefik_dynamic.tomlutilizando el formato TOML. TOML es un lenguaje de configuración similar a los archivos INI, pero estandarizado. Estos archivos nos permiten configurar el servidor Traefik y varias integraciones, o providers, que desee utilizar. En este tutorial, utilizará tres de los proveedores disponibles de Traefik: api, dockery acme. El último de ellos, acme, admite certificados TLS mediante Let's Encrypt.

    Crea y abre traefik.tomlusando nanotu editor de texto preferido:

    1. nano traefik.toml

    Primero, debes especificar los puertos en los que Traefik debe escuchar mediante la entryPointssección de tu archivo de configuración. Necesitarás dos porque quieres escuchar en el puerto 80y 443. Llamemos a estos puertos web(puerto 80) y websecure(puerto 443).

    Agregue las siguientes configuraciones:

    traefik.toml

    [entryPoints]  [entryPoints.web]    address = ":80"    [entryPoints.web.http.redirections.entryPoint]      to = "websecure"      scheme = "https"  [entryPoints.websecure]    address = ":443"

    Tenga en cuenta que también está redirigiendo automáticamente el tráfico para que se gestione a través de TLS.

    A continuación, configure Traefik api, que le dará acceso tanto a la API como a la interfaz del panel de control. El encabezado [api]es todo lo que necesita porque el panel de control se habilita de forma predeterminada, pero será explícito por el momento.

    Añade el siguiente código:

    traefik.toml

    ...[api]  dashboard = true

    Para terminar de proteger sus solicitudes web, debe utilizar Let's Encrypt para generar certificados TLS válidos. Traefik v2 es compatible con Let's Encrypt de manera predeterminada y puede configurarlo creando un solucionador de certificados del tipo acme.

    Ahora configuremos su solucionador de certificados usando el nombre lets-encrypt:

    traefik.toml

    ...[certificatesResolvers.lets-encrypt.acme]  email = "your_email@your_domain"  storage = "acme.json"  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

    Esta sección se llama así acmeporque ACME es el nombre del protocolo que se utiliza para comunicarse con Let's Encrypt para administrar los certificados. El servicio Let's Encrypt requiere el registro con una dirección de correo electrónico válida, por lo que para que Traefik genere certificados para sus hosts, configure la emailclave con su dirección de correo electrónico. Luego, especifique que almacenará la información que recibirá de Let's Encrypt en un archivo JSON llamado acme.json.

    La acme.tlsChallengesección nos permite especificar cómo Let's Encrypt puede verificar el certificado. Lo estás configurando para que entregue un archivo como parte del desafío a través del puerto 443.

    Por último, debes configurar Traefik para que funcione con Docker.

    Agregue las siguientes configuraciones:

    traefik.toml

    ...[providers.docker]  watch = true  network = "web"

    El dockerproveedor permite que Traefik actúe como proxy frente a los contenedores Docker. Ha configurado el proveedor para watchlos nuevos contenedores en la webred que creará pronto.

    Nuestra configuración final utiliza el fileproveedor. Con Traefik v2, las configuraciones estáticas y dinámicas no se pueden combinar. Para solucionar esto, deberá traefik.tomldefinir sus configuraciones estáticas y luego guardar sus configuraciones dinámicas en otro archivo, al que llamará traefik_dynamic.toml. Aquí está utilizando el fileproveedor para indicarle a Traefik que debe leer las configuraciones dinámicas desde un archivo diferente.

    Agregue el siguiente fileproveedor:

    traefik.toml

    1. [providers.file]
    2. filename = "traefik_dynamic.toml"

    Tu finalización traefik.tomlse verá así:

    traefik.toml

    [entryPoints]  [entryPoints.web]    address = ":80"    [entryPoints.web.http.redirections.entryPoint]      to = "websecure"      scheme = "https"  [entryPoints.websecure]    address = ":443"[api]  dashboard = true[certificatesResolvers.lets-encrypt.acme]  email = "your_email@your_domain"  storage = "acme.json"  [certificatesResolvers.lets-encrypt.acme.tlsChallenge][providers.docker]  watch = true  network = "web"[providers.file]  filename = "traefik_dynamic.toml"

    Guarde y cierre el archivo.

    Ahora vamos a crear traefik_dynamic.toml.

    Los valores de configuración dinámica que debes mantener en su propio archivo son los middlewares y los enrutadores. Para poner tu panel de control detrás de una contraseña, debes personalizar el enrutador de la API y configurar un middleware para que gestione la autenticación básica HTTP. Comencemos por configurar el middleware.

    El middleware se configura por protocolo y, dado que está trabajando con HTTP, lo especificará como una sección encadenada a http.middlewares. A continuación, viene el nombre de su middleware para que pueda hacer referencia a él más tarde, seguido del tipo de middleware que es, que en este caso será basicAuth. Llamemos a su middleware simpleAuth.

    Crea y abre un nuevo archivo llamado traefik_dynamic.toml:

    1. nano traefik_dynamic.toml

    Agrega el siguiente código. Aquí es donde pegarás el resultado del htpasswdcomando:

    traefik_dynamic.toml

    [http.middlewares.simpleAuth.basicAuth]  users = [    "admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"  ]

    Para configurar el enrutador para la API, nuevamente deberá encadenar el nombre del protocolo, pero en lugar de usar http.middlewares, deberá usar http.routersseguido del nombre del enrutador. En este caso, apiproporciona su propio enrutador con nombre que puede configurar mediante la [http.routers.api]sección . Configurará el dominio que planea usar con su panel de control también configurando la ruleclave mediante una coincidencia de host, el punto de entrada que se usará websecurey los middlewares que se incluirán simpleAuth.

    Agregue las siguientes configuraciones:

    traefik_dynamic.toml

    ...[http.routers.api]  rule = "Host(`monitor.your_domain`)"  entrypoints = ["websecure"]  middlewares = ["simpleAuth"]  service = "api@internal"  [http.routers.api.tls]    certResolver = "lets-encrypt"

    El webpunto de entrada maneja el puerto 80, mientras que el websecurepunto de entrada usa el puerto 443para TLS/SSL. Redirecciona automáticamente todo el tráfico en el puerto 80al websecurepunto de entrada para forzar conexiones seguras para todas las solicitudes.

    Observe las últimas tres líneas aquí: configure a service, enable tls y configure certResolverto "lets-encrypt". Los servicios son el paso final para determinar dónde se maneja finalmente una solicitud. El api@internalservicio es un servicio integrado que se encuentra detrás de la API que usted expone. Al igual que los enrutadores y los middlewares, los servicios se pueden configurar en este archivo, pero no necesitará hacerlo para lograr el resultado deseado.

    Su traefik_dynamic.tomlarchivo completo se verá así:

    traefik_dynamic.toml

    [http.middlewares.simpleAuth.basicAuth]  users = [    "admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"  ][http.routers.api]  rule = "Host(`monitor.your_domain`)"  entrypoints = ["websecure"]  middlewares = ["simpleAuth"]  service = "api@internal"  [http.routers.api.tls]    certResolver = "lets-encrypt"

    Guarde el archivo y salga del editor.

    Con estas configuraciones establecidas, ahora iniciará Traefik.

    Paso 2: Ejecución del contenedor Traefik

    En este paso, creará una red Docker para que el proxy la comparta con los contenedores. Luego, accederá al panel de control de Traefik. La red Docker es necesaria para poder usarla con aplicaciones que se ejecutan mediante Docker Compose.

    Crea una nueva red Docker llamada web:

    1. docker network create web

    Cuando se inicia el contenedor de Traefik, lo agregará a esta red. Luego, puede agregar contenedores adicionales a esta red para que Traefik los utilice como proxy.

    A continuación, crea un archivo vacío que contendrá tu información de Let's Encrypt. Lo compartirás en el contenedor para que Traefik pueda usarlo:

    1. touch acme.json

    Traefik solo podrá usar este archivo si el usuario root dentro del contenedor tiene acceso exclusivo de lectura y escritura. Para ello, bloquee los permisos de acme.jsonmodo que solo el propietario del archivo tenga permiso de lectura y escritura.

    1. chmod 600 acme.json

    Una vez que el archivo se pasa a Docker, el propietario cambiará automáticamente al usuario root dentro del contenedor.

    Por último, crea el contenedor Traefik con este comando:

    1. docker run -d
    2. -v /var/run/docker.sock:/var/run/docker.sock
    3. -v $PWD/traefik.toml:/traefik.toml
    4. -v $PWD/traefik_dynamic.toml:/traefik_dynamic.toml
    5. -v $PWD/acme.json:/acme.json
    6. -p 80:80
    7. -p 443:443
    8. --network web
    9. --name traefik
    10. traefik:v2.2

    Este comando es un poco largo. Vamos a desglosarlo.

    Utiliza el -dindicador para ejecutar el contenedor en segundo plano como un demonio. Luego, comparte su docker.sockarchivo en el contenedor para que el proceso Traefik pueda escuchar los cambios en los contenedores. También comparte los archivos de configuración traefik.tomly traefik_dynamic.tomlen el contenedor, así como acme.json.

    A continuación, asigna los puertos :80y :443de tu host Docker a los mismos puertos en el contenedor Traefik para que Traefik reciba todo el tráfico HTTP y HTTPS al servidor.

    Establece la red del contenedor en weby nombra el contenedor como traefik.

    Por último, utiliza la traefik:v2.2imagen de este contenedor para garantizar que no estás ejecutando una versión completamente diferente de aquella para la que está escrito este tutorial.

    Una imagen de Docker ENTRYPOINTes un comando que siempre se ejecuta cuando se crea un contenedor a partir de la imagen. En este caso, el comando es el traefikbinario dentro del contenedor. Puedes pasar argumentos adicionales a ese comando cuando inicias el contenedor, pero has configurado todos los ajustes en el traefik.tomlarchivo.

    Una vez iniciado el contenedor, ahora tienes un panel al que puedes acceder para ver el estado de tus contenedores. También puedes usar este panel para visualizar los enrutadores, servicios y middlewares que Traefik ha registrado. Puedes intentar acceder al panel de monitoreo apuntando tu navegador a (el seguimiento es obligatorio).https://monitor.your_domain/dashboard//

    Se le solicitará su nombre de usuario y contraseña, que son admin y la contraseña que configuró en el Paso 1.

    Una vez que haya iniciado sesión, verá la interfaz de Traefik:

    Notarás que ya hay algunos enrutadores y servicios registrados, pero esos son los que vienen con Traefik y la configuración del enrutador que escribiste para la API.

    Ahora tienes el proxy Traefik en funcionamiento y lo has configurado para que funcione con Docker y monitoree otros contenedores. En el siguiente paso, iniciarás algunos contenedores para que Traefik los utilice como proxy.

    Paso 3: Registro de contenedores con Traefik

    Con el contenedor de Traefik en ejecución, ya está listo para ejecutar aplicaciones detrás de él. Iniciemos los siguientes contenedores detrás de Traefik:

    1. Un blog que utiliza la imagen oficial de WordPress.
    2. Un servidor de gestión de bases de datos que utiliza la imagen oficial de Adminer.

    Administrarás ambas aplicaciones con Docker Compose usando un docker-compose.ymlarchivo.

    Crea y abre el docker-compose.ymlarchivo en tu editor:

    1. nano docker-compose.yml

    Agregue las siguientes líneas al archivo para especificar la versión y las redes que utilizará:

    docker-compose.yml

    version: "3"networks:  web:    external: true  internal:    external: false

    Utiliza la versión de Docker Compose 3porque es la versión principal más nueva del formato de archivo Compose.

    Para que Traefik reconozca sus aplicaciones, deben ser parte de la misma red y, dado que creó la red manualmente, la incorpora especificando el nombre de red weby configurando externalen true. Luego, define otra red para poder conectar sus contenedores expuestos a un contenedor de base de datos que no expondrá a través de Traefik. Llamará a esta red internal.

    A continuación, definirás cada uno de tus archivos services, uno a la vez. Empecemos con el blogcontenedor, que utilizarás como base la imagen oficial de WordPress. Agrega esta configuración al final del archivo:

    docker-compose.yml

    ...services:  blog:    image: wordpress:4.9.8-apache    environment:      WORDPRESS_DB_PASSWORD:    labels:      - traefik.http.routers.blog.rule=Host(`blog.your_domain`)      - traefik.http.routers.blog.tls=true      - traefik.http.routers.blog.tls.certresolver=lets-encrypt      - traefik.port=80    networks:      - internal      - web    depends_on:      - mysql

    La environmentclave te permite especificar variables de entorno que se configurarán dentro del contenedor. Si no configuras un valor para WORDPRESS_DB_PASSWORD, le estás indicando a Docker Compose que obtenga el valor de tu shell y lo pase cuando crees el contenedor. Definirás esta variable de entorno en tu shell antes de iniciar los contenedores. De esta manera, no codificarás las contraseñas en el archivo de configuración.

    La labelssección es donde se especifican los valores de configuración para Traefik. Las etiquetas de Docker no hacen nada por sí mismas, pero Traefik las lee para saber cómo tratar los contenedores. Esto es lo que hace cada una de estas etiquetas:

    • traefik.http.routers.adminer.rule=Host(``` blog.your_domain ```)crea un nuevo enrutador para su contenedor y luego especifica la regla de enrutamiento utilizada para determinar si una solicitud coincide con este contenedor.
    • traefik.routers.custom_name.tls=trueespecifica que este enrutador debe usar TLS.
    • traefik.routers.custom_name.tls.certResolver=lets-encryptespecifica que el solucionador de certificados que creó anteriormente lets-encryptdebe usarse para obtener un certificado para esta ruta.
    • traefik.portespecifica el puerto expuesto que Traefik debe usar para enrutar el tráfico a este contenedor.

    Con esta configuración, todo el tráfico enviado a su host Docker en el puerto 80o 443con el dominio de se enrutará al contenedor.blog.your_domainblog

    Asigna este contenedor a dos redes diferentes para que Traefik pueda encontrarlo a través de la webred y pueda comunicarse con el contenedor de la base de datos a través de la internalred.

    Por último, la depends_onclave le indica a Docker Compose que este contenedor debe iniciarse después de que se ejecuten sus dependencias. Dado que WordPress necesita una base de datos para ejecutarse, debe ejecutar su mysqlcontenedor antes de iniciarlo blog.

    A continuación, configure el servicio MySQL:

    docker-compose.yml

    services:...  mysql:    image: mysql:5.7    environment:      MYSQL_ROOT_PASSWORD:    networks:      - internal    labels:      - traefik.enable=false

    Estás usando la imagen oficial de MySQL 5.7 para este contenedor. Notarás que estás usando nuevamente un environmentelemento sin un valor. Las variables MYSQL_ROOT_PASSWORDy WORDPRESS_DB_PASSWORDdeberán configurarse con el mismo valor para asegurarte de que tu contenedor de WordPress pueda comunicarse con MySQL. No quieres exponer el mysqlcontenedor a Traefik ni al mundo exterior, por lo que solo estás asignando este contenedor a la internalred. Dado que Traefik tiene acceso al socket de Docker, el proceso aún expondrá un enrutador para el mysqlcontenedor de manera predeterminada, por lo que agregarás la etiqueta traefik.enable=falsepara especificar que Traefik no debe exponer este contenedor.

    Por último, defina el contenedor Adminer:

    docker-compose.yml

    services:...  adminer:    image: adminer:4.6.3-standalone    labels:      - traefik.http.routers.adminer.rule=Host(`db-admin.your_domain`)      - traefik.http.routers.adminer.tls=true      - traefik.http.routers.adminer.tls.certresolver=lets-encrypt      - traefik.port=8080    networks:      - internal      - web    depends_on:      - mysql

    Este contenedor se basa en la imagen oficial de Adminer. La configuración networky depends_onel tamaño de este contenedor coinciden exactamente con lo que estás usando para blogél.

    La línea le indica a Traefik que examine el host solicitado. Si coincide con el patrón de , Traefik enrutará el tráfico al contenedor a través del puerto .traefik.http.routers.adminer.rule=Host(``` db-admin.your_domain ```)db-admin.your_domainadminer8080

    Su docker-compose.ymlarchivo completo se verá así:

    docker-compose.yml

    version: "3"networks:  web:    external: true  internal:    external: falseservices:  blog:    image: wordpress:4.9.8-apache    environment:      WORDPRESS_DB_PASSWORD:    labels:      - traefik.http.routers.blog.rule=Host(`blog.your_domain`)      - traefik.http.routers.blog.tls=true      - traefik.http.routers.blog.tls.certresolver=lets-encrypt      - traefik.port=80    networks:      - internal      - web    depends_on:      - mysql  mysql:    image: mysql:5.7    environment:      MYSQL_ROOT_PASSWORD:    networks:      - internal    labels:      - traefik.enable=false  adminer:    image: adminer:4.6.3-standalone    labels:    labels:      - traefik.http.routers.adminer.rule=Host(`db-admin.your_domain`)      - traefik.http.routers.adminer.tls=true      - traefik.http.routers.adminer.tls.certresolver=lets-encrypt      - traefik.port=8080    networks:      - internal      - web    depends_on:      - mysql

    Guarde el archivo y salga del editor de texto.

    A continuación, establezca valores en su shell para las variables WORDPRESS_DB_PASSWORDy :MYSQL_ROOT_PASSWORD

    1. export WORDPRESS_DB_PASSWORD=secure_database_password
    2. export MYSQL_ROOT_PASSWORD=secure_database_password

    Sustitúyala secure_database_passwordpor la contraseña de base de datos que desee. Recuerde utilizar la misma contraseña para WORDPRESS_DB_PASSWORDy MYSQL_ROOT_PASSWORD.

    Con estas variables configuradas, ejecute los contenedores usando docker-compose:

    1. docker-compose up -d

    Ahora observe el panel de administración de Traefik mientras se completa.

    Si explora la sección Routers encontrará routers habilitados adminery blogconfigurados con TLS:

    Vaya a , sustituyendo por su dominio. Se lo redireccionará a una conexión TLS y ahora podrá completar la configuración de WordPress:blog.your_domainyour_domain

    Ahora, acceda a Adminer desde su navegador y, nuevamente, sustituya el nombre de su dominio. El contenedor no está expuesto al mundo exterior, pero tiene acceso a él a través de la red Docker que comparten y usa el nombre del contenedor como nombre de host.db-admin.your_domainyour_domainmysqladminerinternalmysql

    En la pantalla de inicio de sesión de administrador, ingrese rooten Nombre de usuario , ingrese mysqlen Servidor e ingrese el valor que estableció MYSQL_ROOT_PASSWORDen Contraseña . Deje Base de datos vacía. Ahora presione Iniciar sesión .

    Una vez que haya iniciado sesión, verá la interfaz de usuario de administrador.

    Ambos sitios ya están funcionando y puedes usar el panel de control para vigilar tus aplicaciones.monitor.your_domain

    Conclusión

    En este tutorial, configuró Traefik v2 para enviar solicitudes a otras aplicaciones en contenedores Docker.

    La configuración declarativa de Traefik a nivel de contenedor de aplicaciones facilita la configuración de más servicios y no es necesario reiniciar el traefikcontenedor cuando se agregan nuevas aplicaciones al proxy de tráfico, ya que Traefik nota los cambios inmediatamente a través del archivo de socket de Docker que está monitoreando.

    Para obtener más información sobre lo que puede hacer con Traefik v2, consulte la documentación oficial de Traefik.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

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

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion