naoyaの日記 RSSフィード

 | 

2006-08-25

なんか 18:04

社内日記とこっちの日記が同じようなことをいろいろかいてて混乱している俺ガイル

LVS#5 17:56

んー、グローバル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つ

  • 上記の構成でまだうまくいってないgw をフォワーダにしたらうまくいった
  • 同一セグメントにある3ホストで試したときはうまくいったけど RIP -> VIP の通信がうまくいかない

LVS#4 15:56

一つ問題があった。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#3 15:28

つーことで次はインターネットに接するところでの LB のために違うセグメントに属するいくつかの IP をつなげてみるぞ。

LVS#2 15:26

LVS で DSR がうまくいかなかったのはテスト用に用意したネットワーク環境が特殊だったのがいけなかった。で、環境を変えていまテスト中。

LVS を二つの用途に使えるかどうかをテストしていて、ひとつは普通インターネットとの門にする目的。もう一つは mysqld のスレーブ群の手前に挟んで使えるかどうかを試すというもの。Flickr が mysqld のスレーブ振り分けを LB でやってるというスライドを以前にみたのでそれを真似してみたい。

で、後者でも LVS + DSR で使うわけだけど、この場合 VIP, クライアント, RIP がすべて同一セグメントにあるので、ネットワークの構成はシンプル。つーわけでやってみたわけだが。

どうも Real Server の loopback に VIPエイリアスしたところで、同一セグメントに対する ARP に応答してしまったらしく、VIP と RIP とでネットワーク上でバッティングしてしまった様子。loopback を隠す、というのが何のためにやるのかよくわからんでいたけど、こういうことでしたか。

そんで、

IP エイリアスをしなくていいというより、この loopback を隠す手間を省くための方法なんすね。IP エイリアスするのも、この iptables 使うのもたいして手間は差ないんじゃないかと最初思ってたんだけど、ここで理解。カーネルパッチ当てなくて済む。

で、これでやったらうまくいった。やっほーい。

LVS 13:12

LVS 試して NAT はうまくいったけど DSR があとちょっとのところでうまくいかない。

tcpdump してると RIP ホストまで、確かに書き換えが発生してないパケットが来てはいるのであとはこれを loopback インタフェースでうまく掴んでやるというところ。

では VIPエイリアスを loopback に作って hidden interface を使うというものだけど、hidden interface を有効にするにはどうもカーネルパッチをあてなければいけないらしく、FC4 のカーネルにはそれが当たってない。(loopback を隠さなくてもいけるかなと思ったんだけど、どうもうまくいかず。

こちらもやってみたけどまだうまくいってない。iptables の設定が組み込まれたのは確認したんだけど、開通せず。

というかなんか全然関係ないとこでシケてる気もしないでもない。ネットワーク周りとか。VIP も RIP もプライベートアドレスで、ルーティングとかがインターネットから入ってくるときと違う感じになってんのが頭を混乱させる。

追記

原因が分かった。多分、試験してる環境が悪い。ルーティングの問題。

ktakaktaka2006/08/25 14:43もし、LVSがgatewayを兼ねているとしたら、LVSにVIPを振らずにLVSでVIP宛てのパケットにfwmarkをつけてipvsを通らせ、(ひ)さんの方法でRealServerでVIPをRedirectNATする方法が良さげです。そうすると、arpの問題や、source martianの問題を避けて通れます。

naoyanaoya2006/08/25 14:45なんかもっと単純な問題で、プライベートアドレスだけど異なるセグメントの2ホストでやってたのが悪かったみたいで。DSR で RIP から応答を返そうとするけれども、そもそもその RIP からクライアントが見えないネットワーク構成になってますと。

いまネットワーク構成を変更して試してみるところです。

hirose31hirose312006/08/25 15:10http://dsas.blog.klab.org/archives/50664843.html
の環境でいうと、
[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
に向ける必要があるかも。

naoyanaoya2006/08/25 15:20うご、なんかなぞのコマンドがいろいろw

ちとその辺後で調べるとして、iptables の方法でうまくいきました。

hirose31hirose312006/08/25 15:24おめでとうございます!! kwsk!!

ktakaktaka2006/08/25 16:23外してるかもしれませんが、RIP→VIPへの経路が無いとかではありませんか?arpに反応するやつはいないでしょうし。ただし、arp解決なりルーティングでVIP宛てのパケットがきちんとLVSに飛ぶようにしてあったとしても、LVSからのフォワード先が送信元のRIPだとすると、応答パケットがRIP->RIPになってしまい上手く通信でき無かったりするような... つまりVIPにパケットを送ったのに、RIPから返事が返ってくる(しかもループバックインターフェース経由で)ので、通信できないとか。

ktakaktaka2006/08/25 16:40hirose31さんの方法ですが、「VIP宛てのパケットにマーク1をつけて、ルーティングテーブル設定により、ローカルパケットとして処理する。」ということですね。これによりLVSのインターフェースにVIPを振っていなくても、LVS上でVIPをipvsにより処理できるようになるわけです。rp_filterのフラグは、同一サブネットのアドレスを違うインターフェースにフォワードしないようにするためのSPOOFING PROTECTIONをオフにするためのもののようですね。

yasuiyasui2006/08/25 18:53gwのマスカレード外すだけで繋がらないでしょうか。
この構成においてGWはただのフォワーダ(ルータ)でなければならなないとおもいます。
そもそもマスカレードしちゃうとそこがボトルネックになっちゃいます。

naoyanaoya2006/08/25 18:59にゃるほろ! フォワーダにするんですね、ちとやってみまっす。

naoyanaoya2006/08/25 18:59ちなみに Real Server をグローバルIPを持ったホストに変えて試したらふつーにうまくいきました。

naoyanaoya2006/08/25 19:08oh,うまくいったー!!!

naoyanaoya2006/08/25 19:14ふと思ったんですが、フォワーダにしても gw をいくつか作って割り振らないと、結局 gw の通信上限がボトルネックになっちゃいますね。

yasuiyasui2006/08/26 01:16gwの通信上限がボトルネックになるといっても上流回線が100Mならギガビットイーサ付きのマシンなら軽くワイヤーレート出せるとおもいます。

yasuiyasui2006/08/26 01:17ああ、でも上流がギガビットなら確かに3台か4台くらい必要かもですね

yasuiyasui2006/08/26 01:19何はともあれうまくいってよかったですね

yasui0906yasui09062006/08/26 01:31あぁ、RIP->VIPの通信はできないはずです。
Linuxはソースアドレスが自分自身のパケットを外から受け取ると破棄するようです。
(netfilterの処理にも流れないのでiptablesで制御することすらできません)
いろいろ頑張ってみてるのですがどうも厳しそうなので、今は別の箱でプロクシサーバ立てて RIP -> PROXY -> VIP という流れで繋いでいます。

naoyanaoya2006/08/26 12:04んー、やっぱそうですか。一部これができないと困るときがありますよね。hosts か proxy かでやってみまっす。

トラックバック - http://naoya.g.hatena.ne.jp/naoya/20060825
 | 
この日記のはてなブックマーク数