ラベル Fedora の投稿を表示しています。 すべての投稿を表示
ラベル Fedora の投稿を表示しています。 すべての投稿を表示

2017/02/27

システム起動時のfsck

現状の確認

インストール直後の既定値を確認する。

/etc/fstab

[root@centos01 ~]# cat /etc/fstab | grep /dev/mapper/vg_centos01-lv_root
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]#
第6フィールドが「1」となっている。
この設定では、起動の際にfsck実施条件をチェックし、適宜fsckを実施する。

ボリュームのパラメータ

CentOS 6/RHEL 6の場合、既定ではext4のボリュームは、fsckを実施しない様設定されている。
# ちなみに、CentOS 7/RHEL 7では、既定でxfsのため、起動にfsckは実行されない。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              4
Maximum mount count:      -1
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

現在は、以下の通り設定されていることが判る。
  • マウントされた回数(Mount count)が4、
  • マウント回数によるfsck実行(Maximum mount count)は無し、
  • 最後にfsckが実行されたの(Last checked)が2017.2.23(木) 06:06:05、
  • 経過時間によるfsck実行(Check interval)は無し
結果、既定状態では起動時のfsckは、実行されないことが判る。

マウント回数による条件の検証

Maximum mount countの設定

前に確認した通り、現在のマウント回数は4回なので、Maximum mount countを5に設定する。
[root@centos01 ~]# tune2fs -c 5 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 5
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              3
Maximum mount count:      5
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない場合

再度再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数5回だが、Maximum mount countの設定値5を超えていないため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              5
Maximum mount count:      5
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認2: fsckされる場合

再度再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数6回に達し、Maximum mount countの設定値5を超えるため、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      5
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復旧

設定を元に戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

/fastbootの検証

ファイル/fastbootを作成すると、次回起動時にfsckされなくなることを確認する。

設定

[root@centos01 ~]# tune2fs -c 1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 1
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない場合

/fastbootを作成し、再起動する。
[root@centos01 ~]# touch /fastboot
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数2回で、Maximum mount countの設定値2を超えているが、/fastbootが作成されていたため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              2
Maximum mount count:      1
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#
再起動前に作成した/fastbootは削除されている。
[root@centos01 ~]# ls /fastboot
ls: cannot access /fastboot: そのようなファイルやディレクトリはありません
[root@centos01 ~]#

確認2: fsckされる場合

/fastbootが設定されていない状態で再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数3回に達し、Maximum mount countの設定値1を超えるため、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 14:35:52 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復旧

設定を戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

/forcefsckの検証

ファイル/forcefsckを作成すると、強制的にfsckを実行させることができる。
これを確認する。

現在状態の確認

現在の状態を確認する。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:35:52 2017
Check interval:           0 (<none>)
[root@centos01 ~]#
マウント回数、経過時間共にfsckされる条件を満たしていないことが判る。

確認

/forcefsckを作成し、再起動する。
[root@centos01 ~]# touch /forcefsck
[root@centos01 ~]# shutdown -r now
強制的にfsckが実行される。
起動後、確認する。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

/etc/fstabの第6フィールドの検証

/etc/fstabの第6フィールドを0に設定すると、fsckが抑制される。

設定

/etc/fstabの第6フィールドを0に設定する。
[root@centos01 ~]# cp -p /etc/fstab /etc/fstab.orig
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]# sed -i '/lv_root/s/1$/0/' /etc/fstab
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 0
[root@centos01 ~]#

Maximum mount countを1に設定する。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]# tune2fs -c 1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 1
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない

再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数2回に達し、Maximum mount countの設定値1を超えるが、/etc/fstabでfsckを抑制しているため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              2
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認2: /etc/fstabの第6フィールド VS /forcefsck

/etc/fstabの第6フィールドを0にした状態で/forcefsckを作成した場合どうなるか検証する。

/forcefsckを作成し、再起動する。
[root@centos01 ~]# touch /forcefsck
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数3回に達し、Maximum mount countの設定値1を超え、さらに/etc/forcefsckが作成されているが、/etc/fstabでfsckを抑制しているため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              3
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復元1: /etc/fstabのみ

/etc/fsckの第6フィールドのみ設定を戻す。
[root@centos01 ~]# mv -f /etc/fstab.orig /etc/fstab
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]#

確認3: fsckされる

/etc/fsckの第6フィールドの設定を戻すと、fsckされることを確認する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数4回に達し、Maximum mount countの設定値1を超えるので、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 15:21:03 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復元2: Maximum mount count

Maximum mount countの設定を戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

2009/04/05

シェルスクリプト内でXMLから情報を取り出す

XML形式により情報をやり取りすることが多くなった昨今、シェルスクリプト(shell script)でXMLを扱うことも増えてきた。例えば、libvirtを使って
virsh dumpxml DomU名
として得た仮想マシンの設定情報などだ。Xen DomU dc1の設定ファイル/etc/xen/dc1が、
name = "dc1"
uuid = "4df3f764-00cb-42a6-8ff6-a98985cbda14"
maxmem = 256
memory = 64
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ ]
disk = [ "phy:/dev/VolGroupXX/LogVolDc1,xvda,w" ]
vif = [ "mac=00:16:3e:ff:ab:01,bridge=br1000",
"mac=00:16:3e:ff:ab:02,bridge=br2000" ]
だったとしよう。このdc1の設定をXML形式で得ると、
# virsh dumpxml dc1
<domain type='xen' id='18'>
<name>dc1</name>
<uuid>094a82d5-7e6c-980d-49d3-9e8e68fb84e2</uuid>
<bootloader>/usr/bin/pygrub</bootloader>
<os>
<type>linux</type>
<kernel>/var/lib/xen/boot_kernel.rMNCqh</kernel>
<initrd>/var/lib/xen/boot_ramdisk.og2mn7</initrd>
<cmdline>ro root=/dev/VolGroup00/LogVol00 console=xvc0 acpi=off nopcmcia noapm nousb nofirewire nosound</cmdline>
</os>
<memory>262144</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<interface type='bridge'>
<source bridge='br4000'/>
<target dev='vif18.0'/>
<mac address='00:16:3e:1d:89:01'/>
<script path='vif-bridge'/>
</interface>
<interface type='bridge'>
<source bridge='br2002'/>
<target dev='vif18.1'/>
<mac address='00:16:3e:1d:92:01'/>
<script path='vif-bridge'/>
</interface>
<disk type='block' device='disk'>
<driver name='phy'/>
<source dev='/dev/VolGroupXX/LogVolDc1'/>
<target dev='xvda'/>
</disk>
<console tty='/dev/pts/1'/>
</devices>
</domain>

#
のようになる。このとき、ディスクに関する情報を取り出したいとしよう。
まず、XML形式をファイルに保存する。
# virsh dumpxml dc1 > dc1.xml
#
このファイルを引数として、xmllintコマンドを対話モードで起動する。
# xmllint --shell dc1.xml
/ >
プロンプトの「/」は、現在のXML文書上のパスを示している。
ここで「cat」と入力すると、現在のパス以下の内容すべてが表示される。つまり、XMLファイルの内容すべてが表示されることになる。
/ > cat
<?xml version="1.0"?>
<domain type="xen" id="18">
<name>dc1</name>
<uuid>094a82d5-7e6c-980d-49d3-9e8e68fb84e2</uuid>
<bootloader>/usr/bin/pygrub</bootloader>
<os>
<type>linux</type>
<kernel>/var/lib/xen/boot_kernel.rMNCqh</kernel>
<initrd>/var/lib/xen/boot_ramdisk.og2mn7</initrd>
<cmdline>ro root=/dev/VolGroup00/LogVol00 console=xvc0 acpi=off nopcmcia noapm nousb nofirewire nosound</cmdline>
</os>
<memory>262144</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<interface type="bridge">
<source bridge="br4000"/>
<target dev="vif18.0"/>
<mac address="00:16:3e:1d:89:01"/>
<script path="vif-bridge"/>
</interface>
<interface type="bridge">
<source bridge="br2002"/>
<target dev="vif18.1"/>
<mac address="00:16:3e:1d:92:01"/>
<script path="vif-bridge"/>
</interface>
<disk type="block" device="disk">
<driver name="phy"/>
<source dev="/dev/VolGroupXX/LogVolDc1"/>
<target dev="xvda"/>
</disk>
<console tty="/dev/pts/1"/>
</devices>
</domain>

/ >
ただし、xmllintの出力は正規化されているため、先頭行が追加されている。
ディスクに関する設定は、XPath形式で表せば、「/domain/devices/disk」にあることが解る。これをcatで出力してみる。
/ > cat /domain/devices/disk
-------
<disk type="block" device="disk">
<driver name="phy"/>
<source dev="/dev/VolGroupXX/LogVolDc1"/>
<target dev="xvda"/>
</disk>
/ >
さらに、ソースデバイス名のみを抽出してみよう。
/ > cat /domain/devices/disk/source/@dev
-------
dev="/dev/VolGroupXX/LogVolDc1"
/ >
これを非対話的に実行するには、
# echo "cat /domain/devices/disk/source/@dev" | xmllint --shell dc1.xml
/ > -------
dev="/dev/VolGroupXX/LogVolDc1"
/ > #
とすればよい。
これと同様の操作をネットワークインターフェースに対して実行してみる。
# echo "cat /domain/devices/interface/source/@bridge" | xmllint --shell dc1.xml 
/ > -------
bridge="br4000"
-------
bridge="br2002"
/ > #
XPath /domain/devices/interfaceにマッチする要素は二つあるので、出力も二つだ。
これらのうち、二番目のものだけを出力するには、
# echo "cat /domain/devices/interface[2]/source/@bridge" | xmllint --shell dc1.xml
/ > -------
bridge="br2002"
/ > #
とする。

2009/04/03

A backup script for Xen DomUs, part 2

A backup script for Xen DomUs, part 1』で紹介したスクリプトxen-backup.shについて解説する。

このスクリプトの大まかな流れは以下の通り:
  1. バックアップ設定ファイルの読み込み: 182行目
  2. バックアップを実行するかどうかの検査: 183行目~215行目
  3. DomU設定の解析: 217行目~228行目
  4. ディスクイメージのマウント@ローカル: 230行目~254行目
  5. ディスクイメージのマウント@リモートDom0: 256行目~263行目
  6. Rsyncによるバックアップ: 265行目~266行目
  7. ディスクイメージのアンマウント@リモートDom0: 268行目~274行目
  8. ディスクイメージのアンマウント@ローカル: 277行目~280行目

バックアップを実行するかどうかの検査
DomUの状態を表示するコマンド
virsh domstate DomU名
を使って、以下の各項目を検査する。
  1. 対象DomUが、ローカルDom0でホストされいるか?
  2. 対象DomUが、ローカルDom0で正常に実行されているか?
  3. 自分自身がDOM0Sに含まれているか?
すべての検査に合格すれば、バックアップを実行する。

DomU設定の解析
コマンド
virsh dumpxml DomU名
で対象となるDomUの設定(XML形式)を得て、ディスクイメージ情報を抽出する。
このとき、関数get_value_from_configを呼び出す。
115: get_value_from_config()
116: {
117:     local xml=$1 num=$2 elem=$3 attr=$4
118:     echo "cat /domain/devices/disk[$num]/$elem/@$attr" | \
119:         xmllint --shell $xml | \
120:         awk -F\" '/^ +'$attr'/{print $2}'
121: }
この中ではxmllintコマンドを使用している。ディスクイメージに対する設定項目/domain/devices/diskは、複数指定される可能性があることに注意。

ディスクイメージのマウント@ローカル
各ディスクイメージをローカルにマウントする。
マウントする前に、ディスクイメージのスナップショットを撮っている(『XenとLVM・その3・スナップショットLVの利用』参照)
238:                 lvcreate --snapshot --name=$snapshot_name --size=$SNAPSHOT_SIZE ${disk_source[$i]}
239:                 add_close_command "lvremove -f /dev/$vgname/$snapshot_name"
240:                 analyze_disk /dev/$vgname/$snapshot_name
マウント時と反対の動作をバックアップ後に実施する必要があるため、add_close_command関数(34行目~38行目)を使って記録する。
実際の解析は、analyze_disk関数(124行目~175行目)を使っている。

analyze_disk関数
マウント時の動作は、リモート側でも実行する必要があるため、add_open_command関数(14行目~19行目)で実行および記録する。
与えられたデバイス$the_diskに対して、
131:     part_type=`parted -s $the_disk print | awk '/^Partition Table:/{print $3}'`
でパーティションの種類を得ている。これがDOSパーティションなら、パーティション毎に分割し、それぞれに対して処理する必要がある。
134:             add_open_command "kpartx -a -p $PSEP $the_disk"
135:             add_close_command "kpartx -d -p $PSEP $the_disk"
ここで、kpartxコマンドに対するオプション「-p 区切文字」を指定していることに注意。例えば、/dev/VolGroup00/LogVolDomUに対して、
kpartx -a /dev/VolGroup00/LogVolDomU1
を実行すると、パーティションごとに
/dev/mapper/LogVolDomU1
/dev/mapper/LogVolDomU1
等のデバイスが作成されるが、元のデバイス名の最後が数字の場合、例えば/dev/VolGroup00/LogVolDomU1の場合は、
/dev/mapper/LogVolDomU1p1
/dev/mapper/LogVolDomU1p1
の様に区切文字「p」が挿入される。オプション「-p 区切文字」を指定すれば、どちらの場合も区切文字が挿入されるので都合が良い。なお、「kpartx -a -p 区切文字」で作成したデバイスは、「-p」を指定して「kpartx -d -p 区切文字」としないと削除できない(この辺りの動作は、kpartxのmanpageにも触れられていない)
136:             while read device[$num] fs_type[$num] mount_point[$num]; do
137:                 ((num++))
138:             done <<EOF
139: $(parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}')
140: EOF
この部分は、一見
parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}' | while read device[$num] fs_type[$num] mount_point[$num]; do
((num++))
done
の様に書き直せそうだが、期待通りの動作とならない。なぜなら、readコマンドをパイプの後で使うと、readコマンドがサブシェルで実行され、サブシェルの変数には代入されるが、元のシェルの変数には反映されないため。
最終的に、mountコマンドでマウントされるデバイスにまで分割できたら、add_fs_table関数(52行目~57行目)で記録しておく。ディレクトリ階層の高い順にマウントする必要があるため、すべてのマウントポイントを解析し終えてからマウントする(252行目~254行目)。

ディスクイメージのマウント@リモートDom0
リモートDom0に対して、SSH経由でマウントを実行する。
258:         ssh -T $remote_dom0 <<EOF
259: ##### COMMANDS FOR TARGET TO OPEN
260: `exec_open_commands | sed 's/-'$$'//'`
261: mkdir -p $target_prefix
262: `mount_fs_all $target_prefix | sed 's/-'$$'//'`
263: EOF
入力がTTYでないことを明示するため、sshコマンドには、「-T」オプションを与えている。

Rsyncによるバックアップ
266:         rsync -avz --delete -e ssh $source_prefix/ $remote_dom0:$target_prefix
引数「$source_prefix/」の最後のスラッシュは必須。省略すると、期待通りに動作しない。


A backup script for Xen DomUs, part 1
A backup script for Xen DomUs, part 2

A backup script for Xen DomUs, part 1

XenのDomUを運用する際、複数のDom0(物理サーバ)を準備しておき、DomUのディスクイメージ(以下、単にイメージ)を共有しておけば、一台のDom0が故障しても、健全なDom0でサービスを継続することが可能だ。
Dom0間でDomUイメージを共有する方法には、iSCSIを使う方法や、DRBDを使う方法があるが、CentOSのiSCSIターゲット(ストレージ側)やDRBDには問題があり、今のところ安心して採用できない(iSCSIターゲットに専用機器を使えば問題無いが、金がかかる)

そこで紹介するのが、今回のバックアップスクリプトxen-backup.shだ。このスクリプトは、rsync(1)を使うため、単純にディスクイメージをネットワークコピーするより圧倒的に早い。また、Xen固有のコマンドを一切使わず、virshコマンドを使っている。このため、libvirtがサポートしている他の仮想環境、kvmなどでも使用できるかもしれない(未確認)。
前提条件は以下の通り:
  1. Dom0間で、rootによるSSHログインが可能であること。
  2. 論理ボリューム(logical volume, LV)上にイメージが保存されていること。
  3. 各DomUに対して、ディスクイメージLV名が一致すること。
  4. Dom0とDomUのボリュームグループ名(volume group, VG)が重複しないこと。
  5. 実行前に別途フルバックアップを実行すること。
  6. 無保証
前提条件1.は、rsyncを安全に使うため必要。完全に自動化したい場合は、このバックアップ用の公開鍵を作成し、秘密鍵のパスフレーズを外した状態で、各Dom0のrootに配布すればよい。
前提条件2.は、動作中のDomUに対してスナップショットを撮ってバックアップするための条件。スナップショットが必要ない場合は、ファイルや物理的なディスクパーティションに対して動作させられるよう改造するのはそう難しくないだろう。
前提条件3.は要するに、DomUの設定ファイルが(ディスクイメージに関して)完全に一致すれば良い、ということだ。これは単に私の手抜きの結果。LV名が異なる場合は、コピー元・コピー先それぞれのDom0上で設定ファイルを解析するよう改造が必要。
前提条件4.については、『パスワードを紛失したDomUをリカバリ』に書いた通りで、具体的には、DomoのVG名を、標準の「VolGroup00」から「VolGroupXX」に変更してインストールする(DomUのVG名を標準のままでよい)。『Red Hat Cluster: CentOS 5.1上でRHCSを使ってみる・その2・Dom0 fsXのインストール』を参照。
前提条件5.は、使用前に例えば、
[root@dom0a ~]# dd bs=16M if=/dev/VolGroupXX/LogVolDomU1 | ssh dom0b 'dd bs=16M of=/dev/VolGroupXX/LogVolDomU1'
を実行する必要がある。今回のスクリプトでは、パーティション情報やLVM情報はコピーされないためだ。

なお、今回のスクリプトでは、対象DomUが実際に動作しているDom0上から、他のDom0へコピーを行う。これは、誤って古いイメージから新しいイメージへ書き戻すのを防ぐため。

スクリプトを実行する前に、各DomUに対する設定ファイル/root/Works/Xen-Backup/xen-backup.d/*.confを準備する(通常は、DomU名.conf)。設定項目は次の二つのみ:
DOMU
DomU名
DOM0S
このDomUのイメージを保存するDom0。空白で区切って並べる。ネットワーク的に到達可能な名前でなければならない。
例えば、DomU domu1に対する設定ファイル/root/Works/Xen-Backup/xen-backup.d/domu1.confならば、
DOMU=domu1
DOM0S="dom0a dom0b"
となる。この場合、domu1は、dom0a dom0bでホストされている。

xen-backup.shをダウンロード

コードは以下のbase64形式を、xen-backup.sh.b64として保存しておき、以下のコマンド
cat xen-backup.sh.b64 | base64 -di | gunzip > xen-backup.sh
で復元して使用する。

2009/4/5(日)追記:
ログをSYSLOGで出力するように変更した。

2009/4/6(月)追記:
重複実行を排除した。

2009/4/7(火)追記:
エラーもログされるよう変更した。
Cronからでも正常に実行されるよう、PATHを設定するように変更した。

2012/11/30(金)追記:
ファイルをダウンロードできるようにした。

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


A backup script for Xen DomUs, part 1
A backup script for Xen DomUs, part 2

2008/12/16

Libvirt & Xen その2 予備調査: xm

Libvirtの使い方の前にxmコマンドについて調査する。

このコマンドとXenハイパーバイザとの通信については、『White Paper: Basic components of Xen』で解説されている。Xenの標準UIであるxmコマンドは、デーモンxendとXML RPCによって通信を行い、Dom0を通じてXenハイパーバイザを制御する。ここで使われるXML RPCインターフェースは、UNIXソケットで、アクセスにはroot権限が必要だ。

実際に試してみよう。
[root@fs1 ~]# /usr/sbin/xm list
Name ID Mem(MiB) VCPUs State Time(s)
Domain-0 0 3673 2 r----- 28871.0
[root@fs1 ~]#

[user01@fs1 ~]$ /usr/sbin/xm list
ERROR Internal error: Could not obtain handle on privileged command interface (13 = Permission denied)
Error: Most commands need root access. Please try again as root.
[user01@fs1 ~]$
通常ユーザでxmコマンドが失敗するのは、xendと通信する際に使用するUNIXドメインソケット/var/run/xend/xmlrpc.sock(CentOS/RHEL/Fedoraの場合)には、root権限でないと書き込めなからだ。
[root@fs1 ~]# ls -l /var/run/xend/xmlrpc.sock
srwxr-xr-x 1 root root 0 Dec 8 13:39 /var/run/xend/xmlrpc.sock
[root@fs1 ~]#
また、xmコマンドは、このUNIXドメインソケットの他に、/proc/xend以下のファイルも利用する。実は、最初のエラーメッセージ「ERROR Internal error: Could not...」は、/proc/xen/privcmdを開こうとしたときのもので、次のエラーメッセージ「Error: Most commands...」は/var/run/xend/xmlrpc.sockを開こうとしたときのもの。

これは、straceコマンドを利用して、
[user01@fs1 ~]$ strace /usr/sbin/xm list > strace-xm-log.txt 2>&1
[user01@fs1 ~]$
の様に実行することにより、確認できる。

以上、Xenハイパーバイザは、主にデーモンxendの提供するインターフェースを通じて制御する。デーモンxendが提供するインターフェースは、三種類のアプリケーション層(HTTP、XML-RPCおよびXen Management API)、二種のトランスポート層(UNIXドメインソケットおよびTCP)の計六種類が提供されている。設定は、/etc/xen/xend-config.sxpで行う。上で使ったUNIXソケット/var/run/xend/xmlrpc.sockもこのファイルの中で設定さていれる。
TCPを利用したインターフェースは、ネットワーク経由で操作することが可能。しかし、HTTPやXML-RPCは、セキュリティは十分ではない。IPアドレス・ドメイン名ベースのアクセス制御があるのみで、認証や暗号化はサポートされていない。SSHのポートフォワーディングと併用するなど、別途セキュリティを確保する必要がある。

2008/12/09

Libvirt & Xen その1 概要

このシリーズでは、Libvirtを使ったXenの管理について解説する。

Libvirtの利点は二つある。

一点目は、他の仮想化ソリューションへの移行が容易になることだ。
現時点でCentOSおよびRHELでは、仮想化ソリューションとしてXenとKVMをサポートしているが、今後Xenはサポートから外される方針のようだ。Xenユーザにとっては、KVMへの移行が今後の課題となるだろう。
移行時の課題の一つが、管理方法の変更だ。Xenでは通常、xmコマンドを用いて管理する。これはXen専用のコマンドなので、KVMを管理することはできない。
CentOSおよびRHELでは、KVMとXenを統合管理するために、RPMパッケージlibvirt準備されている。Libvirtによる管理に慣れておけば、XenからKVMへの移行に役立つだろう。
Libvirtは、XenとKVMの他に、QEMU、Linux Containers、OpenVZ、UMLをサポートしている。将来的にはVMwareもサポートされる予定だ。

二点目は、セキュリティだ。
リモート管理の場合、Xenのアクセス制御は、IPアドレス・ホスト名ベースのものしかなく、貧弱だ。一方、Libvirtでは、ユーザ名・パスワード認証、Kerberos認証、および、TLS(SSL)による認証(および暗号化)をサポートしている。Iptablesを併用すれば、IPアドレスベースのアクセス制御も可能だ。
ローカルからの管理の場合、XenもlibvirtもUNIXソケットを使うが、Xenでは、rootに対する読み書き権限が与えられ、その他のユーザに関しては、読み取り権限が与えられていて、基本的に変更できない。一方、libvirtでは、任意の1グループを特権グループとして設定することができ、これに対して書き込み権限を与えることもできる。また、PolicyKitを使ったアクセス制御を行うこともできる。

2008/12/16追記:
Xenの新しいバージョンでは、新しい管理API・XenApiが準備されている。『XM and XenAPI developement on Xen Summit April 2007』によると、TLSによる暗号化やPAM認証が使えるらしい。

2008/11/03

NTPDとIP multicast

以前このブログでNTPDについて書いた。この中で、『注意!IPマルチキャストに関して訂正・本編』という記事を書いたが、これに間違いが見つかったので訂正する。
Ntpdは、その認証機構がIPアドレスと結びついているため、マルチキャストパケットを送信する際に、送信元となる自分自身のIPアドレスをntpd自身が明示的に知る必要があります。そのため、IPマルチキャスト用のソケット(socket)を取得する際、そのIPマルチキャストアドレス(通常なら 224.0.1.1)で経路情報(routing table)を引き、得られたネットワークインターフェースのIPアドレスを送信元IPアドレスとするようです。
この赤字の部分が誤り。
まず、マルチキャストサーバモードの時の動作だが、manpageの記述も間違っている。

broadcast
For type b and m addresses (only), this command mobilizes a persistent broadcast mode association. Multiple commands can be used to specify multiple local broadcast interfaces (subnets) and/or multiple multicast groups. Note that local broadcast messages go only to the interface associated with the subnet specified, but multicast messages go to all interfaces.
IPマルチキャストを使う場合、つまり、/etc/ntp.confの中で、broadcastコマンドにIPマルチキャストアドレス(m address)を指定した場合、すべてのインターフェースに対してマルチキャストメッセージが送信される、となっている。実際には、この通りにはならない。
実際には、複数のインターフェースを持っている場合には、マルチキャストメッセージが送信されるのは、それらのインターフェースの中の一つのみ。しかも、それはip route showで表示されるルーティングテーブルとは無関係の様だ。
この現象は、NTP BugzillaBug ID 785として扱われているようだ。バージョン4.2.6辺りで修正されるのかもしれない。

2008/11/02

virt-clone

CentOS 5.2上で仮想化パッケージ(@virtualization)をインストールすると、virt-cloneコマンドがインストールされる。
$ rpm -qf `which virt-clone`
python-virtinst-0.300.2-8.el5
$
このコマンドは、Xen DomUを複製するのに使用する。
$ virt-clone --help
usage: virt-clone [options]

options:
-h, --help show this help message and exit
-o ORIGINAL_GUEST, --original=ORIGINAL_GUEST
オリジナルゲストの名前か uuid:
状態は停止でなければなりません
-n NEW_NAME, --name=NEW_NAME
新しいゲストの名前
-u NEW_UUID, --uuid=NEW_UUID
クローンゲストの新しい uuid:
省略値はランダムに生成された UUID です
-m NEW_MAC, --mac=NEW_MAC
クローンゲスト用の固定 MAC アドレス。・
略値はランダムに生成されます
-f NEW_DISKFILE, --file=NEW_DISKFILE
ディスクイメージとして使用される、新
ゲスト用の新ファイル
--connect=CONNECT URI でハイパーバイザーに接続
--force-copy=TARGET 装置のコピーを強制する (例えば 'hdc'
が読込みのみの cdrom 装置なら、--force-
copy=hdc)
--nonsparse クローニングのディスクイメージに疎ら
なファイルを使用しないでください
--preserve-data 新ファイルを新ゲスト用のディスクイメ
ージとして使用するよう保存する
-d, --debug デバッグ情報を印刷
--force Do not prompt for input. Answers yes where applicable,
terminates for all other prompts
$
実際に使ってみよう。まず、元となるDomU dc0がインストールされている。
[root@fs1 xen]# ls /etc/xen/dc*
/etc/xen/dc0
[root@fs1 xen]# cat /etc/xen/dc0
name = "dc0"
uuid = "d9911ef3-1919-9972-fe4c-96c7ece17f7b"
maxmem = 256
memory = 256
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ ]
disk = [ "phy:/dev/VolGroupXX/LogVolDc0,xvda,w" ]
vif = [ "mac=00:16:3e:1d:89:00,bridge=br4000" ]
[root@fs1 xen]# ls /dev/VolGroupXX/LogVolDc*
/dev/VolGroupXX/LogVolDc0
[root@fs1 xen]# lvs /dev/VolGroupXX/LogVolDc0
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
LogVolDc0 VolGroupXX -wi-a- 4.00G
[root@fs1 xen]#
これをdc1という名前で複製しよう。イメージを格納する論理ボリューム(logical volume, LV) LogVolDc1をボリュームグループ(volume group, VG) VolGroupXX上に作成する。
[root@fs1 xen]# lvcreate --name=LogVolDc1 --size=4G VolGroupXX
Logical volume "LogVolDc1" created
[root@fs1 xen]#
コマンドvirt-cloneで複製を実行する。
[root@fs1 xen]# virt-clone --original=dc0 --name=dc1 --file=/dev/VolGroupXX/LogVolDc1
Cloning from /dev/VolGroupXX/LogVolDc0 to /dev/VolGroupXX/LogVolDc1
Cloning domain... 100% |=========================| 4.0 GB 03:23
[root@fs1 xen]#
イメージをコピーするため、実行に三分半弱かかっている。
DomU dc1の定義ファイルは以下の様になっている。
[root@fs1 xen]# cat /etc/xen/dc1
name = "dc1"
uuid = "ce08f29d-9006-c607-7891-786ffa421ca7"
maxmem = 256
memory = 256
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ ]
disk = [ "phy:/dev/VolGroupXX/LogVolDc1,xvda,w" ]
vif = [ "mac=00:16:3e:1c:2f:6e,bridge=br4000" ]
[root@fs1 xen]#
DomU名の他に、UUIDやMACアドレスが変更されていることが解る。
当然、このDomUを実行することもできる。
[root@fs1 xen]# xm create -c dc1

2008/10/01

IP reachableでない場合のremote copy

リモートマシンのファイルをコピーする場合、ローカルマシンとIP到達性が確保されていれば、普通にscpを使ってコピーすれば問題ない。しかし、IP到達性が確保されていない場合はどうするか?ここでは、base64コマンドを使う方法を紹介する。

IP到達性が確保されていない場合とは例えば、
  • Xen環境でDomUとDom0間がXenコンソールでしか繋がっていない
  • シリアルポートからTTY接続している
などだ。

上の様な場合でも、標準出力はローカルマシンのコンソールに出力されるので、ここからコピーすればよいのだが、単にファイルをcatすると、バイナリファイルは正常にコピーできないし、テキストファイルであっても、端末エミュレータによってはタブが空白に変換されたり、行末の空白が無視されたりする。

これを避けるために、TTYで正常に出力されるキャラクタ集合でエンコードする。その昔は、uuencodeを使ったが、最近のLinuxでは、base64コマンドが使いやすい。
まず、コピー元のマシンで、以下の様にエンコードする。
[root@dc1 ~]# base64 /usr/share/doc/yum-3.2.8/README
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpZdW0gLSBhbiBhdXRvbWF0aWMg
dXBkYXRlciBhbmQgaW5zdGFsbGVyIGZvciBycG0tYmFzZWQgc3lzdGVtcwotLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpJbmNsdWRlZCBwcm9ncmFtczoKL3Vzci9iaW4veXVt
<<略>>
dHRwOi8vbGludXguZHVrZS5lZHUveXVtLwp3aWtpOiBodHRwOi8vd2lraS5saW51eC5kdWtlLmVk
dS9ZdW0K
[root@dc1 ~]#
この出力結果をデコードするには、base64コマンドに-diオプションを付けて実行する。以下の実行例では、ローカルマシン上で実行しているが、実際には、コンソール間でエンコードされたデータをコピー&ペーストする。
[root@dc1 ~]# base64 /usr/share/doc/yum-3.2.8/README | base64 -di
-------------------------------------
Yum - an automatic updater and installer for rpm-based systems
-------------------------------------

Included programs:
/usr/bin/yum Main program
<<略>>
wiki: http://wiki.linux.duke.edu/Yum
[root@dc1 ~]#
なお、base64コマンドが無い場合は、opensslコマンドで代用する。
[root@dc1 ~]# openssl base64 < /usr/share/doc/yum-3.2.8/README | openssl base64 -d
-------------------------------------
Yum - an automatic updater and installer for rpm-based systems
<<略>>

2008/09/17

Quota・その3・運用

実際にユーザuser01で、制限がどう働くか見てみよう。
まず、quotaの状況を確認する。
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
76   46080   51200              10       0       0
[user01@dc1 ~]$
この時点では、どの制限にも達していない。
ファイルサイズ45MBのファイルを作成する。
[user01@dc1 ~]$ head --bytes=`expr 45 \* 1024 \* 1024` /dev/zero > 45M.dat
dm-0: warning, user block quota exceeded.
[user01@dc1 ~]$
ファイルは作成されたが、ソフトリミットに達した旨警告された。状況を確認する。
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
46212*  46080   51200   7days      11       0       0
[user01@dc1 ~]$
制限に達したため、使用ブロック容量の後に「*」が表示されている。猶予時間(grace time)は、7日間になっている。
この状態では、ファイルを作成できるが、ハードリミットに達するとそれ以上書込めなくなる。ファイルサイズ1MBのファイルを一つづつ作ってみる。
[user01@dc1 ~]$ for (( i=1; $i <= 6; i=`expr $i + 1` )) do command="head --bytes=`expr 1024 \* 1024` /dev/zero > 1M-$i.dat"; echo $command; eval $command; done
head --bytes=1048576 /dev/zero > 1M-1.dat
head --bytes=1048576 /dev/zero > 1M-2.dat
head --bytes=1048576 /dev/zero > 1M-3.dat
head --bytes=1048576 /dev/zero > 1M-4.dat
head --bytes=1048576 /dev/zero > 1M-5.dat
dm-0: write failed, user block limit reached.
head: write error: Disk quota exceeded
head: write error
head --bytes=1048576 /dev/zero > 1M-6.dat
-bash: 1M-6.dat: Disk quota exceeded
[user01@dc1 ~]$
五番目のファイルでハードリミットに達し、途中で書込めなくなった。六番目のファイルは、作成する前に失敗している。確認してみよう。
[user01@dc1 ~]$ ls -l
total 51124
-rw-r--r-- 1 user01 users  1048576 Sep 17 00:32 1M-1.dat
-rw-r--r-- 1 user01 users  1048576 Sep 17 00:32 1M-2.dat
-rw-r--r-- 1 user01 users  1048576 Sep 17 00:32 1M-3.dat
-rw-r--r-- 1 user01 users  1048576 Sep 17 00:32 1M-4.dat
-rw-r--r-- 1 user01 users   872448 Sep 17 00:32 1M-5.dat
-rw-r--r-- 1 user01 users 47185920 Sep 17 00:32 45M.dat
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
51200*  46080   51200              16       0       0
[user01@dc1 ~]$
ハードリミットに達したため、猶予時間が表示されなくなった事に注意。この状態では、空ファイルすら作れない。
[user01@dc1 ~]$ touch a
touch: cannot touch `a': Disk quota exceeded
[user01@dc1 ~]$
ファイルを削除し、ハードリミットを下回れば、再びファイルを作成可能になる。
[user01@dc1 ~]$ rm 1M-5.dat
[user01@dc1 ~]$ touch a
[user01@dc1 ~]$


この状態を、管理者側で確認してみよう。
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1571120       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0
user01    +-   50352   46080   51200  6days      17     0     0
user02    --      76   46080   51200             10     0     0
user03    --      76   46080   51200             10     0     0


[root@dc1 ~]#
ユーザuser01の猶予時間が6日間と表示されている。
管理者は各ユーザの猶予時間を変更することができる。5分(300秒)に変更してみよう。
[root@dc1 ~]# setquota -T user01 300 unset -a
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1571120       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0
user01    +-   50352   46080   51200  00:05      17     0     0
user02    --      76   46080   51200             10     0     0
user03    --      76   46080   51200             10     0     0


[root@dc1 ~]#


ユーザuser01で、動作を確認してみる。設定直後。
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
50352*  46080   51200   00:05      17       0       0
[user01@dc1 ~]$
ソフトリミットに達しているが、猶予時間がある。この状態では、まだファイルを作成することができる。
五分後。
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
50352*  46080   51200    none      17       0       0
[user01@dc1 ~]$
猶予時間がnoneになっている。この状態では、空ファイルも作成できない。
[user01@dc1 ~]$ touch b
dm-0: write failed, user block quota exceeded too long.
touch: cannot touch `b': Disk quota exceeded
[user01@dc1 ~]$
この制限は、ソフトリミットを下回るまで解除されない。
[user01@dc1 ~]$ rm 1M-*
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
46224*  46080   51200    none      13       0       0
[user01@dc1 ~]$ touch b
dm-0: write failed, user block quota exceeded too long.
touch: cannot touch `b': Disk quota exceeded
[user01@dc1 ~]$ rm 45M.dat
[user01@dc1 ~]$ touch b
[user01@dc1 ~]$ quota
Disk quotas for user user01 (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/VolGroup00-LogVol00
92   46080   51200              13       0       0
[user01@dc1 ~]$

その1・ファイルシステム毎の設定』『その2・ユーザ毎の設定』『その3・運用

Quota・その2・ユーザ毎の設定

一般ユーザuser0[123]を作成し、容量制限を設定する。
[root@dc1 ~]# useradd -g users -m user01
[root@dc1 ~]# useradd -g users -m user02
[root@dc1 ~]# useradd -g users -m user03
[root@dc1 ~]#
当然、この時点ではこれらのユーザにも容量制限は働いていない。
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1571120       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0
user01    --      76       0       0             10     0     0
user02    --      76       0       0             10     0     0
user03    --      76       0       0             10     0     0


[root@dc1 ~]#
これらのユーザに対して、前の記事冒頭で述べた容量制限を設定する。まず、user01に対して設定を行う。この作業は、edquotaコマンドでも実行可能だが、非対話的に実行するため、setquotaコマンドを使用する。最初に作成した一般ユーザuser01のUID番号は、500であることに注意。
[root@dc1 ~]# setquota 500 46080 51200 0 0 /
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1571120       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0
user01    --      76   46080   51200             10     0     0
user02    --      76       0       0             10     0     0
user03    --      76       0       0             10     0     0


[root@dc1 ~]#
ユーザuser01の設定を他のユーザuser0[23](UID番号50[12])にコピーする。設定のコピーには、edquotaを使う。非対話的に実行される。
[root@dc1 ~]# for (( uid=501; $uid <= 502; uid=`expr $uid + 1` )) do command="edquota -p 500 $uid"; echo $command; eval $command; done
edquota -p 500 501
edquota -p 500 502
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1571120       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0
user01    --      76   46080   51200             10     0     0
user02    --      76   46080   51200             10     0     0
user03    --      76   46080   51200             10     0     0


[root@dc1 ~]#
なお、setquotaおよびedquotaコマンドで、ユーザを指定するのに名前で指定することもできるが、ここではUID番号で指定した。これには次のような理由がある。名前指定の場合、先にユーザが登録されている必要がある。一方、UID番号指定の場合には、その制約は無い。将来登録されるユーザに対して容量制限を行いたい場合、ユーザ登録に先立って、それらのユーザが登録されるUID番号の範囲に対して、UID番号指定で容量制限を設定することができる。一方、名前指定ではこれは不可能だ。


その1・ファイルシステム毎の設定』『その2・ユーザ毎の設定』『その3・運用

Quota・その1・ファイルシステム毎の設定

今までquota・ディスク容量制限というものをやったことが無かったのだが、必要に迫られ、やってみた。

CentOS機dc1上で、ユーザuser0[123]を作成し、これらにそれぞれ、45MBのソフトリミット、50MBのハードリミットを設定する。RHELでも同様に作業できる。大まかな流れは以下の通り。
  1. ファイルシステム毎の設定
  2. ユーザ毎の設定
  3. 運用

まず、容量制限を設定するファイルシステムに対して、quotaが動くよう設定する。インストール時に特に指定しなければ、LVMを使って以下の様に設定されている。
[root@dc1 ~]# cat /etc/fstab
/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0
[root@dc1 ~]#
ユーザが自由に書込みできるのは、ユーザのホームディレクトリ/home/user[123]以下で、これはルート(/)に含まれている。
# 検索してみると、ルートにquotaを設定することはできない、と書いてあるページもあるが、これは誤りだ。

ルートのエントリを以下の通り編集する。
[root@dc1 ~]# cp -p /etc/fstab /etc/fstab.orig
[root@dc1 ~]# awk '{if ($2=="/" ) gsub(/defaults/,"defaults,usrquota,grpquota"); print $0 }' < /etc/fstab.orig > /etc/fstab
[root@dc1 ~]# cat /etc/fstab
/dev/VolGroup00/LogVol00 /                       ext3    defaults,usrquota,grpquota        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0
[root@dc1 ~]#
ユーザ単位の制限のみ必要で、グループ単位の制限が不要の場合は、「,grpquota」は無くてもよい。

編集し終わったら、対象となるファイルシステムを再マウントする(unmount→mount)すればよい。しかし、ルートの場合は再起動するしかない。
[root@dc1 ~]# shutdown -r now


再起動後、シングルユーザモードに移行し、quotacheckコマンドを実行する。
シングルユーザモードで実行するのは、以下の理由による。デフォルトでは、quotacheckは、対象ファイルシステムをread-onlyモードで再マウントしようとするが、ルートの場合はこれが失敗する。オプション「-m」を指定すれば、この動作を行わないが、quotacheckコマンド実行中に対象ファイルシステムで書込みが発生すると、使用量に誤差がでてしまう。シングルユーザモードにすれば、書込みは最低限となる。
シングルユーザモードに移行する。
[root@dc1 ~]# telinit 1
INIT: Switching to runlevel: 1
INIT: Sending processes the TERM signal
Shutting down Cluster Module - cluster monitor: [  OK  ]
Shutting down ricci: [  OK  ]
<<略>>

Telling INIT to go to single user mode.
INIT: Going single user
INIT: Sending processes the TERM signal
INIT: Sending processes the KILL signal
sh-3.2#
この時点では、quotaファイルaquota.{user,group}は存在していない。
sh-3.2# ls -l /
total 146
drwxr-xr-x  2 root root  4096 Aug 20 01:54 bin
drwxr-xr-x  4 root root  1024 Aug 19 19:55 boot
drwxr-xr-x 10 root root  2840 Sep 17 00:28 dev
drwxr-xr-x 86 root root 12288 Sep 17 00:28 etc
drwxr-xr-x  2 root root  4096 Mar 30  2007 home
drwxr-xr-x 14 root root  4096 Aug 20 01:54 lib
drwx------  2 root root 16384 Aug 19 19:49 lost+found
<<略>>
drwxrwxrwt  3 root root  4096 Sep 17 00:27 tmp
drwxr-xr-x 14 root root  4096 Aug 19 19:52 usr
drwxr-xr-x 23 root root  4096 Aug 19 20:01 var
sh-3.2#
コマンドquotacheckを実行する。
sh-3.2# quotacheck -cugfma
グループ単位の制限が不要の場合は、「-g」オプションは不要。実行完了までしばらく時間がかかる。
実行後は、quotaファイルが作成されている。
sh-3.2# ls -l /
total 170
-rw-------  1 root root  7168 Sep 17 00:28 aquota.group
-rw-------  1 root root  6144 Sep 17 00:28 aquota.user
drwxr-xr-x  2 root root  4096 Aug 20 01:54 bin
drwxr-xr-x  4 root root  1024 Aug 19 19:55 boot
drwxr-xr-x 10 root root  2840 Sep 17 00:28 dev
drwxr-xr-x 86 root root 12288 Sep 17 00:28 etc
drwxr-xr-x  2 root root  4096 Mar 30  2007 home
drwxr-xr-x 14 root root  4096 Aug 20 01:54 lib
drwx------  2 root root 16384 Aug 19 19:49 lost+found
<<略>>
drwxrwxrwt  3 root root  4096 Sep 17 00:27 tmp
drwxr-xr-x 14 root root  4096 Aug 19 19:52 usr
drwxr-xr-x 23 root root  4096 Aug 19 20:01 var
sh-3.2#
次に、対象ファイルシステムを再マウントするが、ルートの場合は再起動するしかない。
sh-3.2# shutdown -r now


再起動後、対象ファイルシステムに対してquotaが実行されているかどうかを確認する。
[root@dc1 ~]# mount
/dev/mapper/VolGroup00-LogVol00 on / type ext3 (rw,usrquota,grpquota)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/xvda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
[root@dc1 ~]# repquota -a
*** Report for user quotas on device /dev/mapper/VolGroup00-LogVol00
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      -- 1570628       0       0          59255     0     0
daemon    --      20       0       0              3     0     0
lp        --      16       0       0              2     0     0
smmsp     --      16       0       0              2     0     0
avahi     --       8       0       0              1     0     0
apache    --      24       0       0              3     0     0
ntp       --      16       0       0              2     0     0
rpc       --       4       0       0              1     0     0
rpcuser   --       8       0       0              1     0     0
luci      --  263348       0       0          20552     0     0
dovecot   --       8       0       0              1     0     0
webalizer --      32       0       0              4     0     0
piranha   --      16       0       0              3     0     0
rpm       --   24324       0       0             75     0     0
ricci     --      60       0       0              8     0     0


[root@dc1 ~]#
この段階では、どのユーザに対しても制限が設定されていない。


その1・ファイルシステム毎の設定』『その2・ユーザ毎の設定』『その3・運用

2008/07/25

Xen DomU上でDRBDを使う・その6・ベンチマーク

DRBDデバイス/dev/drbd0に直接書込み、速度を測定する。
[root@dc2 ~]# dd bs=64M if=/dev/zero of=/dev/drbd0
dd: writing `/dev/drbd0': No space left on device
64+0 records in
63+0 records out
4294799360 bytes (4.3 GB) copied, 227.723 seconds, 18.9 MB/s
[root@dc2 ~]#
このとき、もう一方のノードdc3の/var/log/messagesには、次のようなメッセージが記録される。この原因は不明。
Jul 24 22:32:08 dc3 kernel: drbd0: local disk flush failed with status -95


この結果を、『その2・DRBD設定前の確認』のときの結果と比較してみよう。DRBDを経由せず、直接/dev/xvdbに書込んだ場合が39.9Mbyte/秒、DRBD経由で/dev/drbd0に書込んだ場合が18.8Mbyte/秒。
/dev/drbd0に書込む場合、/dev/xvdbに書込む場合に比べて、ディスクへの書込みが二倍以上発生する。なぜなら、/dev/drbd0に書込むということは、dc2上の/dev/xvdbとdc3上の/dev/xvdbの両方にデータ書込んだ上で、メタデータも書込むからだ。これらの書込みは結局、Dom0上の同一ディスクへの書込みとなるため直列化され、倍以上の時間が掛かっていると考えられる。

この結果より、/etc/drbd.confで設定した「rate 5M」は、初期同期の場合には効いているが、通常のディスクアクセス時には効いていない事も解る。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

Xen DomU上でDRBDを使う・その5・初期同期

両ノードdc[23]で設定およびDRBDリソースの初期化を行った時点では、ディスクの同期が取れていない不一致(Inconsistent)状態にある。これを解消するため、『The initial device synchronization』に従い、初期同期を行う。
初期同期コマンドは、dc[23]のどちらか一方からのみ実行すればよい。もし、有効なデータがどちらかにのみ入っている場合は、そのノードで実行する。そうでない場合は、どちらで実行してもよい。
[root@dc3 ~]# drbdadm -- --overwrite-data-of-peer primary r0
drbd0: Forced to consider local data as UpToDate!
[root@dc3 ~]#
しばらく待って/proc/drbdを確認する。
[root@dc3 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---
ns:8976 nr:0 dw:0 dr:8976 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 oos:4185164
[>....................] sync'ed:  0.3% (4185164/4194140)K
finish: 4:04:08 speed: 244 (240) K/sec
[root@dc3 ~]#
同期速度が、直近244Kbyte/秒、平均240Kbyte/秒しか出ていない(しつこいようだが、Mbpsではないことに注意)。「rate 5M」と設定したので、5Mbyte/秒出るはずだが、どうもデフォルト値の250Kbyte/秒(『Appendix A. DRBD system manual pages』参照)が適用されているようだ。
これを回避するために、設定を再読み込みさせる。
[root@dc3 ~]# drbdadm adjust r0
[root@dc3 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---
ns:86320 nr:0 dw:0 dr:86320 al:0 bm:5 lo:60 pe:68 ua:60 ap:0 oos:4108092
[>....................] sync'ed:  2.2% (4108092/4194140)K
finish: 0:12:43 speed: 5,344 (1,244) K/sec
[root@dc3 ~]#
設定の通り、5Mbyte/秒に近い数字が出ている。これは、dc2側でも実行する。
しばらくすると同期が完了する。ログ/var/log/messagesを確認する。
Jul 24 22:14:33 dc2 kernel: drbd0: peer( Secondary -> Primary ) pdsk( Inconsistent -> UpToDate )
Jul 24 22:14:33 dc2 kernel: drbd0: Writing meta data super block now.
Jul 24 22:14:33 dc2 kernel: drbd0: Becoming sync target due to disk states.
Jul 24 22:14:33 dc2 kernel: drbd0: Writing the whole bitmap, full sync required after drbd_sync_handshake.
Jul 24 22:14:33 dc2 kernel: drbd0: Writing meta data super block now.
Jul 24 22:14:33 dc2 kernel: drbd0: writing of bitmap took 0 jiffies
Jul 24 22:14:33 dc2 kernel: drbd0: 4096 MB (1048535 bits) marked out-of-sync by on disk bit-map.
Jul 24 22:14:33 dc2 kernel: drbd0: Writing meta data super block now.
Jul 24 22:14:33 dc2 kernel: drbd0: conn( Connected -> WFBitMapT )
Jul 24 22:14:33 dc2 kernel: drbd0: conn( WFBitMapT -> WFSyncUUID )
Jul 24 22:14:33 dc2 kernel: drbd0: helper command: /sbin/drbdadm before-resync-target
Jul 24 22:14:33 dc2 kernel: drbd0: conn( WFSyncUUID -> SyncTarget )
Jul 24 22:14:33 dc2 kernel: drbd0: Began resync as SyncTarget (will sync 4194140 KB [1048535 bits set]).
Jul 24 22:14:33 dc2 kernel: drbd0: Writing meta data super block now.
Jul 24 22:16:09 dc2 kernel: drbd0: Writing meta data super block now.
Jul 24 22:29:06 dc2 kernel: drbd0: Resync done (total 872 sec; paused 0 sec; 4808 K/sec)
Jul 24 22:29:06 dc2 kernel: drbd0: conn( SyncTarget -> Connected ) disk( Inconsistent -> UpToDate )
Jul 24 22:29:06 dc2 kernel: drbd0: helper command: /sbin/drbdadm after-resync-target
Jul 24 22:29:06 dc2 kernel: drbd0: Writing meta data super block now.
4,194,140KBの同期に14分33秒掛かっている。およそ4.7Mbyte/秒で、ほぼ設定値の通り。
この時点では、dc3がprimaryとなっているが、dual-primaryモードで設定しているので、dc2もprimaryへ切り替える。
[root@dc2 ~]# drbdadm primary r0
[root@dc2 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
0: cs:Connected st:Primary/Primary ds:UpToDate/UpToDate C r---
ns:0 nr:4194140 dw:4194140 dr:0 al:0 bm:256 lo:0 pe:0 ua:0 ap:0 oos:0
[root@dc2 ~]#


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

Xen DomU上でDRBDを使う・その4・DRBDの初期化

Enabling your resource for the first time』に従ってDRBDリソースr0を初期化する。まず、dc2から作業する。
[root@dc2 ~]# drbdadm create-md r0
v08 Magic number not found
v07 Magic number not found
v07 Magic number not found
v08 Magic number not found
Writing meta data...
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.
[root@dc2 ~]# drbdadm attach r0
drbd0: No usable activity log found.
drbd0: Barriers not supported on meta data device - disabling
[root@dc2 ~]# drbdadm connect r0
[root@dc2 ~]# 
この時点では、dc3が初期化されていないため、接続が完了しないことを確認する。
[root@dc2 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
0: cs:WFConnection st:Secondary/Unknown ds:Inconsistent/DUnknown C r---
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 oos:4194140
[root@dc2 ~]#
以下のことが判る。
  • 接続状態(cs)が接続待ち(WFConnection)、
  • ロール(st)は、自分自身(dc2)がSecondary、相手(dc3)が不明(Unknown)
  • ディスク状態(ds)は、自分自身(dc2)が不一致、相手(dc3)が不明

続いて、dc3を初期化する。
[root@dc3 ~]# drbdadm create-md r0
v08 Magic number not found
v07 Magic number not found
v07 Magic number not found
v08 Magic number not found
Writing meta data...
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.
[root@dc3 ~]# drbdadm attach r0
drbd0: No usable activity log found.
drbd0: Barriers not supported on meta data device - disabling
[root@dc3 ~]# drbdadm connect r0
[root@dc3 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
0: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent C r---
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 oos:4194140
[root@dc3 ~]#
この時点では、dc[23]の両方が初期化されているため、通信状態(cs)が確立(Connected)となっている。両ノードともロール(st)がSecondaryで、ディスク状態(ds)が不一致(Inconsistent)となっている。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

Xen DomU上でDRBDを使う・その3・drbd.confの設定

各DomU dc[23]上の/etc/drbd.confを以下の通り設定する。
global {
usage-count no;
}
common {
protocol C;
}
resource r0 {
net {
allow-two-primaries;
shared-secret "9wEtE83PFS4xChqY+aT";
}
startup {
become-primary-on both;
}
syncer {
rate 5M;
verify-alg sha1;
}
device    /dev/drbd0;
disk      /dev/xvdb;
meta-disk internal;
on dc2.xencluster {
address   192.168.56.8:7789;
}
on dc3.xencluster {
address   192.168.56.9:7789;
}
}
設定内容は以下の通り。
  • リソースr0を定義。dc[23]からアクセスされる。
  • 両ノードが同時にprimaryになることができる(allow-two-primaries)。
  • ネットワーク接続時の認証のためのパスワードを設定している(shared-secret)。
  • 起動時に、両ノードがprimaryとなる(become-primary-on)。
  • 同期速度は5Mbyte/秒(rate)。単位がMbpsでないことに注意。
  • 両ノードとも、低レベルデバイスは/dev/xvdb(disk)、DRBDデバイスは/dev/drbd0(device)。
  • メタデータ形式はinternal(meta-disk)。つまり、/dev/xvdb内にメタデータを持つ。
  • dc[23]はそれぞれ、192.168.56.[89]の7789/tcpで接続を待つ。

なお、各ノードの設定の共通部分(disk、deviceおよびmeta-disk)をまとめて記述できるのは、DRBD 8.2系から。RPM package drbd82-xenではなくdrbd-xenをインストールしている場合は、これらの設定は、on ノード名節の中でそれぞれ記述する。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

Xen DomU上でDRBDを使う・その2・DRBD設定前の確認

各DomU dc[23]上には、OSイメージが格納されている/dev/xvdaの他に、/dev/xvdbが見えている。
[root@dc2 ~]# ls -l /dev/xvd*
brw-r----- 1 root disk 202,  0 Jul 24 21:41 /dev/xvda
brw-r----- 1 root disk 202,  1 Jul 24 21:41 /dev/xvda1
brw-r----- 1 root disk 202,  2 Jul 24 21:41 /dev/xvda2
brw-r----- 1 root disk 202, 16 Jul 24 21:41 /dev/xvdb
[root@dc2 ~]#
OSインストール直後は、DRBDの設定が行われていないため、/proc/drbdにはリソースが何も表示されない。
[root@dc2 ~]# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-bui
ld, 2008-06-26 16:40:54
[root@dc2 ~]#
この状態で、/dev/xvdbに対する書き込み速度を計測する。
[root@dc2 ~]# dd bs=64M if=/dev/zero of=/dev/xvdb
dd: writing `/dev/xvdb': No space left on device
65+0 records in
64+0 records out
4294967296 bytes (4.3 GB) copied, 107.757 seconds, 39.9 MB/s
[root@dc2 ~]#
[root@dc3 ~]# dd bs=64M if=/dev/zero of=/dev/xvdb
dd: writing `/dev/xvdb': No space left on device
65+0 records in
64+0 records out
4294967296 bytes (4.3 GB) copied, 107.6 seconds, 39.9 MB/s
[root@dc3 ~]#
ほぼ40Mbyte/秒の速度が出ている。単位がMbpsではないことに注意。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

Xen DomU上でDRBDを使う・その1・Xen環境の準備

Xen環境構築の詳細については、『Red Hat Cluster: CentOS 5.1上でRHCSを使ってみる』を参照。ここでは、DomUのKickstart設定ファイルを紹介する。以下の点に注意して欲しい。
  • RPMパッケージdrbd82およびkmod-drbd82-xenをインストールする。
  • ファイアウォール設定で、DRBDの通信、TCPポート7788~7799を許可する。

logging --host=192.168.55.32 --level=debug

install
url --url http://Repository.LocalDomain/centos/5/os/i386
lang en_US.UTF-8
keyboard jp106
network --device eth0 --bootproto dhcp --hostname=localhost.localdomain
rootpw --iscrypted $1$NG4SU1bL$I8FOJo.81cUrO6Xj4dau41
firewall --enabled --ssh --port=snmp:udp
authconfig --enableshadow --enablemd5
selinux --permissive
timezone Asia/Tokyo
bootloader --location=mbr --driveorder=xvda --append="console=xvc0"

services --enabled=ntpd,oddjobd,snmpd --disabled=acpid,apmd,avahi-daemon,bluetooth,cpuspeed,cups,gpm,hidd,lm_sensors,mdmonitor,microcode_ctl,nfslock,pcscd,smartd,xfs,yum-updatesd

clearpart --all --drives=xvda --initlabel
part /boot --fstype ext3 --size=100 --ondisk=xvda
part pv.2 --size=0 --grow --ondisk=xvda
volgroup VolGroup00 --pesize=32768 pv.2
logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=272 --grow --maxsize=544
logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
repo --name=base --baseurl=http://Repository.LocalDomain/centos/5/os/i386/
repo --name=updates --baseurl=http://Repository.LocalDomain/centos/5/updates/i386/
repo --name=addons --baseurl=http://Repository.LocalDomain/centos/5/addons/i386/
repo --name=extras --baseurl=http://Repository.LocalDomain/centos/5/extras/i386/

reboot

%packages
@admin-tools
@base
@cluster-storage
@clustering
@core
@emacs
@mail-server
@network-server
@ruby
@server-cfg
@system-tools
@text-internet
@web-server
-smartmontools
-OpenIPMI*
-squid
-samba-*
-system-config-samba
lynx
tftp
kernel-xen
kmod-gfs-xen
-kernel
-kmod-gfs
-kmod-gnbd
-NetworkManager
-bluez-utils
device-mapper-multipath
-irda-utils
-pcmciautils
net-snmp-utils
net-snmp-libs
net-snmp
iscsi-initiator-utils
-apmd
-acpid
drbd82
kmod-drbd82-xen
-kmod-drbd82

%post --log=/mnt/sysimage/root/install-post.log
### network
echo 'NOZEROCONF=yes' >> /etc/sysconfig/network

/bin/cp -p /etc/sysconfig/network-scripts/ifcfg-eth0 /tmp/ifcfg-eth0
/bin/sed 's/^HWADDR=/#HWADDR=/' < /tmp/ifcfg-eth0 > /etc/sysconfig/network-scripts/ifcfg-eth0

/bin/egrep -v '^#' /etc/sysconfig/network-scripts/ifcfg-eth0 | /bin/sed 's/eth0/eth1/' > /etc/sysconfig/network-scripts/ifcfg-eth1
/bin/egrep -v '^#' /etc/sysconfig/network-scripts/ifcfg-eth0 | /bin/sed 's/eth0/eth2/' > /etc/sysconfig/network-scripts/ifcfg-eth2
/sbin/restorecon /etc/sysconfig/network-scripts/ifcfg-eth[12]

### logrotate
/bin/cat > /etc/logrotate.d/00local.conf <<EOL
rotate 20
compress
start 100
EOL
/sbin/restorecon /etc/logrotate.d/00local.conf

### yum update from the local repository
/bin/cp -p /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.dist
/bin/sed 's/mirrorlist=/#mirrorlist=/
s/#baseurl=/baseurl=/
s/mirror.centos.org/Repository.LocalDomain/' < /etc/yum.repos.d/CentOS-Base.repo.dist > /etc/yum.repos.d/CentOS-Base.repo

### For Cluster
##### /etc/cluster/fence_xvm.key
/usr/bin/base64 -di > /etc/cluster/fence_xvm.key <<EOL
Atf+JoYSVwnPqBR8vnbG68EaY/Y4sr570YywcWXUcsZD6BwQAMA0x62YIMSlHArX60JzvNeh95x7
<<略>>
EN00EFaiso4dDtVaX2RYJf30RExW4E312yu+XwoXjrES0uLIK33p0HToOXUX3RjsCqYuM7ulE5iD
EOL
/bin/chmod 600 /etc/cluster/fence_xvm.key

##### iptables
/bin/cp -p /etc/sysconfig/iptables /etc/sysconfig/iptables.dist
/bin/cat > /etc/sysconfig/iptables <<EOL
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 7788:7799 -i eth1 -s 192.168.56.0/24 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 7788:7799 -i eth2 -s 192.168.57.0/24 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -s 192.168.55.0/24 -i eth0 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
EOL

### sshd
/bin/cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.dist
/bin/sed 's/^PasswordAuthentication yes/PasswordAuthentication no/' < /etc/ssh/sshd_config.dist > /etc/ssh/sshd_config

/bin/mkdir ~root/.ssh
/bin/chmod 600 ~root/.ssh
/bin/cat > ~root/.ssh/authorized_keys2 <<EOL
ssh-dss AAAA<<略>>
EOL
/bin/chmod 644 ~root/.ssh/authorized_keys2

### Mail
##### /etc/mail/sendmail.cf
/usr/bin/patch /etc/mail/sendmail.mc <<EOL
26c26
< dnl define(\`SMART_HOST', \`smtp.your.provider')dnl
---
> define(\`SMART_HOST', \`SmtpServer.LocalDomain')dnl
EOL
(cd /etc/mail; /usr/bin/make sendmail.cf)

##### /etc/aliases
/usr/bin/patch /etc/aliases <<EOL
96c96
< #root:             marc
---
> root:              root@LocalDomain
EOL
/usr/bin/newaliases

### SNMP
/bin/cat > /etc/snmp/snmpd.conf <<EOL
com2sec localhost localhost           COMMUNITY_STRING
com2sec localnet  192.168.55.0/24    COMMUNITY_STRING

group   gOpLocalhost   v1            localhost
group   gOpLocalhost   v2c           localhost
group   gOpLocalnet    v1            localnet
group   gOpLocalnet    v2c           localnet

view    all           included   .1
view    systemview    included   REDHAT-CLUSTER-MIB:RedHatCluster

access  gOpLocalhost   ""      any       noauth    exact  all    none    all
access  gOpLocalnet    ""      any       noauth    exact  all    none    all

syslocation Unknown
syscontact root@LocalDomain

disk /     100000

load 10

# for cluster
dlmod RedHatCluster     /usr/lib/cluster-snmp/libClusterMonitorSnmp.so
EOL

/bin/cat > /etc/snmp/snmp.conf <<EOL
mibs +REDHAT-MIB:REDHAT-CLUSTER-MIB
EOL

### NTP on Xen DomU
/bin/cat >> /etc/sysctl.conf <<EOL

# For ntpd on Xen DomU.
xen.independent_wallclock = 1
EOL

### cron
/bin/cp -p /etc/crontab /etc/crontab.dist
/bin/sed 's/^\(..\) 4 /\1 5 /' < /etc/crontab.dist > /etc/crontab

### grub
/bin/cp -p /boot/grub/grub.conf /boot/grub/grub.conf.dist
/bin/sed 's/ rhgb quiet//' < /boot/grub/grub.conf.dist > /boot/grub/grub.conf

### /etc/bashrc
/bin/cp -p /etc/bashrc /etc/bashrc.dist
/bin/sed 's/xterm\*)/xterm*|vt100*)/' < /etc/bashrc.dist > /etc/bashrc
この設定を元に、Xen DomU dc0を作成する。
# virt-install --name=dc0 --ram=256 --file=/dev/VolGroupXX/LogVolDc0 --mac='00:16:3e:1d:91:00' --bridge=br4000 --nographics --location='http://Repository.LocalDomain/centos/5/os/i386' --extra-args='ks=http://Repository.LocalDomain/centos/conf/DomU-DRBD-ks.cfg'
DomU dc0のインストールが完了したら、LV(logical volume, 論理ボリューム) /dev/VolGroupXX/LogVolDc0を元にDomU dc[23]用のLVをスナップショットLVとして作成する(『XenとLVM・その3・スナップショットLVの利用』参照)
# lvcreate --snapshot --size=1G --name=LogVolDc2 /dev/VolGroupXX/LogVolDc0
Logical volume "LogVolDc2" created
# lvcreate --snapshot --size=1G --name=LogVolDc3 /dev/VolGroupXX/LogVolDc0
Logical volume "LogVolDc3" created
#
続いて、dc[23]に/dev/xvdbとしてエクスポートするためのLVを作成する。
# lvcreate --size=4G --name=LogVolR0-2 /dev/VolGroupXX
Logical volume "LogVolR0-2" created
# lvcreate --size=4G --name=LogVolR0-3 /dev/VolGroupXX
Logical volume "LogVolR0-3" created
#
DomU dc2の設定ファイル/etc/xen/dc2は以下の通り。
name = "dc2"
uuid = "3cc1d59c-b2b1-42a6-b31a-35be18db188d"
maxmem = 512
memory = 256
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [  ]
disk = [ "phy:/dev/VolGroupXX/LogVolDc2,xvda,w",
"phy:/dev/VolGroupXX/LogVolR0-2,xvdb,w" ]
vif = [ "mac=00:16:3e:1d:91:02,bridge=br4000",
"mac=00:16:3e:1d:92:02,bridge=br4001",
"mac=00:16:3e:1d:93:02,bridge=br4002" ]
DomU dc2を起動する。
# xm create -c dc2
<<略>>
INIT: version 2.86 booting
Welcome to  CentOS release 5.2 (Final)
Press 'I' to enter interactive startup.
<<略>>
Starting DRBD resources:    no resources defined!
no resources defined!
[ ]no resources defined!
.
no resources defined!
no resources defined!
[  OK  ]
<<略>>

CentOS release 5.2 (Final)
Kernel 2.6.18-92.1.6.el5xen on an i686

dc2.LocalDomain login:
DRBDの設定を行っていないため、その旨警告メッセージが表示されている。DomU dc3についても同様に作業する。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

2008/07/23

Xen DomU上でDRBDを使う・その0・概要

DRBDは、ネットワーク越しにディスクのミラーリング(RAID1)を実現するソフトウェア。Xen DomU上でこの動作検証を行う。以下は今回検証環境の概念図。

今回は、『The DRBD User's Guide』の『Chapter 5. Configuring DRBD』を実行・検証する。
CentOSのRPMパッケージには、drbd 8.0系であるdrbdおよびkmod-drbd-xenと、8.2系であるdrbd82およびkmod-drbd82がある。今回は、8.2系を使用する。
検証内容は以下の通り。
  • Xen Dom0 fs1上にDomU dc[23]を作成する。
  • DomU dc[23]に対して、それぞれDom0 fs1上のLV(logical volume, 論理ボリューム) LogVolR0-[23]を/dev/xvdbとして与える。
  • DomU dc[23]上で、/dev/xvdbを低レベルデバイスとするDRBD /dev/drbd0を作成する。
  • /dev/xvdbおよび/dev/xvdbに対する書き込み速度を比較する。
なお、CentOS5では、DRBDはextra扱いであり、実用システムに適用すべきではないかもしれない。


その0・概要』『その1・Xen環境の準備』『その2・DRBD設定前の確認』『その3・drbd.confの設定』『その4・DRBDの初期化』『その5・初期同期』『その6・ベンチマーク

2008/07/21

To Do

Google Codeの中におもしろそうなものを発見→Ganeti

ずっと前から口だけ大将になっているCobbler & Koan。Extra Packages for Enterprise Linux (EPEL)にRPMが準備されているので、簡単なんだけど…