Isto parece ser causado por cache ARP (cache de endereço MAC) em novos kernels linux.
Eu tenho 7 servidores Ubuntu 14.04.4 em execução no EC2. Um servidor está hospedando o memcached (porta 11211) e os outros 6 são clientes. Dos 6 clientes, 5 são capazes de se conectar e um não é (veja nota).
Eu fiz um despejo TCP de ambos os lados da conexão. Vi que o cliente enviou uma solicitação SYN, mas nenhum ACK foi enviado de volta. O tcpdump ficou assim para a conexão com falha (os SYNs repetem muitas vezes depois disso)
1 0.000000 172.16.1.58 172.16.1.94 TCP 76 43469 → 11211 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=849737 TSecr=0 WS=128
E para uma conexão bem-sucedida de um servidor diferente:
1 0.000000 172.16.1.64 172.16.1.94 TCP 76 44908 → 11211 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=19201098 TSecr=0 WS=128
2 0.000298 172.16.1.64 172.16.1.94 TCP 68 44908 → 11211 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=19201098 TSecr=3160738522
Mais alguns rastros & comandos:
working-client$ nc -vnz 172.16.1.94 11211
Connection to 172.16.1.94 11211 port [tcp/*] succeeded!
broken-client$ nc -vnz 172.16.1.94 11211
nc: connect to 172.16.1.94 port 11211 (tcp) failed: Connection timed out
broken-client$ nc -vnz -q 5 -u 172.16.1.94 11211
Connection to 172.16.1.94 11211 port [udp/*] succeeded!
Tabela de roteamento (idêntica em todos os clientes e servidor)
$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default ip-172-16-1-1.e 0.0.0.0 UG 0 0 0 eth0
172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
Tabelas IP no cliente quebrado
broken-client$ sudo iptables -nvL -t nat
--------------------------------------
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
broken-client$ sudo iptables -nvL
--------------------------------------
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Tabelas IP no servidor
server$ sudo iptables -nvL -t nat
--------------------------------------
Chain PREROUTING (policy ACCEPT 7332 packets, 531K bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 7332 packets, 531K bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 370 packets, 25781 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 370 packets, 25781 bytes)
pkts bytes target prot opt in out source destination
server$ sudo iptables -nvL
--------------------------------------
Chain INPUT (policy ACCEPT 1963K packets, 341M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 2670K packets, 5518M bytes)
pkts bytes target prot opt in out source destination
Todos os clientes foram clonados a partir da mesma imagem de base e devem ser idênticos. Nós não estamos usando o iptables, todos os servidores estão na mesma sub-rede e grupo de segurança.
O problema não é com o memcached: eu posso reproduzir o problema com telnet (porta 22 ou porta 11211) ou ssh, nenhum deles tem permissão para se conectar, embora eles sejam permitidos pelo grupo de segurança.
O ping está desativado, mas posso rastrear entre servidores (cache < = > cliente, cliente < = > cache) desde que não sejam esses dois servidores.
Aparece (veja os rastros acima) que uma conexão UDP pode ser estabelecida, mas não TCP.
O problema é persistente.
Observação: os 6 servidores clientes fazem parte de um grupo de escalonamento automático (em um VPC). Existem entre 1 e 6 servidores, dependendo da carga, e às vezes um servidor não consegue se conectar. Endereços IP e nomes de servidores são reutilizados.
O que posso ver para descobrir onde a conexão está falhando?
Isto parece ser causado por cache ARP (cache de endereço MAC) em novos kernels linux.
Tags amazon-ec2 ubuntu tcp