2019年2月18日月曜日

Linked Clone を Ruby で試してみた

概要

Linked Clone は差分クローンでフルクローンに比べて高速に VM をクローンすることができます
API 的に CloneVM_Task を使いますがある条件下で CloneVM_Task をコールすることで Linked Clone になります
今回は rbvmomi を使って Linked Clone API をコールしてみました

環境

  • CentOS 7.5.1804
  • Ruby 2.5.0p0
  • rbvmomi 2.0.1

Linked Clone with rbvmomi

とりあえず素の状態の VM から Linked Clone な VM を作成するスクリプトです

  • vim clone_vm.rb
require 'rbvmomi'

src = 'src'
dest = 'dest'
dc = 'dc'

vim = RbVmomi::VIM.connect(
  host: '192.168.100.10',
  user: 'vcenter-user',
  password: 'vcenter-pass',
  insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter(dc)
vm = dc.find_vm(src)
disks = vm.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk)
disks.select { |x| x.backing.parent == nil }.each do |disk|
  spec = {
    :deviceChange => [
      {
        :operation => :remove,
        :device => disk
      },
      {
        :operation => :add,
        :fileOperation => :create,
        :device => disk.dup.tap { |x|
          x.backing = x.backing.dup
          x.backing.fileName = "[#{disk.backing.datastore.name}]"
          x.backing.parent = disk.backing
        },
      }
    ]
  }
  vm.ReconfigVM_Task(:spec => spec).wait_for_completion
end
relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(:diskMoveType => :moveChildMostDiskBacking)
spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocateSpec,
                                   :powerOn => false,
                                   :template => false)
vm.CloneVM_Task(:folder => vm.parent, :name => dest, :spec => spec).wait_for_completion

ポイントは一度、素の VM に対して ReconfigVM_Task を実行している点です
「素」の VM というのは差分ディスクを持たない VM のことをいいます
この素の VM に対して CloneVM_Task を実行してもフルクローンになってしまいます
VirtualDisk のデバイスを新規に追加し追加したディスクの親ディスクを指定することで差分ディスクを作成することができます

実行結果

下の図は素の VM に対して ReconfigVM_Task を実行して差分ディスクを追加した状態のデータストアの状況です


ReconfigVM_Task 実行後

下は src_1.vmdk という差分ディスクが増えていることがわかります
また mob で「src」VM の VirtualDisk の backing の情報を見ると parent がリンク状態になり存在していることがわかります

「dest」VM のデータストアを見てみると極小の vmdk ファイルのみが作成されています

vCenter Web クライアントから見えるタスク的には再設定後に通常のクローンのタスクが実行されているように見えます
なのでタスクだけ見ても Linked Clone かどうかはわかりません

スナップショットでもいいのか

差分ディスクと言えばスナップショットです
先程のサンプルでは差分ディスクをコード上で追加しました
スナップショットを事前に作成しておくことで同じことができないかも試してみました
まず再度「素」の VM を用意しましょう
そして API でも Web クライアントでも何でもいいのでスナップショットを作成します

差分ディスクは 000001 という名前が自動で振られます

この状態で Linked Clone を実行してみましょう
今度は新規でディスクを追加するロジックをごっそり削除しています

  • vim clone_vm2.rb
require 'rbvmomi'

src = 'src'
dest = 'dest'
dc = 'dc'

vim = RbVmomi::VIM.connect(
  host: '192.168.100.10',
  user: 'vcenter-user',
  password: 'vcenter-pass',
  insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter(dc)
vm = dc.find_vm(src)
relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(:diskMoveType => :moveChildMostDiskBacking)
spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocateSpec,
                                   :powerOn => false,
                                   :template => false)
vm.CloneVM_Task(:folder => vm.parent, :name => dest, :spec => spec).wait_for_completion

これで実行しても Linked Clone になりました
ということでスナップショットを事前に作成しておくだけでも Linked Clone にすることができます
要するに元の VirtualDisk を親ディスクとして差分ディスクを追加すれば何でも良いようです

その他

bVmomi::VIM.VirtualMachineRelocateSpec:diskMoveType => :moveChildMostDiskBacking は地味に必須です
これがないと Linked Clone になりません
どういうパラメータかというとクローンする際に使用するディスクを親ディスクから共有するというパラメータになります
つまり、子ディスク (差分ディスク) だけ移動して VM をクローンすることを意味するのでこれで Linked Clone な VM を作成することができます
これを指定しないとフルクローンになるので注意が必要です

また Linked Clone VM がある状態で差分ディスクを削除することはできませんでした
ただ Web Client から試しにスナップショットを削除してみたところスナップショット自体は削除できたのですがデータストアにはまだ src-000001.vmdk が残っていました
要するに親子関係が残った状態の差分ディスクだけは削除されないということになります
スナップショットは削除できるので差分ディスクもないかなと思いきや差分ディスクはあったので気付きとしてメモしておきます

最後に

Linked Clone を rbvmomi で試してみました
最大のポイントを親ディスクを参照する差分ディスクを事前に作成しておく点かなと思います
Linked Clone は差分ディスクだけを使って VM をクローンする手法なので差分ディスクの作成自体はスナップショットなどの方法でも OK です

0 件のコメント:

コメントを投稿