はじめに
一つのパソコンのLinuxの上に
※何年かしたら、なんで出来ないんだっけ?と思う日が来るかもしれないので書いておきます。
※ちなみに、IPVSとKeepalivedの設定はKeepalivedによるロードバランサLVS構築 - RLBの文書が丁寧でいいかなと思います。
ハードウェア構成
実現したかった構成
設定
現実
192.168.0.100の80番ポートに要求が来ると、それをロードバランサが処理するのではなくApacheが先に処理をしてしまいます。その結果、ロードバランサは素通りします。
ロードバランサもApacheも80番ポートで待ち構えているのがNGなので、Apacheのポートを8080にすればいいじゃないか!とも思いましたが、DSR構成でないといけないのでApacheのポートを8080にすると80番ポートに要求してきたものが8080番で応答が返ってしまうのでNGです。
ちなみに左のパソコン自身で
$ curl http://192.168.0.100/index.html
すると、左のパソコンのApacheが選ばれた場合は
が、右のパソコンが選ばれた場合は
送信元が192.168.0.100になるロジックが分からないのでなんともですが、まず
192.168.0.100 → 192.168.0.100(左のパソコンが受信)
というパケットが左のパソコンに送られます。
左のパソコンには
iptables -t nat -A PREROUTING -d 192.168.0.100 -j REDIRECT
が書いてあるので、送信元が192.168.0.100、宛先が192.168.0.100のパケットを返します。
このパケットを受け取った左のパソコンは…送信元が192.168.0.100で宛先が192.168.0.100ってなんだっけ?と破棄して、またSYNパケットを送る…という動作になっているのだと思います。
実現するには
多分、物理的なパソコン2台に、それぞれ1つのOSがのっているという状態だと無理なのだと思います。
※ぐぐって見つかるIPVS + Keepalivedの設定例は、書いてある図が物理構成なのか論理構成なのかいまいち分からない…というのが悩ましいところだと思っています。
※余談ですが、NW機器をまったく知らないという方が異動したきた際に例えばVRFを使った「論理的なルータ」というものを理解してもらうのに苦労します…しませんか?。「ええとね、このルータは物理的には1台なんだけど、仮想的に3台になっていてね…」「物理的なポートに対して仮想的なポートを設定してね…」と説明すると、明らかに挙動がおかしくなり、じゃあ図を書いて説明しますねとホワイトボードに向かうも…ごちゃごちゃになっていまいち分かりにくいと…自分はいったいこれをどう理解して現在に至るのか分かりません…
多分、以下のように仮想化するしかないのかなと…
この構成を取るには学ばなければいけないことがたくさんありすぎるので諦めることにしました。
設定を開始してから諦めるまで5時間くらいかかりました。敗因は「できる」と思い込んでいたことでしょうか…
「できなかったです」という掲示板のやりとりを見て「ああ、やっぱできないんだ」と、そこで、自分でいろいろいじった結果も踏まえて納得して諦めることができました。
この文書が、私と同じ発想に行き着いてしまった方のために役に立つことを祈ります。
※まあ、だいたい、何年後の自分のために役に立つことが多いんですよね。ぐぐると、意外に自分の書いた文書がひっかかったりします…
※ちなみに、keepalivedによるVRRP --- nginx(80番ポートで待ち受け)によるロードバランス ---- Apache(8080番ポートで待ち受け)な構成で、元々やりたかったことが実現可能だと分かりました。
もう5年も前に発売された本ですが、個人でサーバーを運用している私にとってはその内容は色あせることがないです。Webの世界…特にフロントエンドは新しい技術がわさわさ出てきてついていくのが大変ですが、インフラの世界は比較的穏やかなのかな…という気がしました。
そのかわり、達人の域に達するには、達人の域が必要である環境に飛び込まないとスキルが身につかない気がいたします。一度、すごいトラヒックをさばく環境で仕事をしてみたいです。
一つのパソコンのLinuxの上に
- KeepalivedでVRRPを設定
- IPVSでロードバランシングを設定
- Apacheを動作
- パソコンが落ちると、もう一つのパソコンに切り替わり
- 通常時は2台あるパソコンに処理を分散させる
※何年かしたら、なんで出来ないんだっけ?と思う日が来るかもしれないので書いておきます。
※ちなみに、IPVSとKeepalivedの設定はKeepalivedによるロードバランサLVS構築 - RLBの文書が丁寧でいいかなと思います。
ハードウェア構成
実現したかった構成
設定
#VRRP部分 vrrp_instance VI_1 { state BACKUP interface eth1 garp_master_delay 5 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.0.100/24 dev eth1 } } #ロードバランシング部分 virtual_server_group example_web_servers { 192.168.0.100 80 } virtual_server group example_web_servers { delay_loop 3 lvs_sched lc lvs_method DR protocol TCP real_server 192.168.0.1 80 { weight 1 inhibit_on_failure HTTP_GET { url { path / status_code 200 } connect_port 80 connect_timeout 10 } } real_server 192.168.0.2 80 { weight 1 inhibit_on_failure HTTP_GET { url { path / status_code 200 } connect_port 80 connect_timeout 10 } } }想像していたもの
現実
192.168.0.100の80番ポートに要求が来ると、それをロードバランサが処理するのではなくApacheが先に処理をしてしまいます。その結果、ロードバランサは素通りします。
ロードバランサもApacheも80番ポートで待ち構えているのがNGなので、Apacheのポートを8080にすればいいじゃないか!とも思いましたが、DSR構成でないといけないのでApacheのポートを8080にすると80番ポートに要求してきたものが8080番で応答が返ってしまうのでNGです。
ちなみに左のパソコン自身で
$ curl http://192.168.0.100/index.html
すると、左のパソコンのApacheが選ばれた場合は
21:55:03.363352 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [S], seq 2243980878, win 14600, options [mss 1460,sackOK,TS val 2335997614 ecr 0,nop,wscale 7], length 0 21:55:03.363465 IP 192.168.0.100.http > 192.168.0.1.52535: Flags [S.], seq 1870693664, ack 2243980879, win 14480, options [mss 1460,sackOK,TS val 2335994093 ecr 2335997614,nop,wscale 7], length 0 21:55:03.363571 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [.], ack 1, win 115, options [nop,nop,TS val 2335997614 ecr 2335994093], length 0 21:55:03.363659 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [P.], seq 1:184, ack 1, win 115, options [nop,nop,TS val 2335997614 ecr 2335994093], length 183 21:55:03.363995 IP 192.168.0.100.http > 192.168.0.1.52535: Flags [.], ack 184, win 122, options [nop,nop,TS val 2335994094 ecr 2335997614], length 0 21:55:03.364464 IP 192.168.0.100.http > 192.168.0.1.52535: Flags [P.], seq 1:272, ack 184, win 122, options [nop,nop,TS val 2335994094 ecr 2335997614], length 271 21:55:03.364550 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [.], ack 272, win 123, options [nop,nop,TS val 2335997616 ecr 2335994094], length 0 21:55:03.364750 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [F.], seq 184, ack 272, win 123, options [nop,nop,TS val 2335997616 ecr 2335994094], length 0 21:55:03.364997 IP 192.168.0.100.http > 192.168.0.1.52535: Flags [F.], seq 272, ack 185, win 122, options [nop,nop,TS val 2335994095 ecr 2335997616], length 0 21:55:03.365065 IP 192.168.0.1.52535 > 192.168.0.100.http: Flags [.], ack 273, win 123, options [nop,nop,TS val 2335997616 ecr 2335994095], length 0と、送信元が192.168.0.1で宛先が192.168.0.100となって通信が成立します。
が、右のパソコンが選ばれた場合は
21:57:00.468685 IP 192.168.0.100.40601 > 192.168.0.100.http: Flags [S], seq 1090039344, win 32792, options [mss 16396,sackOK,TS val 2336114720 ecr 0,nop,wscale 7], length 0 21:57:00.468820 ARP, Request who-has 192.168.0.100 tell 192.168.0.2, length 46 21:57:00.468843 ARP, Reply 192.168.0.100 is-at 6c:62:6d:08:c8:97 (oui Unknown), length 28 21:57:00.469031 IP 192.168.0.100.http > 192.168.0.100.40601: Flags [S.], seq 354377091, ack 1090039345, win 14480, options [mss 1460,sackOK,TS val 2336111198 ecr 2336114720,nop,wscale 7], length 0 21:57:01.468573 IP 192.168.0.100.40601 > 192.168.0.100.http: Flags [S], seq 1090039344, win 32792, options [mss 16396,sackOK,TS val 2336115720 ecr 0,nop,wscale 7], length 0 21:57:01.468714 IP 192.168.0.100.http > 192.168.0.100.40601: Flags [S.], seq 354377091, ack 1090039345, win 14480, options [mss 1460,sackOK,TS val 2336112198 ecr 2336114720,nop,wscale 7], length 0 21:57:01.631898 IP 192.168.0.100.http > 192.168.0.100.40601: Flags [S.], seq 354377091, ack 1090039345, win 14480, options [mss 1460,sackOK,TS val 2336112362 ecr 2336114720,nop,wscale 7], length 0 21:57:03.468575 IP 192.168.0.100.40601 > 192.168.0.100.http: Flags [S], seq 1090039344, win 32792, options [mss 16396,sackOK,TS val 2336117720 ecr 0,nop,wscale 7], length 0 21:57:03.468768 IP 192.168.0.100.http > 192.168.0.100.40601: Flags [S.], seq 354377091, ack 1090039345, win 14480, options [mss 1460,sackOK,TS val 2336114198 ecr 2336114720,nop,wscale 7], length 0 21:57:03.631910 IP 192.168.0.100.http > 192.168.0.100.40601: Flags [S.], seq 354377091, ack 1090039345, win 14480, options [mss 1460,sackOK,TS val 2336114362 ecr 2336114720,nop,wscale 7], length 0となって、192.168.0.100の間でピンポンゲームになってしまいます。
送信元が192.168.0.100になるロジックが分からないのでなんともですが、まず
192.168.0.100 → 192.168.0.100(左のパソコンが受信)
というパケットが左のパソコンに送られます。
左のパソコンには
iptables -t nat -A PREROUTING -d 192.168.0.100 -j REDIRECT
が書いてあるので、送信元が192.168.0.100、宛先が192.168.0.100のパケットを返します。
このパケットを受け取った左のパソコンは…送信元が192.168.0.100で宛先が192.168.0.100ってなんだっけ?と破棄して、またSYNパケットを送る…という動作になっているのだと思います。
実現するには
多分、物理的なパソコン2台に、それぞれ1つのOSがのっているという状態だと無理なのだと思います。
※ぐぐって見つかるIPVS + Keepalivedの設定例は、書いてある図が物理構成なのか論理構成なのかいまいち分からない…というのが悩ましいところだと思っています。
※余談ですが、NW機器をまったく知らないという方が異動したきた際に例えばVRFを使った「論理的なルータ」というものを理解してもらうのに苦労します…しませんか?。「ええとね、このルータは物理的には1台なんだけど、仮想的に3台になっていてね…」「物理的なポートに対して仮想的なポートを設定してね…」と説明すると、明らかに挙動がおかしくなり、じゃあ図を書いて説明しますねとホワイトボードに向かうも…ごちゃごちゃになっていまいち分かりにくいと…自分はいったいこれをどう理解して現在に至るのか分かりません…
多分、以下のように仮想化するしかないのかなと…
この構成を取るには学ばなければいけないことがたくさんありすぎるので諦めることにしました。
設定を開始してから諦めるまで5時間くらいかかりました。敗因は「できる」と思い込んでいたことでしょうか…
「できなかったです」という掲示板のやりとりを見て「ああ、やっぱできないんだ」と、そこで、自分でいろいろいじった結果も踏まえて納得して諦めることができました。
この文書が、私と同じ発想に行き着いてしまった方のために役に立つことを祈ります。
※まあ、だいたい、何年後の自分のために役に立つことが多いんですよね。ぐぐると、意外に自分の書いた文書がひっかかったりします…
※ちなみに、keepalivedによるVRRP --- nginx(80番ポートで待ち受け)によるロードバランス ---- Apache(8080番ポートで待ち受け)な構成で、元々やりたかったことが実現可能だと分かりました。
安井 真伸
技術評論社
2008-08-07
もう5年も前に発売された本ですが、個人でサーバーを運用している私にとってはその内容は色あせることがないです。Webの世界…特にフロントエンドは新しい技術がわさわさ出てきてついていくのが大変ですが、インフラの世界は比較的穏やかなのかな…という気がしました。
そのかわり、達人の域に達するには、達人の域が必要である環境に飛び込まないとスキルが身につかない気がいたします。一度、すごいトラヒックをさばく環境で仕事をしてみたいです。