Pule o roteamento via interface 'lo' para pacotes de saída

6

Introdução

Tenho a seguinte configuração de balanceamento de carga:

10.0.1.31 - lb
10.0.1.35 - virtual IP
10.0.1.32 - node1 (tomcat + mysql)
10.0.1.33 - node2 (tomcat + mysql)

Estou usando keepalived , que está redirecionando pacotes para nós ativos - o endereço IP compartilhado é 10.0.1.35. lb requereu configuração:

echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf

node1 e node2 para manipular corretamente pacotes de entrada precisam ter 10.0.1.35 em lo

[root@lb-node1 ~]# ip addr list dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
   inet 10.0.1.35/32 scope global lo
   inet6 ::1/128 scope host 
   valid_lft forever preferred_lft forever

Problema

Devido ao fato de que temos 10.0.1.35 no lo se o tomcat locale estiver tentando se conectar ao mysql via lb - a conexão é estabelecida para a instância local.

Gostaria de ignorar lo para pacotes de saída

Teste

Do node1 que desabilitou o serviço mysql e 10.0.1.35 ip na interface lo Estou tentando conectar-me ao mysql no node2. Infelizmente o resultado é

   [root@lb-node1 ~]# telnet 10.0.1.35 3306
   Trying 10.0.1.35...
   telnet: connect to address 10.0.1.35: Connection refused 

é claro que se eu remover 10.0.1.35 da interface lo sou capaz de conectar a instância do mysql no node2

Solução (?)

Eu estava tentando adicionar rotas com métricas apropriadas, mas isso não ajuda: /

    [root@lb-node1 ~]# route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    10.0.1.0        0.0.0.0         255.255.255.255 UH    0      0        0 eth0
    10.0.1.0        0.0.0.0         255.255.255.255 UH    100    0        0 lo
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
    0.0.0.0         10.0.1.1        0.0.0.0         UG    0      0        0 eth0

@Patrick Solution

vip=10.0.1.35

ip route add local $vip dev lo table 10 proto kernel scope host
ip rule add to $vip lookup 10 prio 1
ip route del local $vip dev lo table local
ip rule add to $vip iif lo lookup main prio 0

@Patrick Solution Issue

Estado inicial

VIP + sua configuração de rota ip, o mysql está trabalhando em ambos os nós

P Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.1.35:http rr persistent 6
TCP  10.0.1.35:mysql rr persistent 6
  -> 10.0.1.32:mysql              Route   10     0          0
  -> 10.0.1.33:mysql              Route   10     0          2
UDP  10.0.1.35:snmptrap rr persistent 6
  -> 10.0.1.32:snmptrap           Route   10     0          0
  -> 10.0.1.33:snmptrap           Route   10     0          1




root@lb-node1 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 126
Server version: 5.5.36-MariaDB-wsrep-log MariaDB Server, wsrep_25.9.r3961

Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SHOW VARIABLES WHERE Variable_name = 'hostname';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| hostname      | lb-node2 |
+---------------+----------+
1 row in set (0.00 sec)

MariaDB [(none)]> 


[root@lb-node2 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 133
Server version: 5.5.36-MariaDB-wsrep-log MariaDB Server, wsrep_25.9.r3961

Copyright (c) 2000, 2014, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

ariaDB [(none)]> ;
ERROR: No query specified

MariaDB [(none)]> SHOW VARIABLES WHERE Variable_name = 'hostname';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| hostname      | lb-node2 |
+---------------+----------+
1 row in set (0.00 sec)

MariaDB [(none)]> 

Como você pode ver, tudo está funcionando corretamente.

Problema

Mas quando encerro o servidor mysql atualmente ativo:

[root@lb-node2 ~]# service mysql stop
Shutting down MySQL.... SUCCESS! 
[root@lb-node2 ~]# 



Every 2.0s: ipvsadm -l                                                                                          Fri May  9 10:20:49 2014

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.1.35:http rr persistent 6
TCP  10.0.1.35:mysql rr persistent 6
  -> 10.0.1.32:mysql              Route   10     0          0
UDP  10.0.1.35:snmptrap rr persistent 6
  -> 10.0.1.32:snmptrap           Route   10     0          0
  -> 10.0.1.33:snmptrap           Route   10     0          1

Não consigo me conectar ao mysql de ambos os nós

[root@lb-node2 ~]# mysql -h 10.0.1.35 -u test -p
Enter password: 

..... 

Parece-me que o node1 não está aceitando pacotes de entrada, porque o balanceador de carga está redirecionando corretamente os pacotes

[root@lb-node1 ~]# tcpdump -i eth0 'port 3306' and src 10.0.1.33 or dst 10.0.1.33
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:35:26.915640 ARP, Reply 10.0.1.35 is-at 52:54:00:30:a3:4b (oui Unknown), length 28
10:35:26.915987 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1298907 ecr 0,nop,wscale 7], length 0
10:35:27.914788 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1299907 ecr 0,nop,wscale 7], length 0
10:35:29.914784 IP 10.0.1.33.38517 > 10.0.1.35.mysql: Flags [S], seq 2024730796, win 14600, options [mss 1460,sackOK,TS val 1301907 ecr 0,nop,wscale 7], length 0

O que é estranho porque ainda tenho VIP no lo

[root@lb-node1 ~]# ip addr list dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet 10.0.1.35/32 scope global lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever



[root@lb-node1 ~]# ip route
10.0.1.0/24 dev eth0  proto kernel  scope link  src 10.0.1.32 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.1.1 dev eth0 
    
por hicolour 05.05.2014 / 10:32

1 resposta

2

Eu desenterrei um código muito antigo que fez algo parecido com o que você está tentando realizar. Veja o que você pode fazer para obter o efeito desejado:

vip=10.0.1.35

ip route add local $vip dev lo table 10 proto kernel scope host
ip rule add to $vip lookup 10 prio 1
ip route del local $vip dev lo table local
ip rule add to $vip iif lo lookup main prio 0

Isso fará com que a caixa envie qualquer tráfego para 10.0.1.35 para a rede (e, portanto, para o balanceador de carga que está respondendo a solicitações ARP para esse IP). Mas a caixa ainda aceitará qualquer tráfego que o balanceador de carga fornecer.

Explicação

Eu vou explicá-los fora de ordem, pois eles fazem mais sentido desse jeito.

ip route del local $vip dev lo table local

Isso remove a rota que diz para enviar todo o tráfego para 10.0.1.35 para o host local através de lo .

ip route add local $vip dev lo table 10 proto kernel scope host

Isso substitui o que acabamos de excluir, mas o coloca em uma nova tabela ( 10 ).

ip rule add to $vip iif lo lookup main prio 0

Isso informa ao sistema que, ao enviar o tráfego da caixa local ( iif lo ) para 10.0.1.35 , usar a rota principal em vez da rota 'local'. Isso fará com que 10.0.1.35 tráfego escolha a rota para a sub-rede 10.0.1.0/24 (ou qualquer que seja sua sub-rede local, se não for /24 ).

ip rule add to $vip lookup 10 prio 1

Esta regra é adicionada com uma prioridade mais baixa (maior número) do que a regra acima para que ela corresponda depois. Se o tráfego não corresponder à regra acima (não iif lo ), a tabela 10 será verificada para uma rota correspondente, que selecionará a rota que adicionamos anteriormente.
O motivo da regra (e a rota que adicionamos à tabela 10 ) é para que qualquer tráfego que o balanceador de carga envie para essa caixa (portanto, não iif lo ) não seja rejeitado. Basicamente, ele diz ao kernel "sim, esse IP pertence a mim".

O motivo pelo qual movemos a rota "local" para a tabela 10 é porque queremos que a regra iif lo lookup main prio 0 corresponda. Mas a tabela "local" tem a prioridade mais alta, então sempre corresponde primeiro.

A razão pela qual adicionamos as regras na ordem em que fazemos é evitar a interrupção. Se você os adicionou no pedido coberto na explicação, você teria uma lacuna onde não há rota para 10.0.1.35 , o que resultaria em qualquer tráfego 10.0.1.35 sendo enviado para a caixa local sendo rejeitado.

    
por 08.05.2014 / 07:12