Problema
En muchos homelabs y pequeñas infraestructuras el objetivo es mantener varios servicios críticos (proxy inverso, DNS interno, autenticación, monitorización) siempre disponibles sin complicar la arquitectura. La combinación de un clúster Proxmox, contenedores LXC y una red plana suele generar puntos únicos de falla: la pérdida del nodo que aloja Traefik corta el acceso externo, la caída del servidor DNS rompe la resolución interna y la falta de sincronización de configuraciones genera divergencias que obligan a intervenciones manuales. El patrón recurrente es “servicios críticos sin alta disponibilidad ni replicación de configuración”, lo que lleva a interrupciones inesperadas y a una carga operativa innecesaria.
Causa
- Dependencia de un único nodo – Cuando Traefik, Keepalived o la base de datos de Authelia se ejecutan en un solo host, cualquier caída del hardware o del hypervisor deja el servicio inoperativo.
- Sincronización manual – Copiar archivos de configuración entre nodos a mano o mediante scripts ad‑hoc genera versiones desalineadas y errores de sintaxis que solo se detectan en producción.
- Falta de VIP gestionado – Usar una IP estática sin un mecanismo de conmutación (VRRP) impide que otro nodo asuma la dirección en caso de fallo.
- Red plana sin segmentación – Sin VLANs o subredes dedicadas, el tráfico de gestión y el de datos compiten por ancho de banda y pueden saturar el switch, provocando latencias que afectan a los servicios de monitorización.
- Encriptación parcial – Conexiones SSH sin claves dedicadas o sin restricciones de host pueden ser vulnerables a ataques de replay, especialmente cuando se usan para replicar configuraciones sensibles.
Solución
Una arquitectura basada en VIP + Keepalived, replicación de archivos con Lsyncd y contenedores LXC gestionados por Portainer cubre la mayoría de los escenarios. El flujo es:
- Crear una IP virtual (VIP) gestionada por Keepalived en al menos dos nodos del clúster. Keepalived usa VRRP para anunciar la VIP y realiza un failover automático mediante Gratuitous ARP.
- Instalar Lsyncd en los mismos nodos y configurar una sincronización unidireccional o bidireccional de los directorios de configuración (por ejemplo
/etc/traefik,/etc/technitium,/var/lib/authelia). Lsyncd utiliza rsync bajo el hood y mantiene la consistencia casi en tiempo real. - Ejecutar los servicios críticos dentro de contenedores LXC y montar los volúmenes sincronizados. Al iniciar el contenedor en cualquier nodo, leerá la configuración más reciente sin intervención manual.
- Mantener la red segmentada: crear una VLAN para tráfico de gestión (ej. 192.168.10.0/24) y otra para tráfico de datos (192.168.20.0/24). El Netgear switch soporta 802.1Q, lo que permite aislar el tráfico de Keepalived/SSH del tráfico de NFS y streaming.
- Asegurar la replicación: generar pares de claves ed25519 sin passphrase, restringir el acceso en
authorized_keysa la IP del nodo vecino y usarStrictModes yes. - Monitorear con Prometheus + Loki: exponer métricas de Keepalived (
keepalived_exporter) y de Lsyncd (lsyncd_exporter) para detectar retrasos de sincronización o fallos de VIP.
Keepalived (VIP y VRRP)
Mantener la VIP en los nodos que ejecutan los contenedores críticos. La prioridad determina cuál es el master. Un ejemplo mínimo:
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 150 # nodo master = 200, backup = 150
advert_int 1
authentication {
auth_type PASS
auth_pass secret123
}
virtual_ipaddress {
192.168.1.250/24 dev eth0 label eth0:vip
}
}
Lsyncd (replicación de configuración)
Configurar Lsyncd para sincronizar /etc/traefik y /etc/technitium desde el nodo master al backup:
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
nodaemon = false,
}
sync {
default.rsync,
source = "/etc/traefik",
target = "[email protected]::/etc/traefik",
rsync = {
archive = true,
compress = true,
verbose = true,
_extra = {"--delete"},
}
}
sync {
default.rsync,
source = "/etc/technitium",
target = "[email protected]::/etc/technitium",
rsync = {
archive = true,
compress = true,
verbose = true,
_extra = {"--delete"},
}
}
Contenedores LXC
Definir los contenedores con pct y montar los directorios sincronizados como volúmenes bind:
pct create 101 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.gz \
-hostname traefik -net0 name=eth0,bridge=vmbr0,ip=dhcp \
-mp0 /etc/traefik,mp=/etc/traefik,backup=0 \
-features nesting=1
pct start 101
Repetir para DNS, Authelia y demás servicios. Al iniciar en el nodo backup, la configuración ya está presente gracias a Lsyncd.
Cuándo aplicar esta solución
- Síntomas: pérdida de acceso externo tras reinicio de un nodo, errores de resolución DNS internos, divergencia de archivos de configuración entre nodos.
- Entorno: clúster Proxmox con al menos dos nodos, servicios críticos en contenedores LXC, red con capacidad VLAN.
- No aplica: infraestructuras que ya usan soluciones de orquestación completas (Kubernetes, Docker Swarm) con controladores de ingreso nativos, o entornos donde la carga es tan baja que la complejidad de HA no justifica el esfuerzo.
Código
# Instalar Keepalived y Lsyncd en ambos nodos (Debian/Ubuntu)
apt update && apt install -y keepalived lsyncd
# Copiar configuraciones
scp keepalived.conf root@backup:/etc/keepalived/keepalived.conf
scp lsyncd.conf.lua root@backup:/etc/lsyncd/lsyncd.conf.lua
# Habilitar y arrancar servicios
systemctl enable keepalived && systemctl start keepalived
systemctl enable lsyncd && systemctl start lsyncd
# Verificar que la VIP está asignada
ip addr show dev eth0 | grep 192.168.1.250
Verificación
- VIP activa:
ip a show dev eth0debe listar192.168.1.250. - Failover: apagar el nodo master (
systemctl stop keepalivedo apagar la máquina). Después de 2‑3 segundos, la VIP debe aparecer en el backup (ip aen el nodo secundario). - Sincronización: modificar
/etc/traefik/traefik.ymlen el master, esperar <5 s y comprobar que el mismo archivo se actualiza en el backup (diffentre los dos). - Contenedores: reiniciar el contenedor LXC en el nodo backup y confirmar que Traefik arranca sin errores de configuración.
- Métricas: en Prometheus, buscar
keepalived_stateylsyncd_sync_status. Los valores deben sermaster/backupyuprespectivamente.
Notas adicionales
- Tiempo de convergencia: Keepalived usa
advert_int 1, lo que permite un failover en ~2 s. Ajustar según tolerancia a interrupciones. - Rsync sobre SSH: la configuración anterior usa el modo daemon (
::). Si prefieres SSH, cambiatargeta[email protected]:/etc/traefiky añade la opciónssh = { port = 22 }dentro del bloquersync. - Backup de la VIP: en entornos con más de dos nodos, asigna prioridades diferentes para crear un árbol de failover (master → secondary → tertiary).
- Seguridad de claves: revoca y regenera las claves ed25519 cada 6‑12 meses; usa
ssh-keygen -t ed25519 -C "keepalived-sync"y distribúyelas conssh-copy-id. - Logs: Lsyncd escribe en
/var/log/lsyncd/lsyncd.log. Configura Loki para recoger este archivo y crear alertas cuando el número de errores supere un umbral. - Escalabilidad: si añades más nodos al clúster, simplemente replica la configuración de Keepalived y Lsyncd; no es necesario reescribir los contenedores LXC.
Con este patrón, la mayoría de los servicios críticos de un homelab quedan protegidos contra fallos de nodo, la configuración se mantiene coherente y la conmutación es prácticamente transparente para los usuarios.