|
|
||
社内日記とこっちの日記が同じようなことをいろいろかいてて混乱している俺ガイル
んー、グローバルIPな環境で試してみてるけどやっぱルーティング絡みかな、うまくいかず。
この際なので現状を詳しく記す。構成図を描くとこんな感じ。1.1.1.1 / 2.2.2.2 / 3.3.3.3 はグローバルアドレス。

LVS + DSR で Client に応答を返したい。
で一通り設定して、Real Server で tcpdump でモニタリングしたところ
16:26:07.278022 1.1.1.1.59733 > 2.2.2.2.http: S 3374655946:3374655946(0) win 5656 <mss 1412,sackOK,timestamp 26449364 0,nop,wscale 0> (DF) 16:26:07.278152 2.2.2.2.http > 1.1.1.1.59733: R 0:0(0) ack 3374655947 win 0 (DF)
というパケットが観察できたので、多分ロードバランサー自体の設定はうまくいってる、はず。(同一セグメントのホスト間でやったときと同じ流れ方なので。) で、Real Server はプライベートなアドレスなので、ゲートウェイにいったときに SRC が 192.168.0.0/24 じゃなくて DSR の都合上 2.2.2.2 と特殊なのが理由で、いつものマスカレード設定ではマスカレードできてなくて、死んでるんかなあと。
ということで gw の iptables のマスカレード設定周りをいろいろ見てるんだけど、まだ解決できておらず。(というか実はマスカレードしないでどうにかするのが正解だったりする?)
...というかなんか普通に考えてこの構成は無理じゃんじゃないかと。コネクションどこで維持されるのみたいな。いろいろやりすぎて頭がおかしくなってきた。こういうネットワーク構成でほんとにいけるんかな。
リアルサーバでは、VIPをループバックインターフェースにIP aliasすればいいので、リアルサーバの数だけグローバルIPアドレスを消費するってことはないような。
(ひ)メモ - Linuxでiptablesを使ってDSRする
というのは、この構成ができるってことかと思ってたけどなんか誤読してるかも。
コメント欄で gw をマスカレードするんじゃなくフォワーダにすると良いと教えてもらってそうしたらうまくいった。ども!!
ていうかあれだね、仮にこの構成がうまくいくとしても、gw の設定がしょっちゅう発生するようだと手間がかかるなあ。グローバルIP用意してそいつが直接...の方が全然運用が楽な気がする。iptables のセキュアなフォワーダのルールを VIP に依存しない形で書けば OK だとわかった。
以下手順。
まずは LVS ホストで
# echo "1" > /proc/sys/net/ipv4/ip_forward $ sudo ipvsadm -A -t 2.2.2.2:80 -s lc $ sudo ipvsadm -a -t 2.2.2.2:80 -r 192.168.0.100 -g $ sudo ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 2.2.2.2:80 lc -> 192.168.0.100:80 Route 1 0 0
次、Real Server で
% sudo /sbin/iptables -t nat -A PREROUTING -d 2.2.2.2 -j REDIRECT % sudo /sbin/iptables -t nat -L -n Password: Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT all -- 0.0.0.0/0 2.2.2.2 Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
となってる。
なんか抜けてるかな。
Real Server にもグローバルIPを振って、Real Server が gw を通らず直でインターネットにパケットを放り投げるような構成にしとけばたぶんうまくいきそだけど、それだと Real Server の数だけグローバルIPが必要になっちゃうし、是非この方法で運用したい。
ということで現状問題点は2つ
一つ問題があった。iptables の PREROUTING でままやってると(というかこれは IP エイリアスしても一緒だと思うけど)、RIP から VIP への通信ができないんすね。
RIP からリモートのVIPに接続しようと思ってパケットを飛ばすと VIP に向かうよりも先に RIP に iptables してる PREROUTING のルールにひっかかっちゃってそこでふん詰まりを起こすっぽい。
なんで、ソースが自分だったときは PREROUTING せずに...とすればいいのか...と思ったけど DSR の場合ソースパケットが書き換わらないから駄目じゃんよ。これがコメント欄でもらった
LVSにVIPを振らずにLVSでVIP宛てのパケットにfwmarkをつけてipvsを通らせ、(ひ)さんの方法でRealServerでVIPをRedirectNATする方法が良さげです。そうすると、arpの問題や、source martianの問題を避けて通れます
ってやつなのかな。もう少し調べてみよう。 全然違う気がしてきた。
むかし Alteon 使ったときに自ドメインから自ドメインに対する通信ができないという同じような問題に遭遇して、/etc/hosts いじって無理やり回避したりしたけど、それと同じ問題っぽいな。
LVS で DSR がうまくいかなかったのはテスト用に用意したネットワークの環境が特殊だったのがいけなかった。で、環境を変えていまテスト中。
LVS を二つの用途に使えるかどうかをテストしていて、ひとつは普通にインターネットとの門にする目的。もう一つは mysqld のスレーブ群の手前に挟んで使えるかどうかを試すというもの。Flickr が mysqld のスレーブ振り分けを LB でやってるというスライドを以前にみたのでそれを真似してみたい。
で、後者でも LVS + DSR で使うわけだけど、この場合 VIP, クライアント, RIP がすべて同一セグメントにあるので、ネットワークの構成はシンプル。つーわけでやってみたわけだが。
どうも Real Server の loopback に VIP をエイリアスしたところで、同一セグメントに対する ARP に応答してしまったらしく、VIP と RIP とでネットワーク上でバッティングしてしまった様子。loopback を隠す、というのが何のためにやるのかよくわからんでいたけど、こういうことでしたか。
そんで、
は IP エイリアスをしなくていいというより、この loopback を隠す手間を省くための方法なんすね。IP エイリアスするのも、この iptables 使うのもたいして手間は差ないんじゃないかと最初思ってたんだけど、ここで理解。カーネルにパッチ当てなくて済む。
で、これでやったらうまくいった。やっほーい。
LVS 試して NAT はうまくいったけど DSR があとちょっとのところでうまくいかない。
tcpdump してると RIP ホストまで、確かに書き換えが発生してないパケットが来てはいるのであとはこれを loopback インタフェースでうまく掴んでやるというところ。
では VIP のエイリアスを loopback に作って hidden interface を使うというものだけど、hidden interface を有効にするにはどうもカーネルにパッチをあてなければいけないらしく、FC4 のカーネルにはそれが当たってない。(loopback を隠さなくてもいけるかなと思ったんだけど、どうもうまくいかず。
こちらもやってみたけどまだうまくいってない。iptables の設定が組み込まれたのは確認したんだけど、開通せず。
というかなんか全然関係ないとこでシケてる気もしないでもない。ネットワーク周りとか。VIP も RIP もプライベートアドレスで、ルーティングとかがインターネットから入ってくるときと違う感じになってんのが頭を混乱させる。
いまネットワーク構成を変更して試してみるところです。
の環境でいうと、
[lv1]
iptables -t mangle -F PREROUTING
iptables -t mangle -A PREROUTING -d 10.10.31.100 -j MARK --set-mark 1
ip rule add prio 100 fwmark 1 table 100
ip route add local 0/0 dev lo table 100
echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter
[w101,w102]
iptables -t nat -F
iptables -t nat -A PREROUTING -d 10.10.31.100 -j REDIRECT
でいけないすかね?
クライアントブラウザのマシンのルーティングを
ip route add to 10.10.31.0/24 via 10.10.31.11
に向ける必要があるかも。
ちとその辺後で調べるとして、iptables の方法でうまくいきました。
この構成においてGWはただのフォワーダ(ルータ)でなければならなないとおもいます。
そもそもマスカレードしちゃうとそこがボトルネックになっちゃいます。
Linuxはソースアドレスが自分自身のパケットを外から受け取ると破棄するようです。
(netfilterの処理にも流れないのでiptablesで制御することすらできません)
いろいろ頑張ってみてるのですがどうも厳しそうなので、今は別の箱でプロクシサーバ立てて RIP -> PROXY -> VIP という流れで繋いでいます。