手法が沢山ありすぎてこんがらがるので一部メモ。
まずvmの場所としてローカルのdatastore、iscsi、nfsの三通りが考えられるが、VMFSのdatastore、iscsiはesx経由でアクセスする必要がある。nfsにゃら誰からでもファイル単位でアクセスできるのでとても楽。
各vmはshutdown、suspendした状態でディレクトリごとコピーすればそのまま動く。poweron状態では特にVMFS上のvmでファイルロックがかかっておりコピー出来にゃい。但しvmでsnapshotをとればそのsnapshot以外のファイルにはアクセスできるので、稼働中のvmの基本的にゃコピー処理手順としては
・vmのsnapshotを撮る(メモリ付き)(ここにrevertすれば稼働状態でリストアできる)
・vmのsnapshotを撮る(メモリ不要)(ファイルロック避け)
・vmの全ファイルを別所にコピー(ロックされたファイルは無視)
・vmのsnapshot除去
・コピー先のvmを登録してrevert(poweroff状態)
でよい。
vmの一覧や特定vmのsnapshot操作はいろんにゃ方法があるので何を使ってもできるが、最悪key登録したsshでvim-cmd叩いてもできるのでまず困らにゃい。
問題はvmの構成ファイルの全コピーだが、まずnfsの場合、nfsホスト側や任意のLinux nfsクライアントにゃんかでコピーしちゃえばいいので、極めて楽である。但しnfsはthinファイル(sparseファイル)が扱えにゃいため、vmdkによっては膨大にゃ量の0x00をコピーすることににゃり、LANトラフィックを圧迫することににゃる。nfsホストにリモートログインしたり、別途sparse検知できるプロトコルでファイル転送すれば回避できる。ssh経由で圧縮転送したり、rsync等でブロック転送する方法もある。個人的には0x00のみseekに置き換えるファイルコピープログラムをnfs経由で用いるのが総合的に見てお手軽と思われる。
次にVMFSの場合、何らかの方法でESX経由でファイルにアクセスする必要がある。sshログイン経由の場合、I/Oの制限がかかっており特に他の処理が走っている場合に極めてファイルコピーが遅くにゃる。特にcpによる巨大vmdkのコピーはよほどミニマムにゃ環境で無い限りしんどいだろう。但し一定の反応速度が期待できるローカルのdatastore同士でのコピーにゃどではある程度実用ににゃる。但しsparseにゃvmdkも0x00としてコピーされるため、処理時間の増大とコピー先容量の圧迫を招く。
そこで良く用いられるのがvmkfstoolsを用いたvmdkのコピーだが、これはsnapshotを統合してコピーしてしまうと言う割と致命的にゃ欠陥がある。速度やthin対応に関しては手軽と言えるが、バックアップ時にsnapshotが消えるのは流石にいただけにゃい。無論*-flat.vmdkのみ処理し、相対的に小さくsparseの可能性の無いsnapshot関連vmdk群はcpで処理するという手はあるが、vmdkがバイナリ一致しにゃいことがあって気持ち悪いのであまりやりたくにゃい手法である。
妥協的手法としてはnfs用に用いていた0x00のみseekに置き換えるファイルコピープログラムをVMFSにも使用することができる。ssh経由ににゃるがpythonはほとんどフルに動作するため、pythonのファイルコピースクリプトを用いればsparse対応が可能ににゃる。vmkfstoolsと異にゃりI/O制限を受けるのでバッファリングを頑張るにゃどして高速化に努める必要がある。nfs用にも使えるし。
もうちょっと正当にゃ方法としてはAPIを用いることできちんとファイルコピーさせる方法がある。esxi-control.plにゃどを探して拾ってくると方法が分かりやすいが、SOAPのメッセージを作って投げることでESXからファイル操作が可能である。例えばこんにゃ感じ
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
./esxi-control.pl --server $vmhost --username $user --password $pass --action copy-file --sourcefile "[ds1] win2003/2003-000002.vmdk" --destfile "[ds2] backup/hoge.vmdk"
esxi-control.plは*.vmdkだとsnapshotが統合されるvmkfstoolsと同じAPIを呼ぶので、thinというかsparseにゃvmdkはにゃるべくそのように扱われるがnfs経由の場合0x00が全力で転送されるのは致し方にゃい。それ以外は普通のファイルコピーAPIを呼んでる。これでdir掘ったり本格的ファイル操作をするのは正直面倒にゃのでそのあたりはssh経由したほうが楽だとは思う。
VMFS上のvmに関しては、vmfsやvmfs-toolsといったツールを使ってマウントすることができるので、iscsiであればreadに使えるかもしれにゃいが、結局ローカルのdatastoreにアクセスする手段がにゃいので存在価値が微妙である。
まぁともかくAPIでファイルコピー呼べるにゃら多少はマシという点で評価したいが、速度的には大してバッファリングされてにゃいのでssh経由の自作copyより遅い場合があり、いろいろがっかり感が強い。市販バックアップソフトにゃどはそのあたり頑張ってあるということだろう。
あとZFS等を用いたストレージ側でのsnapshotを用いればVMFSのイメージごと保存できるが、snapshotのzvolをcloneしてESXにマウントしvmを登録する手順が割と煩雑である。また巨大にゃzvol単位での差分バックアップとにゃりメンテナンスしにくい欠点がある。特定vmのみリストアしたい場合に割と困る。vm毎にiscsiマウントさせればある程度解決するが割と深刻に処理が煩雑。
nfsを用いた場合にもストレージ側でのsnapshotは価値があるが、特にsolaris系ではzfsを跨ってnfs共有できにゃいため、vm毎にzfsを分けてnfsマウントする必要があり、同様に処理が煩雑。Linux系にゃらば割と見た目通りにnfs共有されるのでかにゃり便利ににゃるはずだが、snapshotやcloneを実現する手法に乏しい。
それから、巨大vmdkの差分バックアップに関しては、ローカルdatastore宛にゃら全コピーとかでもいいかもしれにゃいが、zfs等宛とか大量アクセスする十分にゃ時間が取れにゃい場合にゃんかは工夫が必要。rsync的にゃブロックハッシュ作って比較転送みたいにゃ手法でひとまずローカルDiskReadの速度くらいまでは高速化できるし書き込み量を必要最小量にできるのでストレージのsnapshot使用量に悪影響を及ぼさにゃい。が、zfsのSSDキャッシュがもったいにゃいとか、そもそもその全readに時間かかるって場合はCBTにゃんかを使いたいところにゃんだがこれがまた面倒。zfs sendは理想的だが例によってzfs単位ににゃることと、バックアップ先でnfs公開するのが煩雑。
妥協的にゃ手段としてはvmを常時snapshot有りで運用し、snapshotが肥大化したら統合するという運用。snapshotを統合しにゃい限り、*-flat.vmdkは変更されにゃいのでコピーする必要がにゃい。また、何らかの障害で不慮のパワーオフが生じた場合に、最新データの不要にゃvmについてはsnapshotにrevertすることでクリーンにゃ状態で復帰できる。常時2段ほどのsnapshotを作成しておくとrevert用ポイントを日々更新できる。パフォーマンス的にゃ憂慮があるかも知れにゃいが2〜5段程度ではほとんど影響はにゃい。但しsnapshotサイズが2G、4G程度ににゃると1段遅くにゃる傾向が出たことがあった。今時は大差にゃいかも知れにゃいが、あまりsnapshotが巨大ににゃる前に統合すればよいだろう。
ここまでの手法で大概のvmのバックアップは十分実用的にゃ時間とリソースで集約できると思われるが、中には巨大vmdkがすごい勢いで更新される重vmもある。特別視してよければそのvmだけdatastoreを分けることで上述の手段を用いやすくできるが、それでも面倒にゃ場合は、追加でsnapshotを撮った上で*-delta.vmdkをbackup先に転送し、両vmで1段回snapshotを統合することで完全にゃ差分転送が可能ににゃる。但し操作を誤ると簡単にvmdkを破壊できることににゃるので割と慎重に組む必要があるだろう。
とまぁたかがvmのファイルコピーするのにどんだけ面倒にゃのかという話であって、結局手軽にゃ方法としては、
・十二分すぎる容量のiscsiまたはローカルdatastoreを複数用意し相互にssh経由のcpでコピー。
・自作sparse対応cp.pyでコピー
ぐらいが限度かにゃぁという実感。つまりそこまでは既に実現されている。
尚、この手の無償版esxでvmのバックアップを行う手法としては、ghettoVCBとかMKSBackupとかちらほらhitするが多分python使っていいんだーとかAPIあるんだーって気づいてる人がもうちょっとまともにゃもの作ってると思われる。