Actualización 1

Actualización 1

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.

información relacionada