Conseguir imagenes en docker hub desde la terminal
Instalar git en ubuntu

Desplegar con docker-compose los servicios Traefik y Portainer

Vamos a configurar un proxy inverso Traefik v2 junto con Portainer, utilizando Docker Compose. Esta configuración hace que la gestión y el despliegue de contenedores sea muy ágil. El proxy inverso permite ejecutar múltiples aplicaciones en un host Docker. Así que reduce la sobrecarga general que normalmente iría junto con la ejecución de múltiples aplicaciones Docker, ya que todo se gestiona desde un punto.

Traefik dirigirá todo el tráfico entrante a los contenedores Docker apropiados . A través de la aplicación de código abierto Portainer puedes acelerar los despliegues de software, solucionar problemas y simplificar las migraciones.

Como ejemplo final, se deplegará una aplicación Node.js en contenedores en nuestro nuevo entorno.

Requisitos previos

  • Servidor Ubuntu 20.04
  • Docker y Docker-Compose instalados
  • Nombre del dominio

Traefik

Traefik es un proxy inverso y equilibrador de carga moderno y ligero que hace que el despliegue de microservicios sea muy fácil. Está diseñado para ser lo más simple posible de operar, pero capaz de manejar despliegues grandes y altamente complejos.

También viene con un potente conjunto de middlewares, un software que se sitúa entre un sistema operativo y las aplicaciones que se ejecutan en él, que mejoran sus capacidades para incluir el equilibrio de carga, la puerta de enlace de la API, la entrada del orquestador, así como la comunicación de servicios de este a oeste y más. Está escrito en Go y está empaquetado como un único archivo binario y disponible como una pequeña imagen docker oficial.

Los proxies inversos tradicionales requieren que configures cada ruta que conectará rutas y subdominios a cada microservicio. En un entorno en el que añades, eliminas, actualizas o escalas tus servicios muchas veces al día, la tarea de mantener las rutas actualizadas se vuelve tediosa.

Traefik escucha el registro de servicios/orquestador API y genera instantáneamente las rutas para que tus microservicios estén conectados con el mundo exterior – sin más intervención por tu parte.

Algunas de las características de Traefik:

  • Enrutamiento dinámico: Una vez configurado correctamente, Traefik añadirá dinámicamente nuevos servicios y contenedores a medida que surjan para proporcionar el enrutamiento del tráfico hacia ellos. Digamos que tienes Traefik en funcionamiento y quieres añadir una nueva aplicación, sólo tienes que construir tu contenedor y registrar un nuevo endpoint y Traefik lo detectará automáticamente y empezará a enrutar su tráfico.
  • Balanceador de carga: Si tienes varias instancias de un contenedor, entonces Traefik puede proporcionar el equilibrio de carga entre esas instancias.
  • Encriptación: Cuando se configura correctamente, Traefik no sólo puede enrutar el tráfico a un servicio recién descubierto, sino también configurar certificados SSL gratuitos de Let’s Encrypt. Después puede redirigir todo el tráfico http a https a través de middlewares para mejorar la seguridad.
  • Interfaz web: Viene con un panel de control de gestión muy útil que ayuda a visualizar todos los puntos finales de tráfico, servicios, middlewares y contenedores docker, mientras que muestra las advertencias y errores potenciales también.

Portainer

Portainer es una interfaz de usuario de gestión ligera que le permite gestionar fácilmente un host Docker o clúster Swarm.

Está pensado para ser tan sencillo de desplegar como de utilizar. Consiste en un único contenedor que puede ejecutarse en cualquier motor Docker. Permite gestionar pilas Docker, contenedores, imágenes, volúmenes, redes y mucho más. Esto ayuda a acelerar los despliegues de software, solucionar problemas y simplificar las migraciones.

Portainer funciona ocultando la complejidad que dificulta la gestión de contenedores detrás de una interfaz gráfica de usuario fácil de usar. Al negar la necesidad de que los usuarios usen CLI, que escriban YAML o que entiendan los manifiestos, Portainer hace que el despliegue de aplicaciones y la resolución de problemas sea tan simple que cualquiera puede hacerlo.

Primeros pasos

Para los requisitos se puede instalar un droplet de 5 dólares muy fácilmente en Digital Ocean. Si te registras a través de este enlace (https://m.do.co/c/98c9ca613f37) consigues 100 dólares de crédito gratis.

Paso 1 – Configuración de los registros DNS

Lo primero que hay que hacer es configurar los dominios apropiados para poder acceder a Portainer y al panel de control de Traefik. Deben apuntar al servidor. Por ejemplo:

traefik.sudominio.com
portainer.sudominio.com

De esta manera el dashboard de Portainer y Traefik estará disponible en los subdominios correspondientes.

Paso 2 – Creando un usuario y configurando el directorio

Siempre se debe evitar el uso de root. Para ello se registra un usuario nuevo y se le agrega al grupo sudo y luego se cambia la sesión a este usuario:

adduser userdocker
usermod -aG sudo userdocker
su - userdocker

Ahora es el momento de configurar el directorio que usaremos. Está publicada en un repositorio git con lo que se puede simplemente clonar o hacer un fork del repo:

 git clone https://github.com/rafrasenberg/docker-traefik-portainer .

Usando el comando cd con la terminal y entrando en src se puede ver esta estructura de árbol:

.
└── src/
├── core/
│ ├── traefik-data/
│ ├── configuraciones/
│ │ └── dynamic.yml
│ │ ├── traefik.yml
│ │ └── acme.json
│ └── docker-compose.yml
└── apps/

Explicación de los archivos

traefik.yml

Se trata de la configuración estática y base de Traefik.

Primero le decimos a Traefik que queremos la interfaz gráfica de la web estableciendo dashboard:true

Después definimos nuestros dos entrypoints web (http) y websecure (https). Para el endpoint https se configura el certResolver para tener los certificados automáticos de Let’s Encrypt. A continuación se carga el middleware adecuado para que todo el tráfico sea reenviado a https.

En la parte de providers se especifica que este archivo será pasado a un contenedor docker usando bind mount. También se indica a Traefik que encuentre nuestra configuración dinámica en configurations/dynamic.yml. Y por último está la configuración para resolver certificados SSL.

# traefik.yml
api:
dashboard: true

entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure

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

providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /configurations/dynamic.yml

certificatesResolvers:
letsencrypt:
acme:
email: manu@tudominio.es
storage: acme.json
keyType: EC384
httpChallenge:
entryPoint: web

Nota: Configurar un correo electrónico en este archivo para la renovación de Let’s Encrypt. Podría arrojar un error cuando quiera ejecutar su contenedor docker.

dynamic.yml

Este archivo contiene los middlewares para asegurar que todo el tráfico es totalmente seguro y se ejecuta sobre TLS. También se establece aquí la autentificación básica para el panel de control de Traefik, ya que por defecto es accesible para todo el mundo.

El archivo es totalmente dinámico y puede ser editado sobre la marcha, sin reiniciar nuestro contenedor.

# dynamic.yml
http:
middlewares:
secureHeaders:
headers:
sslRedirect: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000

user-auth:
basicAuth:
users:
- "userdocker:$apr1$MTqfVdtTiE$65kzT5ERfFqwH9f3uipxA1"
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

docker-compose.yml

Este es el archivo más importante, donde ocurre la magía. La belleza de Traefik es que una vez hecha la configuración inicial, el despliegue de nuevos contenedores es muy fácil. Funciona especificando labels para cada contenedor.

# docker-compose.yml
version: "3"

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

portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./portainer-data:/data
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.portainer-secure.entrypoints=websecure"
- "traefik.http.routers.portainer-secure.rule=Host(`portainer.yourdomain.com`)"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"

networks:
proxy:
external: true

Para cada contenedor que Traefik deba manejar se añaden labels para que Traefik sepa a dónde debe dirigirlo. Así que mirado este archivo se puede comprobar rápidamente lo que está pasando en el contenedor traefik.

La primera etiqueta es la que le dice a Traefik que debe enrutar este contenedor porque especificamos enable=true. Esto es el resultado de la configuración en el archivo estático traefik.yml donde explícitamente se indica exposedByDefault: false por lo que se tiene que especificar así.

La segunda etiqueta indica que se debe utilizar el proxy de red, el cual se creará más adelante. Después de eso se le dice a Traefik que use el endpoint websecure (https). Luego se especifica el nombre del host con el dominio apropiado.

La penúltima etiqueta especifica el manejador de la API. Expone información como la configuración de todos los routers, servicios, middlewares, etc. Para ver todos los endpoints disponibles se puede consultar la documentación aquí: https://doc.traefik.io/traefik/v2.3/operations/api/#endpoints

La última etiqueta es el middleware básico de autentificación, porque el dashboard de Traefik está expuesto por defecto, así que se añade una capa de seguridad básica sobre él. También protegerá la API.

labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.traefik-secure.entrypoints=websecure"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik-secure.service=api@internal"
- "traefik.http.routers.traefik-secure.middlewares=user-auth@file"

Últimos preparativos y ejecución de la pila

Paso 1 – Creando las credenciales

Lo primero que se debe hacer es generar la contraseña para el auth básico que se almacenará en el archivo dynamic.yml. Estas credenciales son necesarias para iniciar sesión en la Web UI de Traefik y protegerá la API.

El servidor debe tener instalado htpasswd. Si no lo tiene se puede hacer con el siguiente comando:

sudo apt install apache-utils

A continuación, se ejecuta el siguiente comando, sustituyendo el nombre de usuario y la contraseña por el que se quiera utilizar.

echo $(htpasswd -nb  <contraseña>)

Se edita el archivo dynamic.yml añadiendo la cadena de autentificación bajo el middleware user-auth.

Paso 2 – Creación de la red proxy

Es necesario crear una nueva red Docker que permita el tráfico exterior. Esta debe llamarse proxy como se especifica en el archivo docker-compose.yml. Para crear una red Docker se utiliza el siguiente comando:

docker network create proxy

Paso 3 – Edición de los nombres de dominio

En el archivo docker-compose.yml se tiene que reemplazar los valores de los dominios en las etiquetas de Traefik por los dominios que se van a utilizar en cada servicio:

traefik.sudominio.com
portainer.sudominio.com

Paso 4 – Dar los permisos adecuados a acme.json

Por defecto el archivo acme.json tiene el permiso establecido en 644, esto dará lugar a un error al ejecutar docker-compose. Los permisos correctos son 600. Con lo que nos situamos con el comando cd en la carpeta core y se ejecuta el siguiente comando:

sudo chmod 600 ./traefik-config/acme.json

Paso 5 – Ejecutar la pila

Ahora es el momento de ejecutar la pila. Se tiene que estar ubicado con el prompt en la carpeta core para que docker pueda encontrar el archivo docker-compose. En la primera ejecución es recomendable usar el comando si el parámetro –detach (segundo plano) para poder ver los errores si los hubiese:

sudo docker-compose up

En este momento deberían estar disponibles las aplicaciones los subdominios traefik.sudominio.com y portainer.sudominio.com. Si se considera que todo ha salido bien y los contenedores están funcionando correctamente, se deberá deshacer todo y ejecutar de nuevo en segundo plano con la opción -d:

sudo docker-compose down && sudo docker-compose up -d

Añadiendo aplicaciones docker al servidor

Ahora el entorno está configurado, para ejemplo del despliegue de contenedores a la configuración de Traefik seguimos los siguientes pasos.

Paso 1 – Configuración DNS

Se registra el dominio que se quiera usar para la aplicación. Por ejemplo wiki.tudominio.es.

Paso 2 – Se descarga la aplicación

En este caso extraemos el docker-compose del siguiente enlace: https://github.com/linuxserver/docker-wikijs

Paso 3 – Se adapta el archivo docker-compose

version: "2.1"
services:
wikijs:
image: lscr.io/linuxserver/wikijs
container_name: wikijs
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
volumes:
- ./config:/config
- ./data:/data
restart: unless-stopped
networks:
- proxy
- default
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.app-secure.entrypoints=websecure"
- "traefik.http.routers.app-secure.rule=Host(`wiki.tudominio.es`)"

networks:
proxy:
external: true

Lo primero que se debe hacer es eliminar la sección de puertos, ya que Traefik se encargará de ello. Para toda la configuración de Traefik sólo hay que añadir 4 etiquetas:

labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.app-secure.entrypoints=websecure"
- "traefik.http.routers.app-secure.rule=Host(`wiki.tudominio.es`)"

Primero se habilita el contenedor con enable=true, luego se añade a la red proxy. Después se especifica los routers y los puntos de entrada.

Hay que tener en cuenta que esta parte: traefik.http.router.app-secure debe tener una identificación de router única. Hay que asegurarse de que no se ha usado ese nombre todavía. Por ejemplo, para desplegar exactamente la misma aplicación en un dominio y una instancia de contenedor diferentes, se podría usar esta etiqueta: traefik.http.router.app1-secure.

En la última parte del archivo docker-compose.yml se necesita especificar las redes.

Paso 4 – ejecutar docker-compose

sudo docker-compose up -d

Más apuntes

Invítame a un café con bitcoins:
1QESjZDPxWtZ9sj3v5tvgfFn3ks13AxWVZ

Bitcoins para café
También puedes invitarme a algo para mojar...

Deja una respuesta

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

Rellena este campo
Rellena este campo
Por favor, introduce una dirección de correo electrónico válida.
Tienes que aprobar los términos para continuar