7月 05

以前、仮想ゲストOSのバックアップについて、簡単に書きましたが、当方の環境もここまでESXi密度が高いと、「もしも・・・」の時に涙ちょちょ切れ~ってことになるので、スナップショットとクローン作成を利用したバックアップ作成スクリプトを作ってみました。お役に立てれば・・・
当方の環境は、バックアップ用ボリュームがESXi上にnfsマウントされており、以下のスクリプトはそこに作成されるような仕組みになっていますので、環境に合わせて変数内容を変えてください。尚、このスクリプトを作成するにあたり、「AKIONWEB」さんのところを参考に作ってみましたが、動作結果については自己責任と言うことで。
では、まず環境条件から・・・といっても上に書いたように、

  • ESXiからバックアップボリュームが見えていること
  • 引数としてはゲスト名だけを使用する
  • バックアップは上書きでも良しとすること

だけです。
では、続きと簡単な解説は、続きでどうぞ。(かなり長いです・・・が、やっていることは大したことないです)
追記:07/11 追加・修正部分あり

#!/bin/ash

###	But I'm sorry, follows comments are Japanese-English, you may not understand it.
###	This script does backup without rotate.

###
#	Input
#	$1 : Guest name
#
#	Internal variable
#	$gname	: Guest name
#	$gid	: Guest ID
#	$store	: Gust datastore name
#	$gdir	: Gust datastore directory
#	$bdate	: Backup date 
#	$bbase	: Backup base directory(/vmfs/volumes/esx01-backup/)
#	$bdir	: Backup directory
#
#	07/05/2009 by hiro
#	07/07/2009 add and fix by hiro
###

###-----
#	wait current snapshot creation work
#
check_running_task (){
for i in `vim-cmd vimsvc/task_list | grep vim.Task:haTask-$1 | grep $2 | sed -e 's/.*vim.Task://' -e "s/[', ]//g"`; do
if [ "`vim-cmd vimsvc/task_info $i | grep running`" != "" ] ; then
	return 0
fi
done
return 1
}
#
###-----

###=======================
#
#	Start main
#
###=======================

# the backup root directory
bbase="/vmfs/volumes/esx01-backup/"

#bdate=`date +%Y%m%d`
#echo $bdate

# the Guest name and get the Guest ID
# -------------------------------------------------------- 07/07/2009 added by hiro
#   Check parameter
if test -z $1
then
        exit 1
fi
gname=$1
gid=`vim-cmd vmsvc/getallvms | grep $gname | awk '{ print $1 }'`
# -------------------------------------------------------- 07/07/2009 fixed by hiro
#   Changed how to check GID
# if [ $? -eq 0 ]; then
if test -z $gid
then
	echo "Error : Guest - "$gname" did not exist."
	exit 0
fi

# take store location of the Guest and set full directory path of the Guest VM files
store=`vim-cmd vmsvc/getallvms | grep $gname | sed -e 's/\[//g' -e 's/\]//g' | awk '{ print $3 }'`
gdir="/vmfs/volumes/"$store"/"$gname"/"

# set backup directory path
bdir=$bbase$gname"/"
if test ! -d $bdir
then
	mkdir $bdir
else
	echo "Already exist backup file."
fi

###-----
#	Start backup
#
#---(Part.1)	copy VM managed information files, you have to copy these informations before make a clone.
#
cp $gdir$gname".vmx" $bdir
cp $gdir$gname".vmxf" $bdir
cp $gdir$gname".vmsd" $bdir
#
#---(Part.2)	take a snapshot
#
vim-cmd vmsvc/snapshot.create $gid $gname
if [ $? -ne 0 ]; then
	echo Snapshot create error.;
	exit;
fi
while check_running_task $gid createSnapshot; do sleep 1; done
#
#---(Part.3)	cloning with monosparse, if you want flat image, remove option.
#
vmkfstools -i $gdir$gname".vmdk" -d monosparse $bdir$gname".vmdk"
if [ $? -ne 0 ]; then
	echo "Error : cloning failed. your backup process did not complete."
	exit 0
fi
#
#---(Part.4)	remove a snapshot
#
vim-cmd vmsvc/snapshot.removeall $gid
#
#	Backup finished

echo "Congratulations!  Guest-"$gname" : backup completely successed."
exit 0
#
###-----
  1. まず、23~30行目の関数について
    ここは、このスクリプトを何度も叩くと、スナップショット(や解放)がその回数分叩かれることになり、あまりESXiに優しくないので、もし前の処理が残っていたのならば、まだ終わっていない事を関知し、通知する関数です。
  2. 41行目の変数について
    この変数は、バックアップが保存される親のディレクトリを指します。このディレクトリの後に、ゲスト名がついたディレクトリが実際のバックアップ先(59行目)になります。
  3. 47~52行目
    ここでは、引数で渡されたゲスト名を保存し、またこのゲスト名を利用してIDリストから該当のID番号を取得しています。コマンド「vim-cmd vmsvc/getallvms」を叩くと、登録されているゲストの一覧が出力されます。以下が実際の出力例。

    # vim-cmd vmsvc/getallvms
    Vmid      Name                       File                          Guest OS          Version   Annotation
    528    witkitty     [datastore1] witkitty/witkitty.vmx       otherLinuxGuest         vmx-04
    544    VpnSrv       [datastore1] VpnSrv/VpnSrv.vmx           otherLinuxGuest         vmx-04
    592    clone        [datastore1] clone/clone.vmx             otherLinuxGuest         vmx-04
    

    この中に該当するゲストのIDが先頭にありますので、ゲスト名でgrepし、IDをawkコマンドで引っぱがします。(次の項でに3番目にあるFile項の中のdatastore?も引っぱがすことになります)ここで、該当ゲスト名が無ければエラーでスクリプトが終了します。

  4. 55~57行目
    ここでは、ゲストファイルの配置情報を取得します。当方のESXiは、ディスクドライブが複数あり、そのうちのいくつかがdatastoreとして登録されています。よって、ゲストによっては同一ESXi上であっても配置されているdatastoreが異なります。1つしかない環境の場合は、後で示すバックアップ元ディレクトリ変数の中で固定していいと思います。
  5. 59~65行目
    ここで、バックアップ先ロケーションを決定しています。決定されたディレクトリがあるかチェックしていますが、必要無いような気もしますが、後でバックアップの世代管理もやってみようと画策しているので、その時のためのものです。
  6. 72~74行目
    ここから実際のバックアップ処理(クローン作成)が始まります。まず、ゲストの管理ファイルをコピーします。AKIONWEBが仰るには、これを先にしておかないと、後でファイルを編集する必要があるとのことでしたので、そのまま掲載させてもらいました。
  7. 78~83行目
    ここでスナップショットを取得します。この処理で後述の仮想実体ファイルへのアクセスが可能になります。で、ここで指定のスナップショットが行われたかどうかを冒頭の関数でチェックし、スナップショットが始まったら、実体ファイルの処理に移ります。
  8. 87~91行目
    ここで、vmkfstoolsコマンドを利用して実体ファイルをクローニングします。当方はmonosparseオプションを利用してバックアップ先のファイルを小さくしていますが、ボリュームサイズが潤沢の方は素のままでもいいのではないかと思います。これはリストアの時に関係していて、小さくした場合、ESXiはその小さいままのファイルを扱うことが出来ず、元の大きなファイルに戻してあげる作業が必要になります。
  9. 95行目
    さて、そろそろ終わりですね。クローニングが完了したら、スナップショットを解放してあげます。

これで、晴れて半自動でのゲストOSのバックアップが可能になりました。あとは、cronに任せることと、バックアップの世代管理機能、リストアスクリプトを組み込めれば安心して眠れます。この辺はまた後で書ければいいかなと・・・(何かいつも最後に自分で宿題作っているような・・・)
試しにこのスクリプトでバックアップし、手動でリストアを行ってみましたが、無事ゲストOSがバックアップ前の状態で稼働しました。(何度も言いますが自己責任で・・・しつこいって)
ではでは。

written by hiro \\ tags: , , , , , ,

One Ping to “仮想ゲストOSバックアップ~スクリプト編~”

  1. 仮想ゲストOSバックアップ~cron登録~ | Whimsical Kitteeeeen Says:

    […] 仮想ゲストOSバックアップ~スクリプト編~ […]


Leave a Reply

*