Estoy buscando ayuda para depurar la siguiente configuración:
Tengo 3 instancias de VP Cloud de una empresa de hosting. (Creo que los VPS son VMWare pero no puedo encontrar ninguna documentación en el sitio de las empresas anfitrionas).
- Todos ejecutan Ubuntu 18.04.
- He instalado Docker en los 3.
Todas las versiones de Docker son iguales:
Client: Docker Engine - Community
Version: 19.03.5
API version: 1.40
Go version: go1.12.12
Git commit: 633a0ea838
Built: Wed Nov 13 07:29:52 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.5
API version: 1.40 (minimum version 1.12)
Go version: go1.12.12
Git commit: 633a0ea838
Built: Wed Nov 13 07:28:22 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.4
GitCommit: e6b3f5632f50dbc4e9cb6288d911bf4f5e95b18e
runc:
Version: 1.0.0-rc6+dev
GitCommit: 6635b4f0c6af3810594d2770f662f34ddc15b40d
docker-init:
Version: 0.18.0
GitCommit: fec3683
En un nodo 1 ejecuté el siguiente comando de inicio:
docker swarm init --advertise-addr NODE_1_IP --data-path-port=7789
Y en los nodos 2 y 3 ejecuté los siguientes comandos de unión
docker swarm join --token XXX -advertise-addr NODE_2/3_IP NODE_1_IP:2377
El token se toma del valor que me dio el Nodo 1. Resolví un problema anterior especificando puerto-ruta-datos. Creo que esto se debe a que los VPS son VMWare y entran en conflicto con el puerto de datos estándar.
Mi proveedor de nube me proporciona una interfaz de usuario para aplicar reglas de firewall a VPS individuales. He utilizado un grupo de firewall para aplicar las siguientes reglas a los 3 servidores:
TCP ACCEPT to dest ports 80, 443, (and my SSH port)
ICMP ACCEPT any
TCP ACCEPT 2376
TCP, UDP ACCEPT 7789
UDP ACCEPT 7789
TCP ACCEPT 2377
ESP ACCEPT
Para probar esto ejecuté los siguientes comandos en el nodo 1
docker network create --driver=overlay --attachable testnet
docker network create --opt encrypted --driver=overlay --attachable testnet_encrypted
docker service create --network=testnet --name web --publish 80 --replicas=5 nginx:latest
Una vez que el servicio se ejecuta en el clúster, hago lo siguiente:
docker run --rm --name alpine --net=testnet -ti alpine:latest sh
apk add --no-cache curl
Luego hago rizos 5 veces:
curl web
Las 5 veces recibo una respuesta. Si sigo adelante, sigo recibiendo respuestas. Creo que esto significa que todos los contenedores están recibiendo tráfico.
Luego cambio el servidor a la red cifrada y repito la misma prueba:
docker service rm web
docker service create --network=testnet_encrypted --name web --publish 80 --replicas=5 nginx:latest
docker run --rm --name alpine --net=testnet_encrypted -ti alpine:latest sh
apk add --no-cache curl
Nuevamente ejecuto curl 5 veces:
curl web
A veces funcionará y otras veces simplemente se quedará ahí y se colgará hasta que presione Ctrl-C.
Si lo ejecuto un múltiplo de 5 veces el patrón de trabajo y repeticiones rotas. Creo que esto se debe a que algunos contenedores se están ejecutando en el NODO_1 y funcionan, pero la comunicación con los nodos 2 y 3 no funciona.
La regla ESP ACCEPT se agregó al conjunto de reglas de firewall de mi proveedor de nube después de investigar un poco el problema.
Intenté reiniciar el clúster pero no tuve suerte.
Ahora estoy estancado. ¿Hay alguna recomendación sobre cómo puedo proceder con la depuración? gracias roberto
Actualización 1
Para depurar, cambié la prueba para que el servicio web solo se ejecutara en una única instancia en NODE_3. Luego cargué dos consolas para el nodo 3 y ejecuté los siguientes comandos:
sudo tcpdump src NODE_1_IP and dst NODE_3_IP and port 7789
sudo tcpdump src NODE_3_IP and dst NODE_1_IP and port 7789
Una consola me mostrará el tráfico hacia el NODE_3 y la otra el tráfico que sale del NODE_3.
Luego volví a ejecutar la prueba sin cifrar. Veo que aparecen alrededor de 7 líneas en la consola entrante y 5 líneas en la consola saliente. Entonces, hay tráfico que ingresa al NODO_3 y tráfico que sale del NODO_3, y la prueba está funcionando.
Luego ejecuté la prueba cifrada. Esta vez veo aparecer una sola línea en la consola entrante y nada en la consola saliente. Entonces, un solo paquete llega al NODO_3. No estoy seguro de si se descifra y se envía de regreso al contenedor.
Actualización 2
Un área de configuración que no mencioné es que tengo la siguiente configuración /etc/docker/daemon.json:
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
"tlscacert": "/var/docker/ca.pem",
"tlscert": "/var/docker/server-cert.pem",
"tlskey": "/var/docker/server-key.pem",
"tlsverify": true
}
Esto es para permitirme usar certificados de cliente SSL para conectarme de forma remota. Este archivo se configuró en todos los nodos antes de crear el enjambre.
Como el descifrado de los paquetes parece una posible causa, cambié mi daemon.json a lo siguiente:
{
"hosts": []
}
Luego reinicié cada máquina. Los resultados de la prueba son los mismos: todavía no funcionan.
Luego ejecuté el comando: docker swarm ca --rotate y volví a ejecutar las pruebas. Esto tiene el mismo resultado.
No eliminé ni reinicié el clúster con la nueva configuración. (Podría hacerlo si alguien cree que sería útil, pero tengo muchos secretos y configuraciones de Docker que perdería en el proceso).
Actualización 3
Ahora eliminé y reinicié completamente el clúster. Esto no ha funcionado.
Algunas fuentes dicen que el siguiente comando:
sudo tcpdump -p esp
Cuando se ejecuta en los nodos, debería mostrar tráfico. Ejecuté esto en todos los nodos del clúster y repetí todas las pruebas y no hay resultados en ninguna parte.
ufw está inactivo en todos los nodos:
robert@metcaac6:/var/log$ sudo ufw status
[sudo] password for robert:
Status: inactive
pero cuando ejecuto iptables -LI obtengo las mismas reglas en cada nodo:
robert@metcaac6:/var/log$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere policy match dir in pol ipsec udp dpt:7789 u32 "0x0>>0x16&0x3c@0xc&0xffffff00=0x100300"
DROP udp -- anywhere anywhere udp dpt:7789 u32 "0x0>>0x16&0x3c@0xc&0xffffff00=0x100300"
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-INGRESS all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DROP all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
Chain DOCKER-INGRESS (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:https
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:30001
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:30001
ACCEPT tcp -- anywhere anywhere tcp dpt:30000
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:30000
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
He inspeccionado dmesg y /var/log/syslog buscando posibles problemas pero no encuentro ninguno.
Todavía no tengo idea de dónde debería buscar el problema.