Problema
En entornos donde coexisten Docker Swarm y Kubernetes, a menudo surge la necesidad de que contenedores de Swarm consuman servicios expuestos por pods de K8s (y viceversa). Cada orquestador crea su propio overlay de red, su propio DNS interno y, por defecto, no comparten rutas. Cuando los clústers están en redes distintas o en diferentes centros de datos, la comunicación se corta a menos que se establezca una capa de red externa que los una. El patrón típico es: “un micro‑servicio legado sigue en Swarm, pero la nueva funcionalidad está en K8s; ambos deben hablar sin re‑escribir código”.
Causa
- Aislamiento de redes overlay – Swarm usa
ingressyoverlaycon CIDR internos, mientras que Kubernetes empleapodCIDRyserviceCIDR. Sin una ruta común, los paquetes nunca llegan al destino. - Descubrimiento de servicios – Swarm resuelve nombres mediante su propio DNS interno; K8s usa
kube-dns. Un contenedor Swarm no conoce los nombresmyservice.namespace.svc.cluster.local. - Políticas de firewall y NAT – Los nodos suelen estar detrás de firewalls que bloquean tráfico entre rangos privados.
- Superposición de CIDR – Si los rangos de pod y overlay se solapan, los routers eligen la ruta equivocada y el tráfico se pierde.
- Falta de ruta estática – Incluso con puertos expuestos, sin una ruta que lleve el tráfico al nodo correcto, la conexión falla.
Solución
Utilizar una VPN para crear una red de capa 3 compartida entre ambos clústers. La VPN actúa como un “router virtual” que:
- asigna un rango de IP único para todos los nodos (ej.
10.200.0.0/16); - transporta tráfico de Swarm a K8s y viceversa sin depender de los overlay internos;
- permite usar los nombres DNS de K8s mediante
CoreDNSo entradas estáticas.
Enfoque general
- Seleccionar la tecnología VPN – WireGuard es ligero, fácil de configurar y ofrece mejor rendimiento que OpenVPN; sin embargo, OpenVPN sigue siendo útil cuando se necesita compatibilidad con clientes antiguos.
- Desplegar un servidor VPN – Puede ser una VM o un contenedor dedicado. El servidor mantiene la interfaz
wg0(otun0para OpenVPN) y distribuye la subred VPN a todos los nodos. - Instalar el cliente VPN en cada nodo – Tanto los workers de Swarm como los masters/agents de K8s deben ejecutar el cliente y añadir la subred VPN a su tabla de rutas.
- Configurar rutas y NAT – Cada nodo debe reenviar tráfico entre su red local y la VPN. En la mayoría de los casos basta con habilitar
net.ipv4.ip_forward=1y añadir reglasiptables -t nat -A POSTROUTING -o <iface> -j MASQUERADE. - Exponer servicios de K8s – Para que Swarm pueda resolver y alcanzar un pod, es más sencillo usar
NodePortoLoadBalancer(con MetalLB) y apuntar al IP del nodo VPN. Alternativamente, habilitarClusterIP+CoreDNSsobre la VPN permite resolución directa. - Validar conectividad – Ping desde un contenedor Swarm a la IP del pod o al nombre DNS de K8s; probar
curlal endpoint expuesto.
WireGuard paso a paso (recomendado)
- Instalar WireGuard en todos los hosts (
apt-get install wireguardoyum install wireguard-tools). - Generar claves en el servidor y en cada cliente.
- Crear archivo de configuración del servidor (
/etc/wireguard/wg0.conf) con la subred VPN y la lista de peers. - Crear archivo de configuración del cliente en cada nodo, apuntando al endpoint del servidor y definiendo
AllowedIPs = 10.200.0.0/16. - Levantar la interfaz con
wg-quick up wg0. - Añadir rutas si el nodo tiene varias interfaces (
ip route add 10.200.0.0/16 dev wg0). - Habilitar reenvío (
sysctl -w net.ipv4.ip_forward=1).
OpenVPN alternativa
- Instalar
openvpnyeasy-rsa. - Generar PKI (CA, server cert, client certs).
- Configurar
server.confconpush "route 10.200.0.0 255.255.0.0"yclient-to-client. - Iniciar el daemon y conectar cada nodo con su archivo
.ovpn. - Verificar que la subred VPN se propague a todos los clientes.
Cuándo aplicar esta solución
- Entornos híbridos donde al menos un clúster no puede migrarse inmediatamente a la otra plataforma.
- Servicios legacy que deben seguir funcionando mientras se adoptan micro‑servicios en K8s.
- Redes aisladas (VPCs, data centers) sin conectividad directa entre los rangos de IP internos.
- Necesidad de DNS unificado – cuando se quiere que los contenedores Swarm resuelvan nombres de K8s sin modificar código.
No es la mejor opción si:
- Ambos clústers están dentro del mismo VPC y pueden compartir rutas mediante VPC peering o Cloud Router.
- Se dispone de una solución de service mesh (Istio, Linkerd) que ya cubre la malla de servicios.
- El rendimiento de la VPN se vuelve un cuello de botella (cargas extremadamente altas pueden requerir una solución de capa 2 como Calico BGP).
Código
# 1. Instalar WireGuard
apt-get update && apt-get install -y wireguard
# 2. Generar claves en el servidor
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
# 3. Configuración del servidor (wg0.conf)
cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.200.0.1/16
ListenPort = 51820
PrivateKey = $(cat /etc/wireguard/server_private.key)
SaveConfig = true
# Peers – añadir una sección por nodo Swarm/K8s
# Ejemplo nodo1
[Peer]
PublicKey = <PUBLIC_KEY_NODO1>
AllowedIPs = 10.200.0.2/32
EOF
# 4. Habilitar reenvío y NAT
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 5. Levantar la interfaz
wg-quick up wg0
# 6. Cliente (en cada nodo)
wg genkey | tee client_private.key | wg pubkey > client_public.key
cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.200.0.2/32
PrivateKey = $(cat client_private.key)
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = <SERVER_IP>:51820
AllowedIPs = 10.200.0.0/16
PersistentKeepalive = 25
EOF
wg-quick up wg0
Verificación
- Desde un contenedor Swarm, ejecutar
ping 10.200.0.10(IP de un pod K8s) y confirmar respuesta. curl http://10.200.0.10:8080/healthzpara validar que el endpoint responde.- En un pod K8s,
nslookup myservice.swarm.local(si se configuró DNS estático) ocurl http://10.200.0.20:5000(IP del contenedor Swarm). - Revisar la tabla de peers con
wg showy asegurarse de que el tráfico entrante y saliente tenga bytes transferidos.
Notas adicionales
- CIDR único – antes de lanzar la VPN, verifica que ni Swarm ni K8s usen rangos que colisionen con
10.200.0.0/16. Cambia la subred si es necesario. - MTU – WireGuard funciona mejor con MTU 1420 en enlaces VPN; ajusta
MTU = 1420enwg0.confsi aparecen paquetes fragmentados. - Persistencia de claves – guarda los archivos de claves fuera del directorio del contenedor y usa volúmenes para evitar que se pierdan al reiniciar.
- Monitorización – exporta métricas de
wga Prometheus (wg_exporter) para detectar caídas de túnel. - Escalado – para clústers con decenas de nodos, considera usar un modelo hub‑spoke: un servidor central y varios servidores regionales que se peeren entre sí.