labunix's blog

labunixのラボUnix

IPVSのみでWebサーバをラウンドロビン構成にする。

■IPVSのみでWebサーバをラウンドロビン構成にする。
 keepalivedを導入済みであれば、ipvsadmも入ってます。
 ただし、今回はkeepalivedを使いません。

 Wheezy/Squeezeにkeepalivedを導入、VRRPで仮想IPにアクセス。
 http://d.hatena.ne.jp/labunix/20130618

■IPVSのバージョン確認。
 LVS(Linux Virtual Server)の実装のひとつ。

$ apt-cache show keepalived | grep ipvsadm
Depends: libc6 (>= 2.7), libnl1 (>= 1.1), libpopt0 (>= 1.16), libssl1.0.0 (>= 1.0.0), ipvsadm, iproute

$ sudo apt-get install -y linux-headers-`uname -r`
$ grep IP_VS_VERSION_CODE /usr/src/linux-headers-3.2.0-4-common/include/linux/ip_vs.h
#define IP_VS_VERSION_CODE      0x010201

$ echo -n "v";echo -n "0x010201" | sed s/".."/"&\n"/g | grep -v 0x | sed s/^/0x/g | \
  for n in `xargs`;do echo -n "$(($n)).";done | sed s/"\.\$"/"\n"/
v1.2.1

■IPVSモジュールの確認

$ lsmod | grep ip_vs
ip_vs                 104053  0
nf_conntrack           52720  1 ip_vs
libcrc32c              12426  1 ip_vs

■IPVSバージョンの確認

$ sudo ipvsadm -v
ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)

■IPVS設定の確認

$ sudo ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

■IPVSパケットの統計の確認

$ sudo ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port

■IPVS設定のクリア

$ sudo ipvsadm -C

■設定方法

$ man ipvsadm | grep -A 15 "^EXAMPLE 1"
EXAMPLE 1 - Simple Virtual Service
       The following commands configure a Linux Director to distribute  incom‐
       ing  requests addressed to port 80 on 207.175.44.110 equally to port 80
       on five real servers. The forwarding method used  in  this  example  is
       NAT,  with  each  of  the  real  servers being masqueraded by the Linux
       Director.

       ipvsadm -A -t 207.175.44.110:80 -s rr
       ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.1:80 -m
       ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.2:80 -m
       ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.3:80 -m
       ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.4:80 -m
       ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.5:80 -m

       Alternatively, this could be achieved in a single ipvsadm command.

■以下のような2台のサーバがあります。

$ ip addr | grep /24
    inet 192.168.164.11/24 brd 192.168.164.255 scope global eth0

$ ip addr | grep /24
    inet 192.168.164.10/24 brd 192.168.164.255 scope global eth0

■自分自身で受けて、自分自身とお隣のサーバに順次利用(ラウンドロビン)します。

$ sudo ipvsadm -A -t 192.168.164.11:80 -s rr; \
  sudo ipvsadm -a -t 192.168.164.11:80 -r 192.168.164.11:80 -m; \
  sudo ipvsadm -a -t 192.168.164.11:80 -r 192.168.164.10:80 -m

■Webサーバは単純にapache2を2台のサーバに導入。
 デフォルトのコンテンツにホスト名が出るようにします。

$ sudo apt-get install -y apache2
$ sudo sed -i s/"<h1>"/"`hostname -s`&"/ /var/www/index.html

■動作テスト

$ w3m -dump -no-proxy http://192.168.164.11 | head -1
web1
$ w3m -dump -no-proxy http://192.168.164.11 | head -1
web2

■統計情報の確認
 「LocalAddress」で受けて「RemoteAddress」にほぼ均等に2つのIPに振り分けています。

$ sudo ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  192.168.164.11:80                  16       79       71     7743    11014
  -> 192.168.164.10:80                   8       39       31     3512     5232
  -> 192.168.164.11:80                   8       40       40     4231     5782

■設定の確認
 「rr」はラウンドロビンです。重み付け等の設定はしていません。

$ sudo ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.164.11:http rr
  -> 192.168.164.10:http          Masq    1      0          1
  -> 192.168.164.11:http          Masq    1      0          1

■以下の10種類のバランサーアルゴリズムがある。

$ man ipvsadm | grep -A 52 "\-s, ..scheduler" | \
  grep "^ *[a-z]* *\- *" | grep -v "\-[sp],\|scheduling-method" | \
  sed s/"\: .*"//g | sed s/"^ *"//g | sed s/" - *"/"\t\t"/g | nl -w 2
 1      rr              Round Robin
 2      wrr             Weighted Round Robin
 3      lc              Least-Connection
 4      wlc             Weighted  Least-Connection
 5      lblc            Locality-Based  Least-Connection
 6      lblcr           Locality-Based  Least-Connection   with   Replication:
 7      dh              Destination Hashing
 8      sh              Source Hashing
 9      sed             Shortest Expected Delay
10      nq              Never Queue

■参考
 バランサーアルゴリズムのスケジューリングについては以下が詳しいのだが、
 言い回しが難しい。

 1.8. Linux 仮想サーバー
 https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/5/html/Cluster_Suite_Overview/s1-lvs-overview-CSO.html

■バランサーアルゴリズムのスケジューリングを簡単に、
 一言で説明すると以下のような感じかな。。。

1       rr		順次利用による振り分け(ラウンドロビン)
2       wrr		処理能力に応じたラウンドロビン
3       lc		最小コネクションによる振り分け(Least-Connection/LC)
4       wlc		処理能力に応じたLC
5       lblc		負荷が最も低い順に振り分けるLC
6       lblcr		負荷が最も低い順に振り分けるLC+レプリケーション
7       dh		送信先IPヘッダのハッシュ値による振り分け
8       sh		送信元IPヘッダのハッシュ値による振り分け
9       sed		最短遅延予測による振り分け(Shortest Expected Delay/SED)
10      nq		空いてるRemoteAddressから振り分け、それ以外はSED。