Kernel/VM Advent Calender 2011 1日目

今年もKernel/VM Advent Calenderの季節がやってまいりました。一日目担当のkamiyaです。


今年は個人的にはバックアップ回りで色々と苦労した年だったので、Kernel/VMVMに多少引っかかればいいなと思いつつも「VMware vSphere Hypervisorでの、自動無停止バックアップ」についてのネタを以下に書きます。


環境

  • ネットワークに繋がったVMware vSphere Hypervisorのマシン(バージョンは3.5/4.0/4.1で確認)
  • 適当なLinuxマシン


普段ESXiを使っている場合でもvSphere Clientを使っている場合はなかなか意識されませんが、vSphereはホストに色々なコマンドを用意しています。今回はこれらのコマンドを活用して、ホストしている仮想マシンを、再度デプロイ可能なVMwareのイメージ形式にして外部のサーバにバックアップを取る手順を紹介します。


vSphereにはsshクライアントもcronもありません。しかし、公開鍵方式に対応したsshdはあります。なので、外部のLinuxサーバから、sshdを経由してバックアップコマンドを呼び出し、scpで転送するという方針の下で話を進めます。


まずは、vSphere Hypervisorをインストールして、メニューからsshdを有効化しておきます。古いESXi Hypervisorをお使いの場合はunsupportedで有効化してください。


vSphereのsshdが利用する公開鍵は、vSphere 4.xまでは /.ssh/authorized_keys vSphere 5からは /etc/ssh/keys-root/authorized_keys となっています。これらは、ホストの再起動で消えてしまう場合があるので注意してください。


Linuxマシンのcronから自動でコマンドを実行する為に、空のパスワードの鍵ペアを作成します。奪取されるとvSphereのホストに対して任意のコマンドを実行出来てしまうので、取扱いには注意してください。


以上が前準備です。


vSphereは(というかVMware製品は)、スナップショットという便利な機能を備えていて、スナップショット取得時以降を差分として保持し、いつでも巻き戻せる様になっています。そして、仮想ディスクイメージファイル(.vmdk)はロックされていますが、スナップショットを取得したら、その時点までの部分に対するイメージのロックが外れ、バックアップを取ることが可能になります。以下に実際に利用しているバックアップ用スクリプトを掲載します。



#!/bin/bash
# ターゲットのVMIDを確認するためにはvSphereホストで "vim-cmd vmsvc/getallvms" を実行
# 下のESXI_HOSTとVMIDを入れたら多分動く

ESXI_HOST=
VMID=

# 仮想マシンの名前を取得
TARGET=`ssh root@$ESXI_HOST vim-cmd vmsvc/getallvms | grep $VMID | awk '{print $2}'`

# 仮想ディスクイメージの実際の名前(.vmdk)を取得
IMAGE=`ssh root@$ESXI_HOST ls -la /vmfs/volumes/datastore1/$TARGET/ | grep vmdk | grep -v flat | awk '{print $9}' | sed s/\.vmdk//`

# バックアップ用に名前の重複しないディレクトリを作るために宣言
BACKUP_DIR=BACKUP_${TARGET}

# フォルダを作って、VMイメージのメタデータをコピーしておく
ssh root@$ESXI_HOST mkdir -p /vmfs/volumes/datastore1/${BACKUP_DIR}/
ssh root@$ESXI_HOST cp /vmfs/volumes/datastore1/$TARGET/*.vmx /vmfs/volumes/datastore1/${BACKUP_DIR}/
ssh root@$ESXI_HOST cp /vmfs/volumes/datastore1/$TARGET/*.vmsd /vmfs/volumes/datastore1/${BACKUP_DIR}/
ssh root@$ESXI_HOST cp /vmfs/volumes/datastore1/$TARGET/*.vmxf /vmfs/volumes/datastore1/${BACKUP_DIR}/

# スナップショットを作成
ssh root@$ESXI_HOST vim-cmd vmsvc/snapshot.create $VMID Backup

# スナップショット時点までの仮想HDDイメージを作成
# 実際に利用している領域分のみのイメージを作る
ssh root@$ESXI_HOST vmkfstools -i /vmfs/volumes/datastore1/${TARGET}/${IMAGE}.vmdk -d monosparse /vmfs/volumes/datastore1/${BACKUP_DIR}/${IMAGE}_thin.vmdk

# スナップショットを削除
ssh root@$ESXI_HOST vim-cmd vmsvc/snapshot.remove $VMID

# Linuxマシンに転送
mkdir /var/backup/esxi/$TARGET/
scp -r root@$ESXI_HOST:/vmfs/volumes/datastore1/${BACKUP_DIR}/ /var/backup/esxi/$TARGET/

# vSphere側にあるイメージファイル達を削除
ssh root@$ESXI_HOST rm -rf /vmfs/volumes/datastore1/${BACKUP_DIR}


以上の流れで、vSphere 3.5〜5.0までの全てで動作を止める事なく仮想マシンのバックアップを取る事が出来ます。ちなみに復元する場合は、復元する先のvSphereホストにバックアップを取ったイメージやメタファイル一式を転送した上で、


vmkfstools -i image_thin.vmdk -d thin image.vmdk


として元のイメージファイルサイズに戻した上で、vSphere Clientからデータストアを参照し、メタデータを選択してインベントリに追加することで普段通りに利用できます。(復元は3.5/4.0/4.1/5.0のバックアップを5.0上で復元する物しか試していませんが…)


もしインベントリに追加した後に起動で失敗する場合は、vmxファイル内で記述されているディスクイメージと展開した後のディスクイメージが同一であるか確認してください。また場合によってはファイルをコピー/移動したかの確認が入る事もありますので、その場合は「I copied it」等を選択してください。


# 来年はKVMで似たようなバックアップネタを書きたい orz