2011年11月27日日曜日

LVS ロードバランサ (1) LVS

Cです。

LVSでのロードバランサ構築方法をまとめておく。(DSR方式)

まずはdebian6.03(squeeze)を最小構成(標準もチェックはずす)でインストール。
openssh-serverをインストールしておく。

今回はLAN内にあるPROXYサーバなどの負荷分散することを目的としたLVSを構築する。
インターネットにへ出て行くような通信を受ける機器の過労死を防ごう。

既存ネットワークがフラットなネットワークであれば、
下の図のように導入するのがいいんだが、


















これはさすがに試すのがしんどいので、シンプル構成にした。こんな感じ。
L3設計はIPアドレスから妄想してくれ。



















2重になってるとこを全部省いてLVS同士のvrrpを
既存のネットワーク側インターフェイスでやり取りするようにした。
ネットワーク構成として正しいのかどうかわからないが、まあいい。

■必要なパッケージインストール
#apt-get install ifenslave ←チーミングするんだから
#apt-get install ipvsadm
#apt-get install bridge-utils



■ipvs 初期設定
#dpkg-reconfigure ipvsadm

自動的にロードするを選択。



これはマスターを選択





■パケット転送ON
#vi /etc/sysctl.conf
↓この部分を
#net.ipv4.ip_forward=1
↑コメントアウトをはずして↓こうする
net.ipv4.ip_forward=1

■LVS01のip address設定
#vi /etc/network/interface

auto lo eth0 eth0:0 bond0
iface lo inet loopback

allow-hotplug eth0 eth1 eth2

iface eth0 inet static
address 192.168.24.161
netmask 255.255.255.0
gateway 192.168.24.1

iface eth0:0 inet static
address 192.168.24.160
netmask 255.255.255.0
gateway 192.168.24.1

iface bond0 inet static
address 10.10.10.11
netmask 255.255.255.0
broadcast 10.10.10.255
slaves eth1 eth2

■PROXY01のip address設定
#vi /etc/network/interface

auto lo bond0 eth2
iface lo inet loopback

allow-hotplug eth0 eth1 eth2

iface bond0 inet static
address 10.10.10.10
netmask 255.255.255.0
broadcast 10.10.10.255
slaves eth0 eth1

iface eth2 inet static
address 192.168.24.163
netmask 255.255.255.0
broadcast 192.168.24.255
gateway 192.168.24.1

■PROXY02のip address設定
#vi /etc/network/interface

auto lo bond0 eth2
iface lo inet loopback

allow-hotplug eth0 eth1 eth2

iface bond0 inet static
address 10.10.10.20
netmask 255.255.255.0
broadcast 10.10.10.255
slaves eth0 eth1

iface eth2 inet static
address 192.168.24.164
netmask 255.255.255.0
broadcast 192.168.24.255
gateway 192.168.24.1

■疎通確認(LVS01とPROXY01,PROXY02の間)
#ping 10.10.10.10
PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data.
64 bytes from 10.10.10.10: icmp_req=1 ttl=64 time=2.32 ms

# ping 10.10.10.20
PING 10.10.10.20 (10.10.10.20) 56(84) bytes of data.
64 bytes from 10.10.10.20: icmp_req=1 ttl=64 time=3.39 ms

疎通OK
プロキシの構築方法はここでは説明しない。
LVSなしの状態でプロキシ経由でWebを見れることを確認する。

■ロードバランス設定(一時的)
#ipvsadm -A -t 192.168.24.160:8080 -s rr
↑VIPに対してのロードバランスサービスを定義してあげる。

#ipvsadm -a -t 192.168.24.160:8080 -r 10.10.10.10 -g
#ipvsadm -a -t 192.168.24.160:8080 -r 10.10.10.20 -g
↑リアルサーバたちを紐付けてあげる。

rrってのはロードバランスアルゴリズムを指定しているんだ。
他にもいろんなアルゴリズムがあるが、
メジャーなのは下のやつら。(manを参照すれば全部書いてあるよ)

■ロードバランスアルゴリズム
rr : ラウンドロビン。実サーバに順番にリクエストを渡す。
wrr : 重み付け(eeight)ラウンドロビン。重み付け設定(weight)が有効になる。
lc : 最小コネクション数。接続数が一番少ないサーバにリクエストがいく。
wlc : 重み付け(weight)最小コネクション数。重み付け設定(weight)が有効になる。
lblc : クライアント(Locality-Based)に応じた最小コネクション数。
    同じクライアントからのリクエストは同じ実サーバにいく。
    接続数が多い場合は別の実サーバにいく。

■動作テスト(結果は失敗する)
クライアントのWebブラウザにプロキシを設定(↑の例だと192.168.24.160)
適当なサイトへアクセスする。
表示されない。

なぜか。

tcpdumpでパケットを追っかけてみると当然だと納得できるだろう。

クライアントからLVSへ渡されるパケットのdestination IPはLVSの持っているVIPだ、
そこでLVSはipvsの設定(DSR)に従い、リアルサーバへ投げつける。
この時もdestination IPはLVSの持っているVIPだ。(↑の例だと192.168.24.160)

でも、リアルサーバ達はそんなIP自分達のじゃないので破棄しちゃう。

これが接続できない原因。当たり前のことなんだよ。


■リアルサーバへ到着したパケットのdestination IPを書き換える
#iptables -t nat -A PREROUTING -d 192.168.24.160 -j REDIRECT

destination IP をリアルサーバの物に書き換えて自分(リアルサーバ)に
渡してあげれば、問題無く受け取れるようになる。

ここではiptablesについては詳しくは書かないが、
PREROUTINGはそのマシンのNICに到着したパケットを
最初に処理するところだと思っておけば間違いは無い。

そして!つぎに!PROXY(リアルサーバ)がインターネットへパケットを投げるとき!
(正確にはdefault gw経由だけど)
パケットのsource IP は クライアントのIPアドレスだ!!!
これがDSRの魅力だ。

PROXYからgatewayへ渡されたパケットはアドレス変換してインターネットに出て行くが、
変換元のsouce IPはクライアントIPアドレスだ!!!
これがDSRの魅力だ。

インターネットから帰ってきたパケットはgatewayで変換テーブルに覚えておいた物に
変換すると思うのだけど、このときにdestination IPアドレスをクライアントのIPに
変換してくれる。(ごく普通のIPマスカレードの動作)

結果、gatewayはLVSやPROXYを経由せずにクライアントにパケットを送ったとさ。
めでたしめでたし。



このまま再起動するとipvsadmの設定消えます。

■ipvsadm設定保存
#/etc/init.d/ipvsadm save
#cat /etc/ipvsadm.rules
# ipvsadm.rules
-A -t 192.168.24.160:8080 -s rr
-a -t 192.168.24.160:8080 -r 10.10.10.10:8080 -g -w 1
-a -t 192.168.24.160:8080 -r 10.10.10.20:8080 -g -w 1

ipvsadmは起動時に/etc/ipvsadm.rulesの中身を自動設定してくれる。
再起動してちゃんと設定されてるか確認しとこう。

#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.24.160:8080 rr
-> 10.10.10.10:8080 Route 1 0 0
-> 10.10.10.20:8080 Route 1 0 0

ちゃんと設定されていた。

PROXY側のiptablesも起動時に読み込むようにしておこう。
再起動後にも、正常に動作していることを確認しておこう。

以上、LVSの設定はこんな感じ。
ただ、この状態だとLVSはダウンしているリアルサーバにも遠慮なくパケットを投げつける。
そこでkeepalivedの登場。LVSからkeepalivedを使ってリアルサーバを監視して、
応答が無かったりしたらipvsの設定からはずしたりする設定をしてやる。

お楽しみに。

0 件のコメント:

コメントを投稿