LinuxでLVSを用いてロードバランサ(DSR方式)の構築を行う。
LVSとはLinuxでの負荷分散(ロードバランサ)環境構築の為のソリューション。
ラウンドロビン方式や重みづけの設定が楽に行える。
注意点として、LVSでは負荷分散の為の振り分けこそ行うがサーバーダウン時の自動切り離し等の冗長化は行えない。
冗長化を行う為には、LVSをラッパーしたkeepalivedを使用するのが一般的。
参考
http://blog.idcf.jp/entry/cloud/keepalived/
今回は冗長化は行わず、単純なラウンドロビンでの負荷分散を行う。
また転送方式には代表的な所で下記2つがあるが、DSRを採用する。
NAT(Network Address Translation)
クライアントからパケットを受け取ると、送信先とIPアドレスがリアルサーバーのものに置き換えられる。
LVSサーバーを必ず通るのでLVSサーバーの負荷が上がる。
Apache等のアクセスログでのIPアドレスは接続元のIPアドレスになる。
ダイレクト・ルーティング(DSR方式)
クライアントからのパケットを直接リアルサーバーに転送する。
IPアドレスなどは変更されないので、リアルサーバーはエンドユーザーに直接応答を送信する。
LVSサーバーの負荷は下がる。
リアルサーバーも直接クライアントと通信が出来ないといけない。
Apacheなどのアクセスログに残るのはLVSのアドレスになる?(未確認)
負荷分散を行う機器とサービスを提供するサーバは、同一のネットワーク上に置かなければならないという制限がある。
参考
http://k-1-ne-jp.blogspot.jp/2013/02/lvsipvsadm.html
環境
以下3台をVMwareで構築。
- LBサーバー(LVSサーバー)
OS:CentOS6
(eth0)IP:192.168.11.30
(eth1)IP:10.0.10.30
- WEBサーバーA(リアルサーバー)
OS:CentOS6
(eth0)IP:10.0.10.40
- WEBサーバーB(リアルサーバー)
OS:CentOS6
(eth0)IP:10.0.10.111
一般的にロードバランサ構成の場合、ロードバランサ宛先側のバックエンドサーバーを実サーバー(リアルサーバー)というらしい。
手順
WEBサーバー2台での設定作業
デフォルトゲートウェイ設定
バックエンドのWEBサーバーではデフォルトゲートウェイをLBサーバーに設定する必要があるのでその設定。
networkファイル編集
[root@localhost ~]# vi /etc/sysconfig/network
LBサーバーのIPを指定
GATEWAY=10.0.10.30
デフォルトゲートウェイ設定後はサーバー再起動が必要ぽいので注意。
ネットワークインターフェイス毎にデフォルトゲートウェイが異なる場合は
/etc/sysconfig/network-script/ifcfg-eth*
に設定するらしい。
両方に記述しては駄目。
設定ファイル変更で反映されなかったのでrouteコマンドを実行。
※ネットワーク再起動やサーバー再起動で消えるらしいので注意
[root@localhost ~]# route add default gw 10.0.10.30
反映された
[root@web ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.0.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.0.10.30 0.0.0.0 UG 0 0 0 eth0
Apache環境構築
WEBサーバー2台にApacheをインストールし、それぞれのサーバーのレスポンスが分かるようなファイルを配置。
今回は取り敢えず動作確認が取れればいいので簡単にyumでインストール。
インストール
yum install -y httpd
起動
/etc/init.d/httpd start
index.htmlファイル配置
WEBサーバーA
echo server111 > /var/www/html/index.html
WEBサーバーB
echo server40 > /var/www/html/index.html
index.htmlにアクセスすると以下のようにサーバーが分かる。
curl http://localhost server40
最後に、リアルサーバーでiptables設定。
下記のIPはLVSサーバーのIPを指定する。
※この設定はDSR方式の場合のみなので、NAT方式の場合は不要
iptables -t nat -A PREROUTING -d 10.0.10.30 -j REDIRECT
80番ポートも解放
iptables -A INPUT -p tcp ---sport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
LBサーバーでの作業
ipvsadmのインストールと設定を行う。
ipvsadmとはIPVS(IP Virtual Server)を制御するためのツール。 仮想サーバグループの追加やリアルサーバの割り当てができるほか、 現在の接続状況や転送レートの表示などができる。
IPVSadministratorの略?
ipフォワード設定
ipvsadmの設定前に、まずはipフォワードの設定を許可します。
設定
vi /etc/sysctl.conf
値を1に設定する。
net.ipv4.ip_forward = 1
IPv4 転送を有効にする設定。
異なるセグメント間のネットワークを有効にするイメージ。
下記記事が参考なる。
http://d.hatena.ne.jp/eco31/20110221/1298260941
#net.bridge.bridge-nf-call-ip6tables = 0 #net.bridge.bridge-nf-call-iptables = 0 #net.bridge.bridge-nf-call-arptables = 0
設定を反映
※sysctlはカーネルの内部状態を設定、参照するための機能
[root@localhost ~]# sysctl -p net.ipv4.ip_forward = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296
ipvsadmインストール設定
ipvsadm インストール
yum -y install ipvsadm
ipvsadm起動
/etc/rc.d/init.d/ipvsadm start
chkconfig ipvsadm on
仮想サービステーブルをクリア
ipvsadm -C
仮想サービスを登録。
今回は実際のLBサーバーのIPを指定してるけど仮想IPを割り当てるのが一般らしい。
IPアドレス、ポート番号、プロトコルで一意となるようにする。
ここで指定するIPは自身のローカルIP。
「-t」をつける事で、<アドレス>:<ポート番号>と指定できる。
「-s」で分散方法を指定、デフォルトの「wlc: 重み付け最小コネクション数」を使用する。
ipvsadm -A -t 10.0.10.30:80 -s wlc
※参考までに、NAT方式で転送する場合
同一セグメントにはできない為
ipvsadm -A -t 192.168.10.30:80 -s wlc
実サーバーを登録
「-a」で実サーバーを登録
「-t」で仮想サービスを指定
「-r」の後ろに実サーバーを指定
転送オプションの指定として、「-g」でDSRを指定している。
他にも転送方法はあるので、詳細はmanで確認する。
ipvsadm -a -t 10.0.10.30:80 -r 10.0.10.40:80 -g ipvsadm -a -t 10.0.10.30:80 -r 10.0.10.111:80 -g
※参考までに、NAT方式で転送する場合
転送オプションの指定として、「-m」でLVS-NAT(アドレス変換)を指定している。
ipvsadm -a -t 192.168.10.30:80 -r 10.0.10.40:80 -m ipvsadm -a -t 192.168.10.30:80 -r 10.0.10.111:80 -m
仮想サービステーブルを確認
[root@lb ~]# ipvsadm -l IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.10.30:http wlc -> 10.0.10.40:http Masq 1 0 0 -> 10.0.10.111:http Masq 1 0 0
設定を保存
/etc/rc.d/init.d/ipvsadm save
iptables設定
iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --sport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
他サーバーから疎通確認
別でIPが10.0.10.50のクライアント・サーバーを立てて、そちらからアクセス。
ロードバランスされている
今回はラウンドロビンなので交互にアクセスされてる
[root@localhost ~]# curl http://192.168.10.30 server40 [root@localhost ~]# curl http://192.168.10.30 server111
試しにWEBサーバーBをダウンさせてみる。
冒頭で触れた通り、LVSは冗長化には対応してないので、ダウンしてようがアクセスが行く。
冗長化対応の為には別途keepaliveインストールが必要。
[root@localhost ~]# curl http://192.168.10.30 server40 [root@localhost ~]# curl http://192.168.10.30 curl: (7) couldn't connect to host
ハマった所
LVS環境構築後、curlアクセスで固まった場合
curlで固まる場合は、LBサーバーとWEBサーバーどちらかのiptables設定でdropされてる可能性大。
iptablesの設定でDropしたパケットはログ出力する等して地道にポート開放設定すべし。
こんな感じでwebサーバー側のiptablesでINPUTがDropされてる事がある。
Feb 15 19:46:29 web kernel: Dropped by INPUT: IN=eth0 OUT= MAC=00:0c:29:5c:ba:fd:00:0c:29:73:76:73:08:00 SRC=192.168.10.30 DST=10.0.10.40 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=21323 DF PROTO=TCP SPT=45687 DPT=80 WINDOW=65495 RES=0x00 SYN URGP=0
この辺でかなりハマった・・・
上記でも解決しない場合
WEBサーバー側でDSR のバランシングに応答するため、LBサーバーとサーバーへのパケットをリダイレクト処理。
iptables -t nat -A PREROUTING -d 10.0.10.30 -j REDIRECT
但しこの設定は振り分け設定を下記のようなオプション「-g」でDSRとした場合のみ。
「-m」でのnatの場合は不要
ipvsadm -a -t 10.0.10.30:80 -r 10.0.10.111:80 -g
実サーバー登録時にエラー
以下のようなエラーが・・・
ipvsadm -A -t 10.0.10.30:80 -s wl Scheduler or persistence engine not found
ちょっとハマったけど、単純に分散方法の指定がおかしい。
最後のcが足りなかった・・・
イージーミス
下記で解決。
ipvsadm -A -t 192.168.10.30:80 -s wlc
やり残し&続いてやる事
LBサーバーからのアクセス、実サーバー自身からのアクセス時にレスポンスが返ってこない
…何言ってるかわからないと思いますが。
1.LBサーバーから下記のようにアクセスするとレスポンス返ってこない
curl http://10.0.10.30
2.例えば、10.0.10.40サーバーから下記でアクセスした場合、かつ内部的に10.0.10.40自身にロードバランサされた時にレスポンスが返ってこない
(別サーバー10.0.10.111にロードバランサされた時はレスポンスある)
恐らくだけど、下記が理由?
http://qiita.com/nagais/items/b9b1940cdaf9a17b4088
>同一筐体だとLVSMaster機が初回に処理した時にARP登録され、次回以降のリクエストがLVS通らず直接ARP登録されたインターフェースへいくのでダメ。。
んー、違うかも。
これはちょっと調査必要かも。
keepalivedを使用して冗長化構成構築
後日やってみます
メモ
今回、LVSのDSRでロードバランサなのですが、NAT構成の場合LVSのサーバとアプリケーションサーバが同一のネットワークセグメントに存在すると振り分けがうまくいかないらしいので、LBサーバーでは2枚NICを挿すか、trunkやIPエイリアスを用いてネットワークが2つある構成に無いといけないみたいなので要注意。