Gentoo Linux 負荷分散ガイド|  
このガイドではLVS,NFS,Heartbeat,Ldirectord,DRBD等のソフトウェアを用いて高可用性を持つ負荷分散システムを構築する方法を解説します。
 |  
 
 
 
  
負荷分散とは?  
負荷分散とは、ロードバランサという装置を介して、Webアクセス等の負荷の大きい処理を複数のサーバに分散する機能の事です。 
このドキュメントでは、Gentoo Linuxが予めインストールされたサーバ群(4台)の上に、 
LVS,Ldirectord,NFS,Heartbeat,DRBD等のソフトウェアを用いて高可用性を持つ負荷分散システムを構築します。
 
高可用性とは?  
一台のサーバの障害によって、システムのダウンが起こらないような稼働率の高いシステムの事です。 
具体的には、障害時にサーバのフェイルオーバを行う等の手法が採られます。 
フェイルオーバに関する詳細な情報は、Gentoo Linux フェイルオーバーガイドを参照してください。
 
LVS(Linux Virtual Server)とは?  
LVSは、複数のサーバを一つの仮想サーバとして扱い、IPレベルの負荷分散をするソフトウェアです。 
LVSをインストールする事により、Linuxサーバ上にロードバランサを実装する事が可能になります。 
詳細は、Ultra Monkey: The Linux Virtual Serverが参考になります。 
LVSには、様々な用途での実績があります(最も良く知られているものとしてはsourceforge.netが挙げられます)。
 
Ldirectordとは?  
Ldirectordは、実サーバ※ に対してHTTP・FTP等のプロトコルでの接続テストを定期的に行い、サーバが正しく動作しているかチェックします。 
サーバが正しく動作していないと判断した場合、LVSに通知してダウンしたサーバへの分散処理を停止します。 
これにより、実サーバがダウンした場合にも影響を受けずに、サービスを続行することが出来ます。 
詳細は、Ultra Monkey: Ldirectordが参考になります。
 
Note: ※実(リアル)サーバ… 分散先のサーバ。実際の処理を受け持つ。以下実サーバと記述  |   
NFSとは?  
UNIX/Linux等のオペレーティングシステムが稼働しているコンピュータ間でファイルを共有する為のプロトコルです。 
Windowsに於けるSMB/CIFS、Macintoshに於けるAFSに相当します。 
詳細は、Linux NFS-HOWTOが参考になります。
 
Heartbeatとは?  
Heartbeatは、サーバの障害を検知し、IPアドレスやサービスの引継ぎを実現するソフトウェアです。 
詳細は、Ultra Monkey: Heartbeatが参考になります。
 
DRBDとは?  
DRBDは、ブロックデバイスをネットワークを介してミラーリングするソフトウェアです。 
DRBDを利用することにより、障害発生時にデータを引き継ぐ事が可能になります。 
詳細は、DRBD HOWTOが参考になります。
 
2.インストール
前提  
- ロードバランサ(運用系)・ファイル/LDAPサーバ(待機系)のホスト名はsrv01、IPアドレスは192.168.1.101とします。
 
- ファイル/LDAPサーバ(運用系)・ロードバランサ(待機系)のホスト名はsrv02、IPアドレスは192.168.1.102とします。
 
- 実サーバは2台あり、それぞれホスト名srv03・IPアドレス192.168.1.103、ホスト名srv04・IPアドレス192.168.1.104とします。
 
- 負荷分散の対象とするIPアドレスは192.168.4.11とします。 このIPアドレスに対するアクセスは、srv03,srv04へ分散されてリダイレクトされます。
 
	また、srv01がダウンした場合、このIPアドレスは自動的にsrv02に引き継がれ、実サーバからはサーバが稼動し続けているように見えます。 
- ファイル/LDAPサーバのIPアドレスは192.168.4.12とします。
 
srv02がダウンした場合、このIPアドレスは自動的にsrv01に引き継がれ、実サーバからはサーバが稼働し続けているように見えます。 
- Heartbeat、DRBD等のフェイルオーバと共通するソフトウェアの設定は、Gentoo Linux フェイルオーバーガイドの設定をベースにしています。
 
これらについての詳細は、このドキュメントでは触れません。 
この事は、負荷分散システムの構築がフェイルオーバシステムの応用である事を意味します。 
 
カーネル構築(ロードバランサ)  
最初に、ロードバランサのカーネルをLVSに対応させます。 
この作業はsrv01/02で行う必要があります。
 
| 
								Code listing 2.1: .config |  
CONFIG_NETFILTER=y
CONFIG_IP_VS=m
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
  |  
 
| 
								Code listing 2.2: カーネルコンパイル |  
srv01/02# make dep clean bzImage modules modules_install && \
          mount /boot && cp arch/i386/boot/bzImage /boot/kernel-2.4.28-gentoo-r5
 |  
 
コンパイルが終わったらgrubやlilo等のBoot Loaderを設定し、再起動してください。 
Note: 
LVSに対応しているカーネルを使用する必要があります。 
現在の2.4の最新版(2.4.28)では既にLVSが含まれていますが、一部のより古いバージョンではパッチを当てる必要があります。
  |   
カーネル構築(実サーバ)  
実サーバでは、隠しデバイスに対応させる為のパッチが必要になります。 
この作業はsrv03/04で行う必要があります。
 
| 
								Code listing 2.3: パッチ適用 |  
srv03/04# cd /usr/src/linux-2.4.28-gentoo-r5
srv03/04# wget http://www.ssi.bg/~ja/hidden-2.4.28-1.diff
srv03/04# patch -p1 < hidden-2.4.28-1.diff
srv03/04# make menuconfig
srv03/04# make dep clean bzImage modules modules_install && \
          mount /boot && cp arch/i386/boot/bzImage /boot/kernel-2.4.28-gentoo-r5
 |  
 
コンパイルが終わったらgrubやlilo等のBoot Loaderを設定し、再起動してください。 
インストール(ロードバランサ)  
前提となるUSEフラグは以下の通りです。 
| 
								Code listing 2.4: USEフラグ |  
apache2 bzlib cjk crypt innodb ldap ldirectord maildir memlimit nls \
pam readline xml xml2 zlib
  |  
 
パッケージをインストールします。 
この作業はsrv01/02で行う必要があります。
 
| 
								Code listing 2.5: インストール |  
# cd /usr/src
# ln -sf linux-`uname -r` linux
# emerge drbd heartbeat ipvsadm nfs-utils
  |  
 
Note: DRBDのコンパイルには、現在使用しているカーネルのソースディレクトリから/usr/src/linuxへシンボリックリンクを張っておく必要があります。  |   
Note: DRBD 0.6はkernel 2.6に対応していないため、2.4である必要があります。  |   
Note: DRBDはカーネルモジュールとしてコンパイルされるので、カーネルモジュールを有効にしている必要があります。  |   
インストール(実サーバ)  
前提となるUSEフラグは以下の通りです。 
| 
								Code listing 2.6: USEフラグ |  
apache2 bzlib cjk crypt innodb ldap ldirectord maildir memlimit nls \
pam readline xml xml2 zlib
  |  
 
パッケージをインストールします。 
この作業はsrv03/04で行う必要があります。
 
| 
								Code listing 2.7: インストール |  
# emerge nfs-utils =apache-* nss_ldap pam_ldap
# cd /usr/local
# wget http://ekinoco.dokukino.com/ekinoco.tbz2
# tar xjf ekinoco.tbz2
# PORTDIR_OVERLAY="/usr/local/ekinoco" USE="ldap" \
emerge ekinoco/net-ftp/proftpd-nlst-ldapv3/proftpd-nlst-ldapv3-1.2.10.ebuild
  |  
 
Heartbeatのresourceスクリプト(ロードバランサ)  
ロードバランサに対してNFSサーバの設定をします。 Gentoo Linux フェイルオーバーガイドを参照してください。 
この作業はsrv01/02で行う必要があります。
 
カーネル(ロードバランサ)  
ロードバランサがパケットをリダイレクトできるように、パケットフォワーディングを有効化します。 
この作業はsrv01/02で行う必要があります。 
| 
								Code listing 3.1: sysctl.conf |  
net.ipv4.ip_forward = 1
  |  
 
| 
								Code listing 3.2: sysctl |  
srv01/02# sysctl -p
  |  
 
カーネル(実サーバ)  
実サーバの隠しインターフェースの設定をします。 
これは、ロードバランサからリダイレクトされてくるパケットが自分宛であると認識させる為に必要です。 
この為にインターフェースlo:0を使用するので、initスクリプトの修正が必要になります。 
この作業はsrv03/04で行う必要があります。
 
| 
								Code listing 3.3: /etc/init.d/net.lo |  
start() {
        ebegin "Bringing ${IFACE} up"
        /sbin/ifconfig lo 127.0.0.1 up 2>/dev/null
		/sbin/ifconfig lo:0 192.168.4.11 netmask 255.255.255.255 up 2>/dev/null
        /sbin/route add -net 127.0.0.0 netmask 255.0.0.0 \
                gw 127.0.0.1 dev lo 2> /dev/null
        eend 0
}
stop() {
        ebegin "Bringing ${IFACE} down"
        /sbin/ifconfig ${IFACE} down &>/dev/null
        eend 0
}
 |  
 
| 
								Code listing 3.4: rc-udate |  
srv03/04# rc-update add net.lo default
  |  
 
また、インターフェースを隠しインターフェースとして設定する為に、sysctl.confに以下の内容を追記し、再ロードします。 
| 
								Code listing 3.5: sysctl.conf |  
net.ipv4.conf.all.hidden = 1
net.ipv4.conf.lo.hidden = 1
  |  
 
| 
								Code listing 3.6: sysctl |  
srv03/04# sysctl -p
  |  
 
DRBD(ロードバランサ)  
ロードバランサに対して、DRBDを設定します。 Gentoo Linux フェイルオーバーガイドを参照してください。 
但し、drbd0と同時にdrbd1を定義して下さい。この事は、ファイル/LDAPサーバとロードバランサを分離する為に必要です。 
この作業はsrv01/02で行う必要があります。
 
NFS(ロードバランサ)  
ロードバランサに対してNFSサーバの設定をします。 Gentoo Linux フェイルオーバーガイドを参照してください。 
但し、drbd1上に設定して下さい。この事は、ファイル/LDAPサーバとロードバランサを分離する為に必要です。 
この作業はsrv01/02で行う必要があります。
 
OpenLDAP(ロードバランサ)  
ロードバランサに対してLDAPサーバの設定をします。 Gentoo Linux フェイルオーバーガイドを参照してください。 
但し、drbd1上に設定して下さい。また、IPアドレスは、192.168.4.12に読み替えてください。 
この事は、ファイル/LDAPサーバとロードバランサを分離する為に必要です。 
この作業はsrv01/02で行う必要があります。
 
ipvsadm(ロードバランサ)  
ipvsadmの設定を/mnt/drbd0/ipvsadmに保存するように設定します。 
(フェイルオーバ時に設定を同期させる為です。) 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.7: [srv01] mkdir |  
srv01# mkdir -p /mnt/drbd0/ipvsadm/data
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.8: [srv01] /mnt/drbd0/init/ipvsadm |  
opts="start stop save"
RULES=/mnt/drbd0/ipvsadm/data/rules
  |  
 
LVSでの負荷分散を設定するには、ipvsadmというLVSの管理コマンドを使う必要があります。 
コマンドは、以下のような非常に単純なものです: 
| 
								Code listing 3.9: [srv01] ipvsadm |  
srv01# ipvsadm -A -t 192.168.4.11:80
srv01# ipvsadm -a -t 192.168.4.11:80 -r 192.168.1.103:80 -g
srv01# ipvsadm -a -t 192.168.4.11:80 -r 192.168.1.104:80 -g
srv01# /etc/ha.d/resource.d/ipvsadm /mnt/drbd0/init/ipvsadm save
  |  
 
Heartbeat/Ldirectord(ロードバランサ)  
最初に、ldirectordの設定をします。 
この作業はsrv01/02で行う必要があります。
 
| 
								Code listing 3.10: /etc/ha.d/ldirectord.cf |  
checktimeout=10
checkinterval=2
autoreload=yes
logfile="local0"
quiescent=yes
virtual=192.168.4.11:80
	#fallback=127.0.0.1:80
	real=192.168.1.103:80 gate
	real=192.168.1.104:80 gate
	service=http
	request="index.html"
	receive="Test Page"
	scheduler=rr
	protocol=tcp
	checktype=negotiate
virtual=192.168.4.11:21
	real=192.168.1.103:21 gate
	real=192.168.1.104:21 gate
	service=ftp
	request="welcome.msg"
	receive="Welcome"
	login="test01"
	passwd=[パスワード]
	scheduler=rr
	#persistent=600
	protocol=tcp
	checktype=negotiate
  |  
 
次に、Heartbeatの設定をします。 
この作業はsrv01/02で行う必要があります。
 
| 
								Code listing 3.11: /etc/ha.d/haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 \
ipvsadm::/mnt/drbd0/init/ipvsadm \
ldirectord::/mnt/drbd0/init/ldirectord
srv02 192.168.4.12/24 datadisk::drbd1 \
nfs::/mnt/drbd1/init/nfs slapd::/mnt/drbd1/init/slapd
  |  
 
| 
								Code listing 3.12: /etc/ha.d/ha.cf |  
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility     local0
keepalive 2
deadtime 10
initdead 120
udpport 694
bcast eth0
auto_failback on
node srv01
node srv02
debug 1
  |  
 
設定が終わったら、Heartbeatを起動しましょう。 
| 
								Code listing 3.13: /etc/init.d/heartbeat |  
srv01/02# /etc/init.d/heartbeat start
srv01/02# tail -f /var/log/ha-debug
  |  
 
NFS(実サーバ)  
実サーバに対してNFSクライアントの設定をします。 Gentoo Linux フェイルオーバーガイドを参照してください。 
但し、drbd1上に設定して下さい。また、IPアドレスは、192.168.4.12に読み替えてください。 
この事は、ファイル/LDAPサーバとロードバランサを分離する為に必要です。 
この作業はsrv03/04で行う必要があります。
 
また、ホームディレクトリを作成しておいてください。 
| 
								Code listing 3.14: mkdir |  
# mkdir /mnt/nfs/home
  |  
 
OpenLDAP(実サーバ)  
実サーバに対してLDAPクライアントの設定をします。 Gentoo Linux フェイルオーバーガイドを参照してください。 
但し、drbd1上に設定して下さい。また、IPアドレスは、192.168.4.12に読み替えてください。 
更に、ユーザの追加例のホームディレクトリを/mnt/nfs/home/[ユーザ名]と読み替えてください。 
この事は、ファイル/LDAPサーバとロードバランサを分離する為に必要です。 
この作業はsrv03/04で行う必要があります。
 
| 
								Code listing 3.15: ~/test01.ldif |  
dn: uid=test01,ou=People,dc=cluster1,dc=dokukino,dc=com
uid: test01
cn: test01
sn: test01
loginShell: /bin/bash
uidNumber: 2001
gidNumber: 2001
homeDirectory: /mnt/nfs/home/test01
shadowMin: -1
shadowMax: 999999
shadowWarning: 7
shadowInactive: -1
shadowExpire: -1
shadowFlag: 0
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
  |  
 
Apache(実サーバ)  
Apacheの設定・データを/mnt/nfsに用意します。 
但し、logとpidファイルはNFS上には置きません。設定とデータのみを共通化します。 
この作業は、全てsrv03から行います。 
| 
								Code listing 3.16: [srv03] /mnt/nfs/apache2に設定・データを用意する |  
srv03# cd /mnt/nfs
srv03# mkdir apache2
srv03# cd apache2/
srv03# mkdir conf www
srv03# ln -s /var/log/apache2 logs
srv03# ln -l /usr/lib/apache2
srv03# ls -l /usr/lib/apache2
srv03# ln -s /usr/lib/apache2/build ./
srv03# ln -s /usr/lib/apache2-extramodules ./extramodules
srv03# ls -l
srv03# ln -s /usr/lib ./
srv03# ln -s /usr/lib/apache2/modules ./
srv03# cd /etc/apache2/conf/
srv03# cp -a magic mime.types modules.d php.ini ssl vhosts /mnt/nfs/apache2/conf/
srv03# cd -
srv03# cp -a /var/www/* www/
  |  
 
apache2.conf、commonapache2.confを参考にして、パスを書き換えた設定ファイルを作成します。
 
| 
								Code listing 3.17: [srv01] /mnt/nfs/apache2/conf/apache2.conf |  
ServerRoot /mnt/nfs/apache2
DocumentRoot /mnt/nfs/apache2/www/localhost/htdocs
  |  
 
| 
								Code listing 3.18: [srv01] /mnt/nfs/apache2/conf/commonapache2.conf |  
<IfModule mod_alias.c>
    Alias /icons/ /mnt/nfs/apache2/www/localhost/icons/
    Alias /doc /usr/share/doc
    ScriptAlias /cgi-bin/ /mnt/nfs/apache2/www/localhost/cgi-bin/
    ScriptAlias /protected-cgi-bin/ /mnt/nfs/apache2/www/localhost/protected-cgi-bin/
    ScriptAliasMatch ^/~([^/]*)/cgi-bin/(.*) /mnt/nfs/home/$1/public_html/cgi-bin/$2
    <IfModule mod_perl.c>
	Alias /perl/ /mnt/nfs/apache2/www/localhost/perl/
	Alias /cgi-perl/ /mnt/nfs/apache2/www/localhost/perl/
    </IfModule>
</IfModule>
<IfModule mod_deflate.c>
	<Directory "/mnt/nfs/apache2/www/localhost/htdocs/manual">
<Directory /mnt/nfs/apache2/www/localhost/htdocs>
	
<Directory /mnt/nfs/apache2/www/localhost/perl>
<Directory /mnt/nfs/apache2/www/localhost/cgi-bin>
<Directory /mnt/nfs/apache2/www/localhost/protected-cgi-bin>
<Directory /mnt/nfs/home/*/public_html>
<Directory /mnt/nfs/home/*/public_html/cgi-bin>
<IfModule mod_perl.c>
    <Directory /mnt/nfs/home/*/public_html/perl>
	
<Directory /mnt/nfs/apache2/www/localhost/icons>
<IfModule mod_alias.c>
AliasMatch ^/manual(?:/(?:de|en|fr|ja|ko|ru))?(/.*)?$ \
"/mnt/nfs/apache2/www/localhost/htdocs/manual/$1"
<Directory "/mnt/nfs/apache2/www/localhost/htdocs/manual">
 |  
 
webapp-configのVHOST_ROOTを以下のように書き換えます。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.19: /etc/vhosts/webapp-config |  
VHOST_ROOT="/mnt/nfs/apache2/www/${G_HOSTNAME}"
 |  
 
conf.dの設定を以下のように書き換えます。 
この作業は、両方のサーバで行う必要があります。
 
| 
								Code listing 3.20: /etc/conf.d/apache2 |  
SERVERROOT=/mnt/nfs/apache2
CONFIGFILE=conf/apache2.conf
PIDFILE=/var/run/apache2.pid
RESTARTSTYLE="graceful"
  |  
 
Apacheを起動します。 
この作業は両方のサーバで行う必要があります。 
| 
								Code listing 3.21: apacheを起動 |  
srv03/04# rc-update add apache2 default
srv03/04# /etc/init.d/apache2 start
  |  
 
ProFTPD(実サーバ)  
ProFTPDの設定・データを/mnt/nfs/proftpdに用意します。
/mnt/nfsの中のファイルの設定は、全てsrv03から行います。
 
| 
								Code listing 3.22: [srv03] /mnt/nfs/proftpdに設定・データを用意する |  
srv03# mkdir -p /mnt/nfs/proftpd/conf
  |  
 
proftpd.conf.distrib等を参考にして、proftpd.confを作成します。
 
| 
								Code listing 3.23: [srv03] /mnt/nfs/proftpd/conf/proftpd.conf |  
ServerName                              "ProFTPD Default Installation"
ServerType                              standalone
DefaultServer                   on
Port                                    21
Umask                                   022
MaxInstances                    30
User                                    proftpd
Group                                   proftpd
DefaultRoot                             ~
AuthPAM                                 off
LDAPServer                              192.168.4.12
LDAPDoAuth                              on "ou=People,dc=cluster1,dc=dokukino,dc=com"
LDAPProtocolVersion             3
LDAPDoUIDLookups                on "ou=People,dc=cluster1,dc=dokukino,dc=com"
LDAPDoGIDLookups                on "ou=Group,dc=cluster1,dc=dokukino,dc=com"
AllowOverwrite                  on
MultilineRFC2228                on
ShowSymlinks                    on
AllowForeignAddress             on
TimesGMT                                off
IdentLookups                    off
UseReverseDNS                   off
ServerIdent                             on ""
AllowStoreRestart               on
AllowRetrieveRestart    on
AllowOverwrite                  on
RequireValidShell               off
DisplayLogin                    welcome.msg
  |  
 
conf.dの設定を以下のように書き換えます。 
この作業は、両方のサーバで行う必要があります。 
| 
								Code listing 3.24: [srv03] /etc/conf.d/proftpd |  
CONFIGFILE=/mnt/nfs/proftpd/conf/proftpd.conf
  |  
 
ProFTPDを起動します。 
この作業は両方のサーバで行う必要があります。 
| 
								Code listing 3.25: proftpdを起動 |  
srv03/04# rc-update add proftpd default
srv03/04# /etc/init.d/proftpd start
  |  
 
ldirectord用に、welcome.msgを配置します。 
| 
								Code listing 3.26: [srv03] welcome.msgを配置 |  
srv03# echo "Welcome" > /mnt/nfs/home/test01/welcome.msg
  |  
  |