0.前書き
今回は、無償版のESXiのホストおよび仮想マシンのバックアップを
取得するためのスクリプトを書き、Cronで設定します。
本来、ESXiで仮想マシンのバックアップを取得するには、
vCenterサーバが必要ですがghettoVCBを利用すれば、
スナップショットからバックアップを生成することができます。
ghettoVCBのインストールから、スクリプトの中身まで、
雑に紹介していきます。
1.環境説明
まずうちの環境を説明すると、
ESXiは自作PCで稼働しており、Raspberry Pi 4上にUbuntuを入れて
iSCSIターゲットを構築しています。
そしてすべての仮想マシンはRaspberry Pi 4に、
接続しているHDDに保存しています。
要するにESXiの仮想基盤と仮想マシンは別のストレージで管理しています。
そこで今回実現するのは、以下の通りです。
①ESXIホストのバックアップデータは仮想マシン上で動いているファイルサーバに保存
②仮想マシンのバックアップデータはESXiホストと同じデータストアに保存
では①を行うための下準備であるghettoVCBのインストールから始めていきます。
2.ghettoVCBのインストール
まず、以下のサイトからghettoVCB-master.zipをダウンロードします。
ESXiのデータストアブラウザにghettoVCB-master.zipを
アップロードして解凍します。
unzip ghettoVCB-master.zip
解凍後のファイルの置き場は、任意の場所で問題ないです。
私はデータストアブラウザのデフォルトのディレクトリの直下に
BACKUPフォルダを作成して置きました。
最後にZipファイルを削除してインストール完了です。
3.スクリプトの記述
ghettoVCB-masterの中には、ghettoVCB.shというスクリプトがあり、
以下のコマンドを実行することですべての仮想マシンのバックアップを取得可能です。
./ghettoVCB.sh -a
今回参考にさせていただいたスクリプトでは、
ghettoVCB.shとは別にスクリプトファイルを作成し、
より細かな設定に対応しています。
ちなみにghettoVCB.shを手動で変更する箇所はありません。
※新規作成するスクリプトの中で、ghettoVCB.sh上の
バックアップ保存先のパスを書き換えています。
もし、バックアップ取得の世代数をデフォルトの3世代から
変更したい場合は、ghettoVCB.shの
「VM_BACKUP_ROTATION_COUNT=」の値を書き換えてください。
また、ghettoVCB.confという構成定義ファイルがあり、
以下のようにオプション指定すると、
ghettoVCB.shではなく、ghettoVCB.confの内容でスクリプトが実行されるようです。
./ghettoVCB.sh -g ./ghettoVCB.conf
ただ今回は全く利用していません。
では、本題のスクリプトに入っていきます。
スクリプトの置き場所は任意の場所で大丈夫ですが、実行権限付与をお忘れなく。
以下スクリプトの中身です。
##おまじない
set -exo pipefail
##バックアップファイル保存先パス
VM_BACKUP_VOLUME=/vmfs/volumes/内臓SSD/BACKUP/VMBACKUP
##「ghettoVCB.sh」のパス
SCRIPT_DIR=/vmfs/volumes/内臓SSD/BACKUP/ghettoVCB-master/
##仮想マシン名一覧のファイル名を変数に代入
VMLIST_FILE=vmlist.txt
##除外一覧のファイル名を変数に代入
IGNORE_VMLIST_FILE=ignore.txt
##このスクリプトのパスを変数に代入
CURRENT_DIR=$(cd $(dirname $0); pwd)
##Retention Period Option
RETENTION_PERIOD_OPTION=”-mtime +7″
##ディレクトリが存在するかしないか
if [ -d ${SCRIPT_DIR} ]
##存在している場合
then
##ghettoVCB.shの「VM_BACKUP_VOLUME=」を「VM_BACKUP_VOLUME=${VM_BACKUP_VOLUME}」に置換
sed -i “/^VM_BACKUP_VOLUME=/c VM_BACKUP_VOLUME=${VM_BACKUP_VOLUME}” ${SCRIPT_DIR}/ghettoVCB.sh
##仮想マシンの一覧を取得し、「getallvms.txt」に書き出す
vim-cmd vmsvc/getallvms | grep vmx | awk ‘{print $2}’ > ${CURRENT_DIR}/getallvms.txt
##除外一覧が存在するかしないか
if [ -f ${CURRENT_DIR}/${IGNORE_VMLIST_FILE} ]
##存在する場合
then
##「getallvms.txt」の記載内容と除外一覧の並びをそろえて、重複した行を削除したうえで、「vmlist.txt」に書き出す
sort ${CURRENT_DIR}/getallvms.txt ${CURRENT_DIR}/${IGNORE_VMLIST_FILE} | uniq -u > ${SCRIPT_DIR}/${VMLIST_FILE}
##存在しない場合
else
##「getallvms.txt」を「vmlist.txt」に書き出す
cat ${CURRENT_DIR}/getallvms.txt > ${SCRIPT_DIR}/${VMLIST_FILE}
fi
##バックアップ開始
${SCRIPT_DIR}/ghettoVCB.sh -f ${SCRIPT_DIR}/${VMLIST_FILE}
##除外一覧を加える
ignore_path=“”
##
num=`wc -l ${CURRENT_DIR}/getallvms.txt | awk ‘{print $1}’`
i=0
##「getallvms.txt」の内容ををひとつづつ読み込み、引数lineに渡したあとif文の処理を実行
while read line
do
if [ $i -eq 0 ]
##一番最初だけに実行
then
ignore_path=”-type d ( -name $line “
elif [ $i -eq `expr $num – 1` ]
##一番最後だけに実行
then
ignore_path=”${ignore_path} -o -name $line ) -prune -o “
else
ignore_path=”${ignore_path} -o -name $line “
fi
i=`expr $i + 1`
done < ${CURRENT_DIR}/getallvms.txt
##仮想マシン一覧に無いデータを保存期間経過後に削除する
find ${VM_BACKUP_VOLUME} ${ignore_path} -type d -maxdepth 1 -mindepth 1 ${RETENTION_PERIOD_OPTION} -print | xargs rm -rf
黄色のマーカーで塗った部分は環境に合わせて変更してください。
あまり詳しくはないですが、ESXiのスクリプトではシバンが必要ないようです。
スクリプトができたら、まず手動で動かしてみましょう。
./backupVM.sh
以下の表示が出たら無事に完了です。
info: ============================== ghettoVCB LOG END ================================
4.ESXiへのCron設定
ESXiではCron設定を行う際に、
/var/spool/cron/crontabs/rootに記載しなければなりませんが、
権限を変更しなければ編集することはできません。
また、/var/spool/cron/crontabs/rootに記載した内容は、電源を落とすと消えてしまいます。
なので起動後に再度/var/spool/cron/crontabs/rootにCron設定する方法として、
/etc/rc.local.d/local.shに記載します。
vi /etc/rc.local.d/local.sh
#!/bin/sh ++group=host/vim/vmvisor/boot
# local configuration options
# Note: modify at your own risk! If you do/use anything in this
# script that is not part of a stable API (relying on files to be in
# specific places, specific tools, specific output, etc) there is a
# possibility you will end up with a broken system after patching or
# upgrading. Changes are not supported unless under direction of
# VMware support.
# Note: This script will not be run when UEFI secure boot is enabled.
/bin/echo “0 3 * * * /bin/sh /vmfs/volumes/61d226cd-83332f25-e3c1-001517a5be64/BACKUP/script/backupVM.sh” >> /var/spool/cron/crontabs/root
/bin/kill $(cat /var/run/crond.pid)
/bin/crond
exit 0
※ESXiホストはUTC時刻が固定で、変更できないため、
バックアップを取得したい時刻-9時間を記載すること。
今回の場合、12時での取得
記載後ESXiホストを再起動して、
/var/spool/cron/crontabs/rootの記載内容を確認し、
問題なければ仮想マシンのバックアップの自動化完了です。
では続いて、ESXiホストのバックアップに参ります。
5.ESXiホストのバックアップ
今回バックアップファイルの保存先は仮想マシン上のファイルサーバなので、
scpで転送する必要がありますが、scpをCronで自動化するには
expectコマンドを利用する必要があります。
しかし、ESXiホストにはexpectがインストールされていません。
そこで、ファイルサーバからsshでESXiホストをリモートし、
バックアップファイルを作成した後、scpで転送することにしました。
処理の流れを簡単に説明します。
2日前のバックアップを削除しています。ファイルサーバのスクリプト実行と
バックアップファイル保存先のフォルダの所有者が異なるため、
一度ユーザを変更しています。不要な可能性が高いので、その場合は削除してください。
その際、ESXiホスト上のバックアップの保存先のパスが毎回変更になるため、
あらかじめ、バックアップファイル作成時にパスを変数に代入しておきます。
日付付きのファイルをファイルサーバへ転送します。
ファイルサーバのスクリプトの内容は以下です。
#!/bin/bash
####おまじない####
set -exo pipefail
####前前回分バックアップファイルを変数に代入####
DAYBEFOREYESTERDAY=`date +%Y%m%d –date ‘2 day ago’`
RMFILE=/home/share/バックアップ/ESXiホストバックアップ/${DAYBEFOREYESTERDAY}_configBundle-esxi.home.miyamo83.com.tgz
####前回分バックアップファイルがあった場合以下を実行####
if [ -e $RMFILE ]; then
expect -c “
##待機時間を1秒にする
set timeout 1
##削除権限を持つ********ユーザに切り替え
spawn su -l ********
expect \”Password:\”
send \”********\r\”
##前前回分バックアップファイルを確認メッセージなしで強制削除
expect \”\\\$\”
send \”rm –force ${RMFILE}\r\”
expect \”\\\$\”
send \”exit\r\”
“
fi
####バックアップファイルを作成し、ファイルサーバの所定の場所へ転送する処理####
expect -c “
##待機時間を1秒にする
set timeout 1
##ESXiにssh接続
spawn ssh********@********
expect \”\*yes/no\*\” {
send \”yes\r\”
expect \”Password:\”
send \”********\r\”
} \”Password:\” {
send \”********\r\”
}
##バックアップファイル作成しつつ、保存先ファイルパスが毎回変化するため、パスの39桁以降の可変部分を切り取って変数に代入
expect \”\\\$\”
send \”TEMP=\`vim-cmd hostsvc/firmware/backup_config | cut -c 39-\`\r\”
##不変のファイルパスと可変のファイルパスを合体したフルパスを変数に代入
expect \”\\\$\”
send \”BACKUPORIGINAL=’/vmfs/volumes/61d226cd-69df189d-adf0-001517a5be64‘\$\{TEMP\}\r\”
##フルパスのバックアップファイルのファイル名に生成日を付け足したフルパスを変数に代入
expect \”\\\$\”
send \”BACKUPCOPY=\$\{BACKUPORIGINAL/configBundle-esxi.home.miyamo83.com.tgz/\`date +\’%Y%m%d\’\`_configBundle-esxi.home.miyamo83.com.tgz\}\r\”
##ファイルをコピー
expect \”\\\$\”
send \”cp \$\{BACKUPORIGINAL\} \$\{BACKUPCOPY\}\r\”
##ESXIからファイルサーバへバックアップファイルを転送
expect \”\\\$\”
send \”scp \$\{BACKUPCOPY\}********@********:/home/share/バックアップ/ESXiホストバックアップ\r\”
expect \”\*yes/no\*\” {
send \”yes\r\”
expect \”Password:\”
send \”********\r\”
} \”********@********‘s password:\” {
send \”********\r\”
}
expect \”\\\$\”
send \”exit\r\”
“
※ユーザ名やパスワードは伏字にしています。
黄色でマーカーを付けている部分は環境に合わせて変更してください
スクリプトが完成したら、手動実行し、
保存先へファイルが生成されていれば完了です。
私は設定していませんが、スクリプト失敗時に
通報メールを飛ばすなどの設定を入れるといいかもしれません。
6.ファイルサーバへのCron設定
おなじみのCron設定です。
crontab -e
0 9 * * * /home/*****/vmhostbk.sh
※ユーザの直下に置いているため、伏字にしています。
ファイルサーバ上では朝9時に実行していますが、
例のごとく、ESXiホスト上では0時に実行されていることになっています。
7.後書き
今回の設定で、ESXiホストと仮想マシンの相互バックアップ保管が完了しました。
ちなみに、取得した仮想マシンのバックアップファイルは、
「仮想マシンの作成/登録」の後、「既存の仮想マシンの登録」をクリック、
vmxファイルを選択することでリストアできます。
検証としてテストサーバをデプロイし、
バックアップを取得してからテストサーバを削除しました。
そのあと、vmxからリストアしたところ、無事にファイルの中身まで
復元できていましたので、問題ないと思います。
一点気になったのは、リストアするとvmxを含めたすべての
バックアップファイルが削除されていました。
バックアップからリストアする場合、なぜか復元後に削除されるみたいですね。
なんで?…
コメント