Gentoo Linux フェイルオーバーガイド|  
このガイドではHeartbeatとDRBDを用いてフェイルオーバシステムを構築する方法を解説します。
 |  
 
 
 
  
フェイルオーバとは?  
フェイルオーバとは、サーバに障害が発生した時に待機系サーバが処理を引き継ぐことにより、サービスのダウンタイムを軽減し、高可用性を実現する機能の事です。 
このドキュメントでは、Gentoo Linuxが予めインストールされた運用系・待機系の2台のサーバの上に、HeartbeatとDRBDというソフトウェアを用いてフェイルオーバシステムを構築します。
 
Heartbeatとは?  
Heartbeatは、サーバの障害を検知し、IPアドレスやサービスの引継ぎを実現するソフトウェアです。 
詳細は、Ultra Monkey: Heartbeatが参考になります。
 
DRBDとは?  
DRBDは、ブロックデバイスをネットワークを介してミラーリングするソフトウェアです。 
DRBDを利用することにより、障害発生時にデータを引き継ぐ事が可能になります。 
詳細は、DRBD HOWTOが参考になります。
 
2.インストール
前提  
- 運用系のサーバのホスト名はsrv01、IPアドレスは192.168.1.101とします。
 
- 待機系のサーバのホスト名はsrv02、IPアドレスは192.168.1.102とします。
 
- フェイルオーバの対象とするIPアドレスは192.168.4.11とします。 srv01がダウンした場合、このIPアドレスは自動的にsrv02に引き継がれ、外部からはサーバが稼動し続けているように見えます。
 
- DRBDはLVMのボリューム上に構築します。 LVMについての詳細はGentoo LVM2インストールが参考になります。
 
- UNIXユーザアカウントの情報をフェイルオーバに対応させる為に、LDAPによるユーザ認証を用います。
 
- HTTPサーバはApache2、FTPサーバはProFTPD、LDAPサーバはOpenLDAP、DBサーバはMySQL/PostgreSQL、DNSサーバはBIND、メールサーバはCourierで構築します。
 
 
インストール  
前提となるUSEフラグは以下の通りです。 
| 
								Code listing 2.1: USEフラグ |  
apache2 bzlib cjk crypt innodb ldap ldirectord maildir memlimit nls \
pam readline xml xml2 zlib
  |  
 
パッケージをインストールします。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 2.2: インストール |  
# cd /usr/src
# ln -s linux-`uname -r` linux
# emerge drbd heartbeat =apache-2* openldap nss_ldap pam_ldap \
	mysql postgresql bind courier
# 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
  |  
 
Note: DRBDのコンパイルには、現在使用しているカーネルのソースディレクトリから/usr/src/linuxへシンボリックリンクを張っておく必要があります。  |   
Note: DRBD 0.6はkernel 2.6に対応していないため、2.4である必要があります。  |   
Note: DRBDはカーネルモジュールとしてコンパイルされるので、カーネルモジュールを有効にしている必要があります。  |   
Note: ※ proftpd-1.2.10に付属のmod_ldapは、LDAPv3に未対応のようだったので、対応しているバージョンのmod_ldapを使うように変更してあります。 
また、一部のFTPクライアントソフトがファイル一覧の取得に使うNLST命令に対応する為のパッチを当てています。  |   
Heartbeatのresourceスクリプト  
Heartbeatでは、各サーバアプリケーションの起動・終了処理を/etc/ha.d/resource.dに配置されているシェルスクリプトを通して行います。 
このドキュメントでは、設定の柔軟性を高める為に独自のresourceスクリプトを用いています。 
このスクリプトは以下の手順でインストール可能です。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 2.3: resourceスクリプト |  
srv01/02# cd /etc/ha.d/resource.d
srv01/02# wget http://documents.dokukino.com/jpdoc/resource_scripts.tar.bz2
srv01/02# tar xvjpf resource_scripts.tar.bz2
  |  
 
Note: 詳細な使用方法は、設定の章で説明します。  |   
前提  
サーバアプリケーションをフェイルオーバする為に必要な全てのデータ・コンフィグレーションは、/mnt/[DRBDリソース名]/[アプリケーション名]に保存する事とします。
 
Note: 
drbdデバイス内のファイル・ディレクトリのオーナに注意しなければいけません。 
同じユーザ名・グループ名でも、サーバ間でuid・gidが違う場合、正常に認識されないのでサーバアプリケーションが実行できない恐れがあります。
Gentoo Linuxでは、サーバアプリが利用するユーザ名・グループ名のuid・gidは固定されているのでこれを使用しますが、異なるディストリビューションやパッケージ管理システムを用いずにサーバアプリをインストールし、ユーザを追加した場合、サーバ間のuid・gidを合わせておくか、ldap上にユーザを作成する必要があります。
  |   
下準備  
DRBD用のLVMボリュームを作成します。 
予めLVMがセットアップされている必要があります。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.1: DRBD用ボリュームの作成 |  
# lvcreate -n drbd0 -L 2G vg0
  |  
 
Note: 
LVMはDRBDに必須という訳では有りません。 
一般的な/dev/hda4などのパーティーションを利用する事も可能です。 
また、LVMのボリュームも空きのパーティーション領域も無ければ、ループバックデバイスを使うという方法もあります。
  |   
DRBD  
初めに、drbd.confを作成します。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.2: /etc/drbd.conf |  
resource drbd0 {
    protocol=C
    fsckcmd=fsck.reiserfs -y
    disk {
        do-panic
        disk-size = 2097152
    }
    net {
        sync-min=600M
        sync-max=600M
    }
    on srv01 {
        device=/dev/nbd/0
        disk=/dev/vg0/drbd0
        address=192.168.1.101
        port=7788
    }
    on srv02 {
        device=/dev/nbd/0
        disk=/dev/vg0/drbd0
        address=192.168.1.102
        port=7788
    }
}
 |  
 
次に、srv01でdrbdを有効化します。
 
| 
								Code listing 3.3: [srv01] /drbd drbd0 start |  
srv01# /drbd drbd0 start
Setting up 'drbd0' .. disk ok .. net .. OK
Do you want to abort waiting for other server and make this one primary?
[リターン]
still waiting:
        drbdsetup /dev/nbd/0 wait_connect -t 0
Answer either "yes" or not at all: yes
 |  
 
一定時間を経過しても、ミラー先サーバと接続が出来ない場合、上記のようなメッセージが出ます。 
ここでは、未だsrv02を立ち上げていないのでyesと入力してください。 
続けて、srv02でdrbdを有効化してください。
 
Note: そのまま待機させておいても、ミラー先と接続が確立すれば正常起動します。  |   
| 
								Code listing 3.4: [srv02] /drbd drbd0 start |  
srv02# /drbd drbd0 start
Setting up 'drbd0' .. disk ok .. net .. OK
drbd:  drbd0  done.
drbd: 'drbd0' SyncingAll, waiting for this to finish
Sun Jan  9 00:42:03 Local time zone must be set--see zic manual page 2005
0: cs:SyncingAll st:Secondary/Primary ns:0 nr:206476 dw:206480 dr:0 pe:0 ua:1041
        [=>..................] sync'ed: 10.0% (1846/2048)M
        finish: 0:11:30h speed: 2,944 (20,647) K/sec
Waiting for Sync to finish ...
drbd: 'drbd0' SyncingAll finished, issue drbdsetup /dev/nbd/0 secondary_remote
 |  
 
コンフィグレーションが正しければ、drbdデバイスの同期が始まるはずです。 
同期の様子は、以下のようなコマンドで見ることが出来ます。
 
| 
								Code listing 3.5: watch cat /proc/drbd |  
# watch cat /proc/drbd
version: 0.6.12 (api:64/proto:62)
0: cs:SyncingAll st:Primary/Secondary ns:282536 nr:0 dw:0 dr:282540 pe:954 ua:0
        [==>.................] sync'ed: 13.6% (1772/2048)M
        finish: 0:02:23h speed: 21,738 (21,738) K/sec
 |  
 
表示を止めるにはCTRL+Cを入力してください。 
同期が完了するまで暫く掛かりますが、終わるまで待たなくても作業は続行できます。 
次に、srv01をdrbd0のPrimaryサーバにしてください。
 
| 
								Code listing 3.6: [srv01] drbdsetup /dev/nbd/0 primary |  
srv01# cat /proc/drbd
version: 0.6.12 (api:64/proto:62)
0: cs:Connected st:Secondary/Secondary ns:2097152 nr:0 dw:0 dr:2097152 pe:0 ua:0
srv01# drbdsetup /dev/nbd/0 primary
srv01# cat /proc/drbd
version: 0.6.12 (api:64/proto:62)
0: cs:Connected st:Primary/Secondary ns:2097152 nr:0 dw:0 dr:2097152 pe:0 ua:0
  |  
 
/proc/drbdをみると、st:の表示がSecondary/SecondaryからPrimary/Secondaryに変わっているはずです。 
これでdrbdデバイスに書き込みを行う事が出来るようになりました。
 
Note: 
DRBDでは、書き込みに対する排他制御が行われており、同時に両方のサーバからDRBDデバイスに対する書き込みを行う事は出来ません。 
書き込みが可能なのはPrimaryのサーバのみです。
  |   
書き込めるようになったので、早速フォーマットを行う事にします。 
今回は、ファイルシステムにReiserFSを用いることにしました。
 
| 
								Code listing 3.7: [srv01] mkreiserfs /dev/nbd/0 |  
srv01# mkreiserfs /dev/nbd/0
  |  
 
マウントポイントを作成し、fstabに加えます。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.8: mkdir /mnt/drbd0 |  
# mkdir /mnt/drbd0
  |  
 
| 
								Code listing 3.9: /etc/fstab |  
/dev/nbd/0              /mnt/drbd0      reiserfs        noauto,noatime,notail  0 0
  |  
 
srv01でDRBDデバイスをマウントします。
ホームディレクトリを作成します。
フェイルオーバに対応させるユーザのホームディレクトリは、このディレクトリ内に作成してください。
 
| 
								Code listing 3.10: [srv01] mount /mnt/drbd0 |  
# mount /mnt/drbd0
# mkdir /mnt/drbd0/home
# mkdir /mnt/drbd0/init
  |  
 
起動時に、drbdを起動させる必要があります。 
これを怠ると、Heartbeatがdrbdデバイスをマウントできず、フェイルオーバが機能しなくなります。 
この作業は両方のサーバで行う必要があります。 
| 
								Code listing 3.11: /etc/conf.d/drbd |  
DRBD=/drbd
DRBDDEV=drbd0
  |  
 
| 
								Code listing 3.12: rc-update |  
# rc-update add drbd default
  |  
 
Note: 複数のDRBDデバイスに対応させる場合、initスクリプトを修正する必要があります。 こちらからダウンロード出来ます。 
また、複数のデバイスをサポートする場合のconf.dは以下のようになります。 DRBD=/drbd 
DRBDDEV=”drbd0 drbd1”  |   
Apache  
Apacheの設定・データを/mnt/drbd0/apache2に用意します。 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.13: [srv01] /mnt/drbd0/apache2に設定・データを用意する |  
srv01# mkdir /mnt/drbd0/apache2
srv01# cd /mnt/drbd0/apache2
srv01# mkdir logs run
srv01# ln -s /usr/lib/apache2/build ./
srv01# ln -s /usr/lib/apache2-extramodules ./extramodules
srv01# ln -s /usr/lib ./
srv01# ln -s /usr/lib/apache2/modules ./
srv01# cd -a /etc/apache2/conf ./
srv01# cp -a /var/www ./
  |  
 
apache2.conf、commonapache2.confを参考にして、パスを書き換えた設定ファイルを作成します。
 
| 
								Code listing 3.14: [srv01] /mnt/drbd0/apache2/conf/apache2.conf |  
ServerRoot /mnt/drbd0/apache2
PidFile run/apache2.pid
DocumentRoot /mnt/drbd0/apache2/www/localhost/htdocs
  |  
 
| 
								Code listing 3.15: [srv01] /mnt/drbd0/apache2/conf/commonapache2.conf |  
<IfModule mod_alias.c>
    Alias /icons/ /mnt/drbd0/apache2/www/localhost/icons/
    Alias /doc /usr/share/doc
    ScriptAlias /cgi-bin/ /mnt/drbd0/apache2/www/localhost/cgi-bin/
    ScriptAlias /protected-cgi-bin/ /mnt/drbd0/apache2/www/localhost/protected-cgi-bin/
    ScriptAliasMatch ^/~([^/]*)/cgi-bin/(.*) /mnt/drbd0/home/$1/public_html/cgi-bin/$2
    <IfModule mod_perl.c>
	Alias /perl/ /mnt/drbd0/apache2/www/localhost/perl/
	Alias /cgi-perl/ /mnt/drbd0/apache2/www/localhost/perl/
    </IfModule>
</IfModule>
<IfModule mod_deflate.c>
	<Directory "/mnt/drbd0/apache2/www/localhost/htdocs/manual">
<Directory /mnt/drbd0/apache2/www/localhost/htdocs>
	
<Directory /mnt/drbd0/apache2/www/localhost/perl>
<Directory /mnt/drbd0/apache2/www/localhost/cgi-bin>
<Directory /mnt/drbd0/apache2/www/localhost/protected-cgi-bin>
<Directory /mnt/drbd0/home/*/public_html>
<Directory /mnt/drbd0/home/*/public_html/cgi-bin>
<IfModule mod_perl.c>
    <Directory /mnt/drbd0/home/*/public_html/perl>
	
<Directory /mnt/drbd0/apache2/www/localhost/icons>
<IfModule mod_alias.c>
AliasMatch ^/manual(?:/(?:de|en|fr|ja|ko|ru))?(/.*)?$ \
"/mnt/drbd0/apache2/www/localhost/htdocs/manual/$1"
<Directory "/mnt/drbd0/apache2/www/localhost/htdocs/manual">
 |  
 
webapp-configを使う場合、VHOST_ROOTを以下のように書き換えます。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.16: /etc/vhosts/webapp-config |  
VHOST_ROOT="/mnt/drbd0/apache2/www/${G_HOSTNAME}"
 |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.17: [srv01] /mnt/drbd0/init/apache2 |  
OPTS="-D PHP4"
SERVERROOT=/mnt/drbd0/apache2
CONFIGFILE=conf/apache2.conf
PIDFILE=/mnt/drbd0/apache2/run/apache2.pid
  |  
 
ProFTPD  
ProFTPDの設定・データを/mnt/drbd0/proftpdに用意します。
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.18: [srv01] /mnt/drbd0/proftpdに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/proftpd
srv01# cd /mnt/drbd0/proftpd
srv01# mkdir conf log run
  |  
 
proftpd.conf.distrib等を参考にして、proftpd.confを作成します。
 
| 
								Code listing 3.19: [srv01] /mnt/drbd0/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.11
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
ScoreboardFile                  /mnt/drbd0/proftpd/log/scoreboard
TransferLog             /mnt/drbd0/proftpd/log/xferlog
LogFormat               default "%h %l %u %t \"%r\" %s %b"
LogFormat               auth    "%v [%P] %h %t \"%r\" %s"
LogFormat               write   "%h %l %u %t \"%r\" %s %b"
ExtendedLog             /mnt/drbd0/proftpd/log/access_log    WRITE,READ write
ExtendedLog             /mnt/drbd0/proftpd/log/auth_log      AUTH auth
ExtendedLog             /mnt/drbd0/proftpd/log/paranoid_log  ALL default
PidFile                                 /mnt/drbd0/proftpd/run/proftpd.pid
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.20: [srv01] /mnt/drbd0/init/proftpd |  
CONFIGFILE=/mnt/drbd0/proftpd/conf/proftpd.conf
PIDFILE=/mnt/drbd0/proftpd/run/proftpd.pid
  |  
 
OpenLDAP(サーバ)  
OpenLDAPの設定・データを/mnt/drbd0/openldapに用意します。
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.21: [srv01] /mnt/drbd0/openldapに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/openldap
srv01# cd /mnt/drbd0/openldap
srv01# mkdir conf data run
srv01# cp -a /etc/openldap/schema conf/
srv01# cp -a /etc/openldap/ssl conf/
  |  
 
slappasswdで暗号化されたパスワードを生成します。 
このツールは、ユーザアカウントを生成する際にも使用します。
 
| 
								Code listing 3.22: [srv01] slappasswd |  
srv01# slappasswd
New password: [パスワード]
Re-enter new password: [パスワード]
{SSHA}*******************************
 |  
 
slapd.confを参考にして、パスを書き換えます。
 
| 
								Code listing 3.23: [srv01] /mnt/drbd0/openldap/conf/slapd.conf |  
include /mnt/drbd0/openldap/conf/schema/core.schema
include /mnt/drbd0/openldap/conf/schema/corba.schema
include /mnt/drbd0/openldap/conf/schema/cosine.schema
include /mnt/drbd0/openldap/conf/schema/inetorgperson.schema
include /mnt/drbd0/openldap/conf/schema/java.schema
include /mnt/drbd0/openldap/conf/schema/misc.schema
include /mnt/drbd0/openldap/conf/schema/nis.schema
include /mnt/drbd0/openldap/conf/schema/openldap.schema
pidfile         /mnt/drbd0/openldap/run/slapd.pid
argsfile        /mnt/drbd0/openldap/run/slapd.args
database        bdb
suffix  "dc=cluster1,dc=dokukino,dc=com"
rootdn  "cn=manager,dc=cluster1,dc=dokukino,dc=com"
rootpw [slappasswdで暗号化したパスワード]
directory       /mnt/drbd0/openldap/data
index   objectClass             pres,eq
index   cn,sn,uid               eq
index   uidNumber,gidNumber,memberUid   eq
index   oncRpcNumber,ipServicePort      eq
index   ipNetworkNumber,ipHostNumber    eq
access to attribute=userPassword
        by self write
        by dn="cn=manager,dc=cluster1,dc=dokukino,dc=com" write
        by anonymous auth
        by * none
access to *
        by self write
        by dn="cn=manager,dc=cluster1,dc=dokukino,dc=com" write
        by * read	
 |  
 
LDAPツリーに、ユーザとグループのオブジェクトを作成します。 
| 
								Code listing 3.24: [srv01] ~/root.ldif |  
dn: dc=cluster1,dc=dokukino,dc=com
objectClass: dcObject
objectClass: organization
o: cluster1
dc: cluster1
  |  
 
| 
								Code listing 3.25: [srv01] ~/base.ldif |  
dn: ou=People,dc=cluster1,dc=dokukino,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit
dn: ou=Group,dc=cluster1,dc=dokukino,dc=com
ou: Group
objectClass: top
objectClass: organizationalUnit
  |  
 
| 
								Code listing 3.26: [srv01] slapd start |  
srv01# /usr/lib/openldap/slapd -u ldap -g ldap -f /mnt/drbd0/openldap/conf/slapd.conf
  |  
 
| 
								Code listing 3.27: [srv01] ldapadd |  
srv01# ldapadd -x -D 'cn=manager,dc=cluster1,dc=dokukino,dc=com' -W -f ~/root.ldif
Enter LDAP Password:[パスワード]
adding new entry "dc=cluster1,dc=dokukino,dc=com"
srv01# ldapadd -x -D 'cn=manager,dc=cluster1,dc=dokukino,dc=com' -W -f ~/base.ldif
Enter LDAP Password:[パスワード]
adding new entry "ou=People,dc=cluster1,dc=dokukino,dc=com"
adding new entry "ou=Group,dc=cluster1,dc=dokukino,dc=com"
  |  
 
必要にあわせて、ユーザやグループを追加します。 
| 
								Code listing 3.28: [srv01] ~/group1.ldif |  
dn: cn=group1,ou=Group,dc=cluster1,dc=dokukino,dc=com
cn: group1
gidNumber: 2001
objectClass: top
objectClass: posixGroup
  |  
 
| 
								Code listing 3.29: [srv01] ~/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/drbd0/home/test01
userPassword: [slappasswdで暗号化したパスワード]
shadowMin: -1
shadowMax: 999999
shadowWarning: 7
shadowInactive: -1
shadowExpire: -1
shadowFlag: 0
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
  |  
 
| 
								Code listing 3.30: [srv01] ldapadd |  
srv01# ldapadd -x -D 'cn=manager,dc=cluster1,dc=dokukino,dc=com' -W -f ~/group1.ldif
Enter LDAP Password:[パスワード]
adding new entry "ou=People,dc=cluster1,dc=dokukino,dc=com"
srv01# ldapadd -x -D 'cn=manager,dc=cluster1,dc=dokukino,dc=com' -W -f ~/test01.ldif
Enter LDAP Password:[パスワード]
adding new entry "cn=test01,ou=Group,dc=cluster1,dc=dokukino,dc=com"
srv01# mkdir /mnt/drbd0/home/test01
srv01# chown test01:group1 /mnt/drbd0/home/test01
  |  
 
| 
								Code listing 3.31: [srv01] killall slapd |  
srv01# killall slapd
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.32: [srv01] /mnt/drbd0/init/slapd |  
CONFIGFILE=/mnt/drbd0/openldap/conf/slapd.conf
PIDFILE=/mnt/drbd0/openldap/run/slapd.pid
#LISTEN="ldap://192.168.4.11"
  |  
 
OpenLDAP(クライアント)  
OpenLDAPによる認証を有効化します。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 3.33: /etc/nssswitch.conf |  
passwd:      files ldap
shadow:      files ldap
group:       files ldap
hosts:       files dns
networks:    files dns
services:    db files
protocols:   db files
rpc:         db files
ethers:      db files
netmasks:    files
netgroup:    files
bootparams:  files
automount:   files
aliases:     files
  |  
 
| 
								Code listing 3.34: /etc/pam.d/system-auth |  
#%PAM-1.0
auth       required     /lib/security/pam_env.so
auth       sufficient   /lib/security/pam_unix.so likeauth nullok
auth       sufficient   /lib/security/pam_ldap.so use_first_pass
auth       required     /lib/security/pam_deny.so
account    required     /lib/security/pam_unix.so
account    sufficient   /lib/security/pam_ldap.so
password   required     /lib/security/pam_cracklib.so retry=3
password   sufficient   /lib/security/pam_unix.so nullok md5 shadow use_authtok
password   sufficient   /lib/security/pam_ldap.so use_authok
password   required     /lib/security/pam_deny.so
session    required     /lib/security/pam_limits.so
session    required     /lib/security/pam_unix.so
session    optional     /lib/security/pam_ldap.so
  |  
 
| 
								Code listing 3.35: /etc/ldap.conf |  
host 192.168.4.11
base dc=cluster1,dc=dokukino,dc=com
pam_password exop
  |  
 
MySQL  
MySQLの設定・データを/mnt/drbd0/mysqlに用意します。 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.36: [srv01] /mnt/drbd0/mysqlに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/mysql
srv01# cd /mnt/drbd0/mysql
srv01# mkdir conf data log run
srv01# chown mysql:mysql data log run
  |  
 
my.cnfを参考にして、パスを書き換えます。 
| 
								Code listing 3.37: [srv01] /mnt/drbd0/mysql/conf/my.cnf |  
[client]
port            = 3306
socket          = /mnt/drbd0/mysql/run/mysqld.sock
[safe_mysqld]
err-log         = /mnt/drbd0/mysql/log/mysql.err
[mysqld]
user            = mysql
pid-file        = /mnt/drbd0/mysql/run/mysqld.pid
socket          = /mnt/drbd0/mysql/run/mysqld.sock
log-error       = /mnt/drbd0/mysql/log/mysqld.err
basedir         = /usr
datadir         = /mnt/drbd0/mysql/data
tmpdir          = /tmp
language        = /usr/share/mysql/english
skip-locking
set-variable    = key_buffer=16M
set-variable    = max_allowed_packet=1M
set-variable    = thread_stack=128K
bind-address    = 127.0.0.1
port            = 3306
[mysqldump]
quick
set-variable    = max_allowed_packet=1M
[isamchk]
set-variable    = key_buffer=16M
  |  
 
DBを初期化し、drbdデバイスにコピーします。 
| 
								Code listing 3.38: [srv01] mysql_install_db |  
srv01# mysql_install_db
srv01# cp -a /var/lib/mysql/* ./data/
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.39: [srv01] /mnt/drbd0/init/mysql |  
CONFIGFILE=/mnt/drbd0/mysql/conf/my.cnf
PIDFILE=/mnt/drbd0/mysql/run/mysqld.pid
  |  
 
PostgreSQL  
PostgreSQLの設定・データを/mnt/drbd0/mysqlに用意します。 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.40: [srv01] /mnt/drbd0/potgresqlに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/postgresql
srv01# cd /mnt/drbd0/postgresql
srv01# mkdir data
srv01# chown postgres:postgres data
srv01# su postgres initdb -E EUC_JP -D /mnt/drbd0/postgresql/data
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.41: [srv01] /mnt/drbd0/init/postgresql |  
PGDATA=/mnt/drbd0/postgresql/data
PGLOG=/mnt/drbd0/postgresql/data/postgresql.log
PGUSER=postgres
PGOPTS=""
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.42: [srv01] /mnt/drbd0/init/pg_autovacuum |  
PGUSER=postgres
PG_AUTOVACUUM_LOG=/mnt/drbd0/postgresql/data/pg_autovacuum.log
VACUUM_BASE=1000
VACUUM_SCALE=2
SLEEP_BASE=300
SLEEP_SCALE=2
  |  
 
BIND  
BINDの設定・データを/mnt/drbd0/bindに用意します。 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.43: [srv01] /mnt/drbd0/bindに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/bind
srv01# cd /mnt/drbd0/bind
srv01# mkdir conf run zone
srv01# cp -a /var/bind/* zone/
srv01# chown named:named run zone
  |  
 
named.confを参考にして、パスを書き換えます。 
| 
								Code listing 3.44: [srv01] /mnt/drbd0/bind/conf/named.conf |  
options {
        directory "/mnt/drbd0/bind/zone";
        listen-on-v6 { none; };
        listen-on { 127.0.0.1; };
        pid-file "/mnt/drbd0/bind/run/named.pid";
};
zone "." IN {
        type hint;
        file "named.ca";
};
zone "localhost" IN {
        type master;
        file "pri/localhost.zone";
        allow-update { none; };
        notify no;
};
zone "127.in-addr.arpa" IN {
        type master;
        file "pri/127.zone";
        allow-update { none; };
        notify no;
};
 |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.45: /mnt/drbd0/init/named |  
CONFIGFILE="/mnt/drbd0/bind/conf/named.conf"
PIDFILE="/mnt/drbd0/bind/run/named.pid"
CPU="1"
OPTS=""
  |  
 
Courier  
Warning: 
この項は未完成です。 
この通りに設定しても、正常に動作しない可能性があります。
  |   
Courierの設定・データを/mnt/drbd0/courierに用意します。 
/mnt/drbd0の中のファイルの設定は、全てsrv01から行います。
 
| 
								Code listing 3.46: [srv01] /mnt/drbd0/courierに設定・データを用意する |  
srv01# mkdir /mnt/drbd0/courier
srv01# cd /mnt/drbd0/courier
srv01# mkdir conf run
srv01# chown mail:mail run
srv01# cp -a /etc/courier/* conf/
srv01# cp -a /var/lib/courier data
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.47: [srv01] /mnt/drbd0/init/courier |  
prefix="/usr"
exec_prefix="/usr/bin"
sysconfdir="/mnt/drbd0/courier/conf"
bindir="/usr/bin"
sbindir="/usr/sbin"
libexecdir="/usr/lib/courier"
datadir="/usr/share/courier"
rundir="/mnt/drbd0/courier/run"
initdir="/etc/ha.d/resource.d"
  |  
 
NFS(サーバ)  
Warning: 
この項は未完成です。 
この通りに設定しても、正常に動作しない可能性があります。
  |   
初めに、ディレクトリを作成します。 
| 
								Code listing 3.48: [srv01] ディレクトリを作成 |  
srv01# mkdir -p /mnt/drbd0/nfs/data
srv01# mkdir /mnt/drbd0/nfs/conf
  |  
 
exportsを作成します。
  
| 
								Code listing 3.49: [srv01] /mnt/drbd0/nfs/conf/exports |  
/mnt/drbd0/nfs/data 192.168.4.0/255.255.255.0(rw,no_root_squash,async)
  |  
 
Heartbeatのresourceスクリプトに対応する変数定義ファイルを用意します。 
| 
								Code listing 3.50: /mnt/drbd0/init/nfs |  
opts="start stop restart reload"
restarting=yes
exportfs=/usr/sbin/exportfs
statd=/sbin/rpc.statd
rquotad=/usr/sbin/rpc.rquotad
nfsd=/usr/sbin/rpc.nfsd
mountd=/usr/sbin/rpc.mountd
exports=/mnt/drbd0/nfs/conf/exports
PORTMAP_OPTS=""
EXPORTFSTIMEOUT=30
  |  
 
NFS(クライアント)  
上記のNFSサーバに対して、アクセスを行うクライアント側の設定です。 
| 
								Code listing 3.51: /etc/fstab |  
192.168.4.11:/mnt/drbd0/nfs/data /mnt/nfs nfs rw,hard,intr 0 0
  |  
 
netmountを起動します。これによって、NFSがマウントされます。 
| 
								Code listing 3.52 |  
# /etc/init.d/netmount restart
  |  
 
Mon  
Heartbeat  
Note: Heartbeatの全ての設定は、両方のサーバで行う必要があります。  |   
初めに、ha.cfを作成します。 
これはHeartbeatの全般的な設定ファイルであり、以下のような内容になります。 
| 
								Code listing 3.53: /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
#serial /dev/ttyS0
#baud 19200
auto_failback on
node srv01
node srv02
debug 1
  |  
 
authkeysは、Heartbeatの認証情報ファイルです。 
以下のように設定します。 
| 
								Code listing 3.54: /etc/ha.d/authkeys |  
auth 1
1 crc
  |  
 
| 
								Code listing 3.55: chmod |  
# chmod 600 /etc/ha.d/authkeys
  |  
 
haresourcesは、Heartbeatのリソース情報ファイルです。 
	このファイルによって、フェイルオーバ対象が決定されます。 
| 
								Code listing 3.56: /etc/ha.d/haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 \
named::/mnt/drbd0/init/named \
slapd::/mnt/drbd0/init/slapd \
mysql::/mnt/drbd0/init/mysql \
postgresql::/mnt/drbd0/init/postgresql \
pg_autovacuum::/mnt/drbd0/init/pg_autovacuum \
apache2::/mnt/drbd0/init/apache2 \
proftpd::/mnt/drbd0/init/proftpd \
courier::/mnt/drbd0/init/courier \
nfs::/mnt/drbd/init/nfs
  |  
 
Heartbeatを起動します。 
| 
								Code listing 3.57: /drbd stop |  
# /etc/init.d/heartbeat start
# tail -f /var/log/ha-debug
  |  
 
LVMボリュームをセットアップするディスクスペースが無く、DRBDに割り当て可能なパーティーションも無い場合  
既に全てのディスク領域に一般的なパーティーションを作成しており、LVMボリュームをセットアップするディスクスペースも無く、DRBDに割り当て可能なパーティーションも無い場合、DRBDを構築する事が不可能に思われるかもしれません。 
このような場合、よく使われる方法としてループバックデバイスというものがあります。 
ファイルをブロックデバイスと見立てて利用する方法です。 
パフォーマンスは落ちますが、動作検証が目的であれば、十分に機能します。 
DRBDでループバックを用いるには幾つかの手順を踏む必要があるので、以下ではその方法を説明します。 
最初に、ddコマンドでループバックデバイスとして扱うファイルを作成します。 
count=の部分には、MB単位で容量を入力してください。 
パーティーションのスペースを使い切らないように注意してください。 
| 
								Code listing 4.1: dd |  
# dd if=/dev/zero of=/drbd0.img bs=1M count=1024
# dd if=/dev/zero of=/drbd1.img bs=1M count=512
  |  
 
次に、こちらからinitスクリプトをダウンロードしてください。 
これは/dev/loop*とループバックデバイスとして扱うファイルを関連付ける為に必要なlosetupコマンドを起動時に実行します。 
| 
								Code listing 4.2: wget |  
# cd /etc/init.d
# wget http://documents.dokukino.com/jpdoc/losetup
# chmod a+x losetup
  |  
 
conf.dファイルを作成します。 
ここにファイルとデバイス名、起動時にロードするか否かを記述してください。 
| 
								Code listing 4.3: /etc/conf.d/losetup |  
loop0=/drbd0.img
loop1=/drbd1.img
auto_load="0 1"
  |  
 
最後にlosetupを起動し、runlevelsに登録します。 
| 
								Code listing 4.4: init.d & rc-update |  
# /etc/init.d/losetup start
# rc-update add losetup default
  |  
 
以上の設定で、/dev/loop0は1024MBのブロックデバイスとして、/dev/loop1は512MBブロックデバイスとしてDRBDから扱えるようになりました。 
drbd.confの中でdisk=/dev/loop0と記述して、正しく動作する事を確認してください。 
待機系サーバを活用したい  
運用系・待機系でサーバを分けて設定してしまうと、片方のサーバのみ負荷がかかり、もう片方は遊んでいるという事になるかもしれません。 
drbdデバイスを複数定義しharesourcesを書換えることによって、サービス毎に実行するサーバを別々に出来ます。 
勿論、片方に障害が発生した場合はフェイルオーバがかかり、正常動作中のサーバが全ての処理を引き継ぎます。 
初めに、二つ目のdrbdデバイスを定義します。 
予め、ブロックデバイス(ここでは/dev/vg0/drbd1とします)を用意しておいてください。 
要領は一つの時と変わりません: 
| 
								Code listing 4.5: /etc/drbd.conf |  
resource drbd1 {
    protocol=C
    fsckcmd=fsck.reiserfs -y
    disk {
        do-panic
        disk-size = 2097152
    }
    net {
        sync-min=600M
        sync-max=600M
    }
    on srv01 {
        device=/dev/nbd/1
        disk=/dev/vg0/drbd1
	address=192.168.1.101
        port=7789
    }
    on srv02 {
        device=/dev/nbd/1
        disk=/dev/vg0/drbd1
        address=192.168.1.102
        port=7789
    }
}
 |  
 
フォーマット・マウントポイントの設定は同じですので省略します。 
drbd0、drbd1を同時にマウントして、データをコピーしてきましょう。 
Warning: Heartbeatは終了しておいてください。  |   
| 
								Code listing 4.6: mv |  
# /drbd restart
# /etc/ha.d/resource.d/datadisk drbd0 start
# /etc/ha.d/resource.d/datadisk drbd1 start
# cp -a /mnt/drbd0/bind /mnt/drbd1
# cat /mnt/drbd0/init/named |sed -e "s/drbd0/drbd1/g" > /mnt/drbd1/init/named
  |  
 
Note: 多くの設定ファイルにもdrbd0を含むパスが含まれています。 
initファイルと同様に、それらも書換える必要があります。  |   
haresourcesを変更します。 
この作業は両方のサーバで行う必要があります。
 
| 
								Code listing 4.7: /etc/ha.d/haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 \
slapd::/mnt/drbd0/init/slapd \
mysql::/mnt/drbd0/init/mysql \
postgresql::/mnt/drbd0/init/postgresql \
pg_autovacuum::/mnt/drbd0/init/pg_autovacuum \
apache2::/mnt/drbd0/init/apache2 \
proftpd::/mnt/drbd0/init/proftpd \
courier::/mnt/drbd0/init/courier
srv02 192.168.4.12/24 datadisk::drbd1 \
named::/mnt/drbd1/init/named
  |  
 
一度全てのdrbdを停止し、Heartbeatを起動します。 
| 
								Code listing 4.8: /drbd stop |  
# umount /mnt/drbd0
# umount /mnt/drbd1
# /drbd stop
# /etc/init.d/heartbeat start
# tail -f /var/log/ha-debug
  |  
 
同じサーバアプリを両方のサーバで動かし、どちらかがダウンしたときにフェイルオーバさせる事は可能?  
このような設定が考えられます: 
| 
								Code listing 4.9: haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 named::/mnt/drbd0/init/named
srv02 192.168.4.12/24 datadisk::drbd1 named::/mnt/drbd1/init/named
  |  
 
この設定では、片方のサーバがダウンしているときは、一台のサーバ上で2つのnamedを立ち上げようとします。 
デフォルトの設定では全てのIPアドレスに対してLISTENしようとしてしまいどちらかがソケットを開けず起動できなくなりますが、LISTENするIPをharesourcesに記述したIPアドレスに限定すれば、正常に動作します。
 
Warning: 
複数のサーバ上でアプリケーションを動かし、相互にフェイルオーバをかける場合、UNIXユーザアカウントについて注意ください。 
UNIXアカウントをNSS/PAMを通して認証に使い、かつアカウント情報を別々のLDAPサーバに格納した場合、恐らく正しく動作しないでしょう。 
NSS及びPAMの設定は、アプリケーションのインスタンス毎に設定出来る訳では無く、サーバに対して1つになっているからです。 
これに該当する主なアプリケーションは、Apacheのuserdir・suexec機能です。
  |   
運用系2台:待機系1台の設定は可能?  
Heartbeatは基本的には1:1のフェイルオーバシステムを実現する為のソフトですが、haresourcesの書き方を工夫すれば運用系2台:待機系1台という設定も可能です。 
その場合、運用系のharesourcesにはそのサーバ自身のリソースのみを記述し、待機系のharesourcesには運用系の全てのリソースを記述します。 
| 
								Code listing 4.10: [srv01] haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 apache2::/mnt/drbd0/init/apache2
  |  
 
| 
								Code listing 4.11: [srv02] haresources |  
srv02 192.168.4.12/24 datadisk::drbd1 named::/mnt/drbd1/init/named
  |  
 
| 
								Code listing 4.12: [srv03] haresources |  
srv01 192.168.4.11/24 datadisk::drbd0 apache2::/mnt/drbd0/init/apache2
srv02 192.168.4.12/24 datadisk::drbd1 named::/mnt/drbd1/init/named
  |  
  |