web-dev-qa-db-ja.com

発信パケットの `lo`インターフェースを介したルーティングをスキップする

前書き

次の負荷分散構成があります。

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)

パケットをアクティブノードにリダイレクトするkeepalivedを使用しています-共有IPアドレスは10.0.1.35です。 lbには設定が必要です:

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

着信パケットを適切に処理するためのnode1とnode2は、loに10.0.1.35が必要です。

[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

問題

ロケールTomcatがlbを介してmysqlに接続しようとしている場合、loに10.0.1.35があるため、ローカルインスタンスへの接続が確立されます。

発信パケットのloをスキップしたい

テスト

Mysqlサービスとloインターフェースの10.0.1.35IPを無効にしたnode1から、node2のmysqlに接続しようとしています。残念ながら、結果は

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

もちろん、loインターフェースから10.0.1.35 IPを削除すると、node2のmysqlインスタンスに接続できます。

解決(?)

適切なメトリックでルートを追加しようとしましたが、役に立ちません:/

    [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ソリューション

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ソリューションの問題

初期状態

VIP + IPルート構成、mysqlは両方のノードで機能しています


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)]> 

ご覧のとおり、すべてが正しく機能しています。

問題

しかし、現在アクティブなmysqlサーバーをシャットダウンすると:

[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

両方のノードからmysqlに接続できません

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

..... 

ロードバランサーがパケットを正しくリダイレ​​クトしているため、node1は着信パケットを受け入れていないようです。

[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

まだ私はVIP on 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 
6
hicolour

私はあなたが達成しようとしていることと同様のことをした私の本当に古いコードをいくつか掘り起こしました。必要な効果を得るためにできることは次のとおりです。

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

これにより、ボックスはトラフィックを10.0.1.35にネットワークに送信します(したがって、そのIPのARP要求に応答しているロードバランサーに送信します)。ただし、ボックスは、ロードバランサーが提供するすべてのトラフィックを引き続き受け入れます。


説明

それらがより理にかなっているので、私はそれらを順不同で説明するつもりです。

ip route del local $vip dev lo table local

これにより、10.0.1.35へのすべてのトラフィックをloを介してローカルホストに送信するように指示するルートが削除されます。

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

これにより、削除したものが置き換えられますが、新しいテーブル(10)に配置されます。

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

これは、ローカルボックス(iif lo)から10.0.1.35にトラフィックを送信するときに、「ローカル」ルートの代わりにメインルートを使用するようにシステムに通知します。これにより、10.0.1.35トラフィックが10.0.1.0/24サブネット(または/24でない場合はローカルサブネット)のルートを選択します。

ip rule add to $vip lookup 10 prio 1

このルールは、上記のルールよりも低い優先度(高い数値)で追加されるため、後で一致します。トラフィックが上記のルールに一致しなかった場合(iif loではない)、テーブル10で一致するルートがないかチェックされ、前に追加したルートが選択されます。
ルール(およびテーブル10に追加したルート)の理由は、ロードバランサーがこのボックスに送信するトラフィック(したがってiif loではない)が送信されないようにするためです。拒否されました。基本的に、それはカーネルに「はい、このIPは私のものです」と伝えます。

'ローカル'ルートをテーブル10に移動した理由は、iif lo lookup main prio 0ルールを一致させたいためです。ただし、「ローカル」テーブルの優先度が最も高いため、常に最初に一致します。

ルールを順番に追加する理由は、中断を防ぐためです。説明に記載されている順序でそれらを追加すると、10.0.1.35へのルートがないギャップが生じ、ローカルボックスに送信される10.0.1.35トラフィックが拒否されます。

2
Patrick