紹介する
以下の負荷分散構成があります。
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が10.0.1.35を開く必要があります。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
質問
lo
ロケールTomcatがlbを介してmysqlに接続しようとすると、ポートは10.0.1.35であるため、接続はローカルインスタンスに確立されます。
lo
発信パケットをスキップしたい。
テスト
mysqlサービスが無効になり、lo
インタフェースのipが10.0.1.35の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
@パトリックソリューション
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アクセス権はまだありますが、何がおかしいですか?
[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
ベストアンサー1
私はあなたが達成したいものと似たようなことをする非常に古いコードを見つけました。希望の効果を得るには、次のようにします。
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
これにより、すべてのトラフィックをlocalhostに送信して表示されるパスが削除されます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
確認し、以前に追加したルートを選択します。このルール(および私たちがテーブルに追加したパス)の理由は、ロードバランサーがこのボックスに送信した(したがって送信されなかった)すべてのトラフィックが拒否されないためです。デフォルトでは、これはカーネルに「はい、このIPは私のものです」と伝えます。10
10
iif lo
「ローカル」パスをテーブルに移動するのは、ルールが一致したい10
からです。iif lo lookup main prio 0
ただし、「ローカル」テーブルは優先順位が最も高いため、常に最初に一致します。
ルールを順番に追加する理由は、邪魔を防ぐためです。指示に示されている順序で追加すると、ギャップが発生し、ルーティングがなくなり、ローカルボックスに送信されるすべてのトラフィックが拒否されます10.0.1.35
。10.0.1.35