KeepalivedによるロードバランサLVS構築
LVS構築における最強の手順書を残してみました。
はじめに
ロードバランサ(LVS)の需要は間違いなくあると思うのですが、いかんせんネットに情報が少ない。
かの有名な「サーバ/インフラを支える技術」が出版された2008年あたりがピークの感がある。(Klabさんの記事には大変お世話になりました) Googleで調べてもまとまった情報がなかったりするので、最初は大変でした。
普段インフラ周りで仕事しているので、そこで培ったノウハウを出したいと思います。マイブログ史上最大の情報量。
今回は「CentOS6.4 x86_64マシン」に「最新版keepalived-1.2.7を導入」で「割りと本番運用に耐えられる手順」を解説。もちろん定番のIPVS + Keepalived のDirect Server Return(DSR)構成。
※是非コメント欄でもさらに有益な情報がありましたら歓迎です。
内容
- IP Virtual Server(IPVS)のインストール
- Keepalivedインストール(IPVS用Daemon設定)
- パラメータチューニング
- 重要:LVS設定(リアルサーバ側)
- アプリケーション起動
- リリース後確認
- 注意点ノウハウいろいろ
- 最後に
0. 構成図
今回はVIPで着信して、DSRでレスポンスする形式で実装します。VRRPにより、LVS自体の冗長化も目指します。
1. IP Virtual Server(IPVS)のインストール
パッケージインストール
yum -y install ipvsadm iproute curl
基本的に上記で終了です。
2. Keepalivedインストール(IPVS用Daemon設定)
ソースしかないためrpmを作成し、そこからインストールを実施。
rpmユーザで作成。実はKeepalivedのソースにはRPM作成用のspecファイルなどが予め同梱されているため、活用する。 RPM経由のインストールにより、アンインストールも容易に行えるようにする。
RPMの準備
基本パッケージインストール
#各種ライブラリインストール sudo yum -y install make kernel kernel-devel rpm-build openssl-devel popt popt-devel #RPMユーザになる su rpm; cd $HOME #ソースファイル取得 wget http://www.keepalived.org/software/keepalived-1.2.7.tar.gz tar -xvzf keepalived-1.2.7.tar.gz #任意のディレクトリにコピー(ディレクトリなければ作っときましょう) mkdir -p /home/rpm/rpmbuild/SOURCES/ cp -ar keepalived-1.2.7.tar.gz /home/rpm/rpmbuild/SOURCES/ cd keepalived-1.2.7
specファイル修正
ちゃんとチェックしてリリースしてほしい笑
vim keepalived.spec vim keepalived.spec.in # 1.2.2 => 1.2.7
configure
./configure
make rpm
rpmインストール
正常にいけば、下記のパスにrpmファイルが完成しているはずです。
/home/rpm/rpmbuild/RPMS/x86_64/keepalived-1.2.7-5.x86_64.rpm
そして、以下のコマンドを発行してインストール。
rpm -ivh /home/rpm/rpmbuild/RPMS/x86_64/keepalived-1.2.7-5.x86_64.rpm
注意!
- 独自の設定でKernelコンパイルするため、毎回rpm作成すること!(使い回しをしない)
- 一応以下でrpmが消えるか確認する(変なrpmだと削除出来ない)
Keepalived設定ファイルの編集
以下が設定ファイルなのでLVSの設定を追加する。基本的にkeepalived.confに設定を記載すれば大丈夫ですが、最近のkeepalivedのバージョンではincludeにも対応したので、Webサーバ側のコンフィグ設定を分離させます。
/etc/keepalived/keepalived.conf
global_defs { notification_email { [email protected] } notification_email_from [email protected] smtp_server localhost smtp_connect_timeout 30 router_id lvs01_alert } vrrp_instance VI_1 { state BACKUP #MASTERは絶対に利用せず、全てBACKUPに設定します。 interface eth0 virtual_router_id 51 priority 100 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.105.253 } } include example_real_web_servers.conf
/etc/keepalived/example_real_web_servers.conf
virtual_server_group example_web_servers { 192.168.105.253 80 } virtual_server group example_web_servers { delay_loop 3 lvs_sched lc lvs_method DR protocol TCP #virtualhost example.org #sorry_server 192.168.31.102 80 real_server 192.168.5.111 80 { weight 1 inhibit_on_failure HTTP_GET { url { path /health_check.html #healthチェックページを必ず用意※ status_code 200 } connect_port 80 connect_timeout 3 } } real_server 192.168.5.112 80 { weight 1 inhibit_on_failure HTTP_GET { url { path /health_check.html status_code 200 } connect_port 80 connect_timeout 3 } } }
lvs_methodは必ずDR(ダイレクトルーティング)を選択します。DSRと紛らわしいので注意が必要。 対象となるWebサーバを増やしたい場合は上記のreal_server部分にコピーして追加していけばOK。weight項目でバランシングの割合も微調整できますが、基本的に1で全て共通にするが通常運用です。 (もしweight変更したければ、lvs_schedをwlcに変更も忘れずに)
3. パラメータチューニング
上記の設定だけではDSR構成で動かないため、各種パラメータを調節します。 おまけにチューニング自体も合わせて実施します。
パケット転送設定
/etc/sysctl.conf
net.ipv4.ip_forward = 1 net.ipv4.conf.eth1.rp_filter = 0
rp_filter(Reverse path filtering / 経路フィルタ)とはIPスプーフィング対策のパラメータのことです。 仮にeth0で着信して、それをeth1(privateマシン)でロードバランスする場合、デフォルトだとrp_filterがひっかかりパケットを破棄してしまう。そのため上記の設定を追加し、eth1のrp_filterをOFFにします。
【詳細】Linux Advanced Routing & Traffic Control HOWTO | 戻り経路フィルタ (Reverse Path Filtering)
http://linuxjf.sourceforge.jp/JFdocs/Adv-Routing-HOWTO/lartc.kernel.rpf.html
設定を適応する
sysctl -p service network restart
LVSがファイアウォール機能も兼ねたい場合(iptables時)
LVS自体はご存知の通り、利用されるシーンとしては大量のIPが着信します。そのIP全てに対して、複雑なiptablesを通過しているとあっという間にボトルネックになり、処理が詰まる原因に。
以下で現在利用しているconntrackの状態を見ることが可能。
wc -l /proc/net/nf_conntrack
デフォルトだと64MB = 4096コネクションほどしかさばけない。これより増えて着信すると、IPを弾いてしまう。
そのためiptablesをLVSで利用するときは以下も設定する
net.nf_conntrack_max = 20000000 #CentOS6から名称変更された
最後にこちらも適応
sysctl -p service network restart
【参考】あなたの大量配信サーバ、ip_conntrack溢れていまんか
http://www.e-agency.co.jp/column/20121225.html
ただし個人的なことを言えば、こうしたファイアウォール機能自体は上位の専用ルータで集中的に処理すべきだと思うので、あまり意識してません。応用情報で出てくる「リスク集中」でしょうか。念のため設定はしますが、今のところそれ以上に溢れたケースはないです。
IPv6をOFFにする
利用しないのであれば積極的にOFFにする。
/etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
設定の保存及び再起動
sysctl -p service network restart
/etc/ssh/sshd_config
#AddressFamily any
↓
AddressFamily inet
以下再起動して終了
service sshd restart
【参考】5. How do I disable IPv6?
http://wiki.centos.org/FAQ/CentOS6#head-d47139912868bcb9d754441ecb6a8a10d41781df
NIC設定チューニング
基本的に大量通信を処理するLVSではNICの負荷を軽減させるためOFFにしたほうがベター。 オフロードとはCPUに変わってNICが処理を負担する機能。名前の通り負荷(load)を軽減(off)させてくれます。
デフォルトだとオフロード設定は以下のようになっている。
ethtool -k eth0
Offload parameters for eth0: rx-checksumming: off tx-checksumming: on scatter-gather: on tcp-segmentation-offload: off udp-fragmentation-offload: off generic-segmentation-offload: on generic-receive-offload: on large-receive-offload: off
以下のコマンドを発行して全部OFFにする
ethtool -K eth0 rx off tx off tso off gso off ethtool -K eth1 rx off tx off tso off gso off
【参考】DELLのサーバでCentOS6でLVS+keepalivedなロードバランサを構築したらハマったりした話
http://heartbeats.jp/hbblog/2012/09/dellcentos6lvskeepalived.html
4. 重要:LVS設定(リアルサーバ側)
DSR設定で一番重要です。VIP(VirtualIP)宛のパケットを自分宛として処理出来るようにします。 設定しないとパケットは届くが破棄してしまうので、表示ができません。
iptables -t nat -A PREROUTING -d 192.168.105.253 -j REDIRECT /etc/init.d/iptables save
ここのVIPはWebサービスを受け取るIPです。このVIPを元にLVSはフェイルオーバをします。 DNSにサービスを登録する際は、こちらのVIPを登録して、これ経由でユーザのアクセスを受けるようにします。
もちろん本番稼働には1個だけ必要ですが、私はここに2個VIPを登録しておいています。LVSのテストをする際に、もう片側のVIPを利用してテストして、それでOKが出た場合に本番のVIP設定に書き換えて運用しています。(テストの際はkeepalived.confのvirtual_router_idの変更忘れずに)
5. アプリケーション起動
ついに来ました。
Keepalivedの起動
下記を実行する。(問題があれば停止する)
service keepalived start
以下のコマンドで正常にVIPが動いているか確認。手動でループバックデバイスのIPを設定する記事もありますが、そちらの作業は不要です。 なぜかというと、Keepalived側が勝手に先ほどの作業を実施してくれるため。
ip addr show
IPVSが動いているか確認。watchコマンドを実行して毎秒どれだけバランシングしているかリアルタイムに確認します。フェイルオーバの際はこの数値が徐々にもう片側のLVSに移行しているのを確認することが出来ます。
watch -n1 "ipvsadm -Ln"
そして最後に忘れずにchkconfigで自動起動をon
chkconfig keepalived on
6. リリース後確認
ifconfigを実施し、RX(ReceivedExchange/受信パケット)及びTX(TransmitExchange/送信パケット)の箇所からerrorが出ていないか確認する。
基本的には下記は常に0となっているのが基本。
watch -n 1 "ifconfig" eth0 Link encap:Ethernet HWaddr 00:00:00:05:41:84 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RX packets:807118 errors:0 dropped:0 overruns:0 frame:0 TX packets:947221 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RX bytes:316937897 (302.2 MiB) TX bytes:76153154 (72.6 MiB) Interrupt:24 eth1 Link encap:Ethernet HWaddr 00:00:00:05:41:85 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2028637 errors:0 dropped:0 overruns:0 frame:0 TX packets:1973969 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RX bytes:984257815 (938.6 MiB) TX bytes:176880677 (168.6 MiB) Interrupt:25
問題があれば、auto-negotiation、全二重・半二重、通信速度(1000BASE-T...)含めてethtool(mii-tool)で確認する。
7. 注意点ノウハウいろいろ
色々試行錯誤しながら溜まったノウハウを箇条書きでメモします。
- LVSのVIPサーバ自体にも80番ポートを開けること。そうしないと、そこのアクセスでLinux側から弾かれてしまう。
- LVSは全部BACKUPとして設定すること。(MASTERを作らない)
- 自動フェールバックをしないこと。これにより、不安定な動作を招くことがある。(nopreempt設定)
- ヘルスチェックページを必ず作ること。keepalived.conf側でconfファイルを編集するとどうしても再起動のタイミングで表示にラグが生まれるため、頻繁に編集するのは好ましくない。
/health_check.htmlを作成し、切り離す際にはそのページをmvしてやるだけに設定すると良い。記事書きました - DSR構成であれば、LVS自体がボトルネックになることは殆どないと思っていい。
- NATにすると負荷がすごいことになるので、大規模な所には基本DSRで組む。
- ipvsadmを見て、InactiveConnなどが非常に増えるなどあれば、sysctlの設定でestablishedを破棄するタイミングなどを変更する。広告配信などシビアな業界では全部10秒などに設定されている。
- RPMを使いまわすのはやめよう。動作がおかしくなることが以前にあった。
- VIPを2個用意しておくと、テスト出来るのでGOOD
8. 最後に
ネットワーク図の追加など徐々にしていこうと思います!なのでブックマークも歓迎です。