VirtualBox和Vagrant虚拟机迁移复用及原理

2,258 阅读3分钟

看完此文, 你将:

  1. 再也不用担心因 VirtualBox 卸载|损坏, 或更换电脑后, 辛苦搭建的虚拟机环境丢失了.
  2. 虚拟机文件随意迁移. 文后, 有自动帮你迁移虚拟机的 Python 脚本. 轻松给你的虚拟机换新家. 文章有点啰嗦, 请耐心阅读, 欢迎评论!

为说明方便, 先声明几个概念:

  • VB : VirtualBox
  • vbox : VB 列表里看到的虚拟机的抽象表述, 含有两个核心文件: 元数据和磁盘文件. 如: {虚拟机名}.vboxcentos-7-1-1.x86_64.vmdk .
  • Vgrant workspace(ws) : vagrant 工作空间, 一个空间可能关联(管理)单个虚拟机或多个虚拟机.

Vagrant 和 VirtualBox(VB) 关联原理

角色: • 虚拟机(vbox) • 存储介质(vmdk or vdi) • vagrant

vbox 和 vmdk:

virtualbox 本身有 vbox 和 虚拟磁盘(如vmdk, 下文以vmdk代表磁盘) 两个关键概念. vbox 其实就是一些xml配置(虽然图标看起来是个盒子), vmdk 才是真正意义上的机器. 每个 vbox 和 磁盘 都有唯一标识uuid. virtualbox界面上看到的机器列表, 其实就是各个vbox的配置生效的结果. 同时各个vmdk也会注册(就是xml配置)在virtualbox的中, 就是{用户}/.VirtualBox/VirtualBox.xml. 所以, 逻辑链就是, vbox id --> vmdk id .

.vbox 配置 Machine uuid="{ef0252c6-adcc-4800-beb8-8ae4ec5cd03e}" AttachedDevice e788ac71-6cb0-45ab-90fd-f9411d5b0ff2 (这个必须是事先注册过vmdk等存储介质, 见: {用户}/.VirtualBox/VirtualBox.xml MediaRegistry.HardDisks[].HardDisk.uuid , 注意这个配置会被当前内存中最新的覆盖. 所以要想修改, 需要停止vbox服务)

vagrant工作目录

.vagrant\machines\default\virtualbox\id ef0252c6-adcc-4800-beb8-8ae4ec5cd03e 这个id就是上面vbox的id.

vagrant 工作目录中.vagrant\machines\default\virtualbox\id 的id就是对应的vbox id. vagrant up 时, 会拿着这个id请求virtualbox, virtualbox根据这个box id定位到最终的vmdk. 逻辑链就是, vagrant的默认机器id --> vbox id --> vmdk id.

.vagrant/ 下的虚机元数据中, id 文件正好对应 VB 注册的 vbox id (MachineEntry).

迁移

CASE 1: 从别的电脑上复制过来的 vbox 和 vmdk , 安到'新家' CASE 2: VB 重装了. 旧的虚机注册信息丢失. 但 vbox 和 vmdk 还在. 复用后, 虚机复用, 环境不丢失.

方式1: 手动迁移

经过上面的分析, 从别处迁移过来的虚拟机, 只要有完整的 vbox 和 vmdk 即可.

  1. 注册vmdk:

2. 注册 vbox

3. 确保 vagrant 中id文件和 vbox id 一致.

总结:

  1. 将迁移过来的 vbox 及其 vmdk 注册到当前目标virtual box中.
  2. 确保 .vagrant\machines\default\virtualbox\id 文件中的id和上步中的vbox id一致. 没有则新建.
  3. vagrant up. 这样就成功为vagrant box换了个"新家"了(virtual box).

或, 手动修改 VirtualBox.xml 完成 vbox 和 vmdk 的注册. ( 退出VB, 退出VB ). 这也下文能够脚本化的原因.

方式2: 脚本自动化迁移

针对迁移场景, 笔者写了简单的Python脚本方便大家操作.

流程:

== 迁移 vbox ==
写入或更新vbox到 VirtualBox.xml 中(注册)
1. 拿到 VMs/foo/foo.vbox 的 vbox id 和 vmdk id
2. VB 退出状态下, 写入 VirtualBox.xml 

== vagrant 迁移 ==
入参:
- VB存储目录(含有所有虚机介质),
- vagrant 某个虚机的工作目录.
流程:
工作空间下遍历所有虚机(.vagrant/machines/), 即获取该工作目录关联的所有虚机名称(对应目录名).
去VB存储目录下, 找到对应的虚机存储介质目录. 先迁移 vbox , 再更新同步vagrant id文件元数据, 使得vagrant和vbox关联起来.

脚本位置: github.com/Nisus-Liu/m… 欢迎大家使用和反馈! 参考:www.yuque.com/docs/share/… 《Vagrant 和 VirtualBox , 迁移》