Estou procurando ajuda para depurar a seguinte configuração:
Tenho 3 instâncias de VPs Cloud de uma empresa de hospedagem. (Acredito que os VPS sejam VMWare, mas não consigo encontrar nenhuma documentação no site das empresas anfitriãs.)
- Todos estão executando o Ubuntu 18.04.
- Eu instalei o docker em todos os 3.
Todas as versões do docker são iguais:
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
Um nó 1 executei o seguinte comando init:
docker swarm init --advertise-addr NODE_1_IP --data-path-port=7789
E nos nós 2 e 3 executei os seguintes comandos de junção
docker swarm join --token XXX -advertise-addr NODE_2/3_IP NODE_1_IP:2377
O token é retirado do valor que o Nó 1 me deu. Resolvi um problema anterior especificando data-path-port. Acho que isso ocorre porque os VPS são VMWare e entram em conflito com o dataport padrão
Meu provedor de nuvem me fornece uma interface do usuário para aplicar regras de firewall a VPS individuais. Usei um grupo de firewall para aplicar as seguintes regras a todos os três 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 testar isso, executei os seguintes comandos no nó 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
Depois que o serviço estiver em execução no cluster, faço o seguinte:
docker run --rm --name alpine --net=testnet -ti alpine:latest sh
apk add --no-cache curl
Em seguida, curvo 5 vezes:
curl web
Todas as 5 vezes recebo uma resposta. Se eu continuar, continuo recebendo respostas. Acho que isso significa que todos os contêineres estão recebendo tráfego.
Depois mudo o servidor para a rede criptografada e repito o mesmo teste:
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
Novamente executo curl 5 vezes:
curl web
Funcionará algumas vezes e outras vezes ficará parado e travado até eu pressionar ctrl-c.
Se eu executar um múltiplo de 5 vezes o padrão de repetições de trabalho e quebradas. Acho que isso ocorre porque alguns contêineres estão rodando em NODE_1 e funcionam, mas a comunicação com os nós 2 e 3 não está funcionando.
A regra ESP ACCEPT foi adicionada ao conjunto de regras de firewall do meu provedor de nuvem após algumas pesquisas sobre o problema.
Tentei reiniciar o cluster, mas sem sorte.
Agora estou preso. Há alguma recomendação sobre como posso prosseguir com a depuração. Obrigado Roberto
Atualização 1
Para depurar, mudei o teste para que o serviço web funcionasse apenas em uma única instância no NODE_3. Em seguida, carreguei dois consoles para o nó 3 e executei os seguintes 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
Um console me mostrará o tráfego para NODE_3 e o outro tráfego para NODE_3.
Em seguida, executei o teste não criptografado novamente. Vejo cerca de 7 linhas aparecerem no console de entrada e 5 linhas no console de saída. Portanto, há tráfego entrando no NODE_3 e tráfego saindo do NODE_3, e o teste está funcionando
Em seguida, executei o teste criptografado. Desta vez, vejo uma única linha aparecer no console de entrada e nada no console de saída. Portanto, um único pacote está chegando ao NODE_3. Não tenho certeza se ele está sendo descriptografado e enviado de volta ao contêiner.
Atualização 2
Uma área da configuração que não mencionei é que tenho a seguinte configuração /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
}
Isso permite que eu use certificados de cliente SSL para conectar-me remotamente. Este arquivo foi configurado em todos os nós antes de eu criar o enxame.
Como a descriptografia dos pacotes parece uma causa possível, mudei meu daemon.json para o seguinte:
{
"hosts": []
}
Em seguida, reiniciei cada máquina. Os resultados do teste são os mesmos - ainda não funcionam.
Em seguida, executei o comando: docker swarm ca --rotate e executei novamente os testes. Isso tem o mesmo resultado.
Não removi e reiniciei o cluster com a nova configuração. (Eu poderia fazer isso se alguém achar que isso ajudaria, mas tenho muitos segredos e configurações do docker que perderia no processo.)
Atualização 3
agora removi completamente e reiniciei o cluster. Isso não funcionou.
Algumas fontes dizem que o seguinte comando:
sudo tcpdump -p esp
Quando executado nos nós deve mostrar tráfego. Executei isso em todos os nós do cluster e repeti todos os testes e não há saída em lugar nenhum.
ufw está inativo em todos os nós:
robert@metcaac6:/var/log$ sudo ufw status
[sudo] password for robert:
Status: inactive
mas quando executo iptables -LI obtenho as mesmas regras em todos os nós:
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
Inspecionei dmesg e /var/log/syslog procurando possíveis problemas, mas não consigo encontrar nenhum.
Ainda não tenho ideia de onde devo procurar o problema.