• [译] libvirt 虚机的生命周期 (Libvirt Virtual Machine Lifecycle)


     
    这篇文章描述虚机生命周期的基本概念。其目的在于在一篇文章中提供完整的关于虚机创建、运行、停止、迁移和删除的基础知识。

    1. 概念

    先补充一下 Domain(域)、Virutal Machine(虚机)和 Guest OS (客户机操作系统)三个术语的区别。这三个概念经常被相互使用,其实它们之间还是有些区别。

    Oracel 的解释 (资料来源):

    • Domain:资源的一个可配置集合,包括内存,虚拟CPU,网络设备和磁盘设备。在 Domain 中运行(多个)虚拟机。一个 Domain 被分配虚拟资源,可以独立地被启动、停止和重启。
    • Guest OS:运行在 domain 中的虚拟操作系统。一个 Guest OS 可以是部分虚拟化或者硬件虚拟化的。一个 Hypervisor上可以运行多个 Guest OS。
    • VM:Guest OS + 它相关的应用软件。

    libvirt 的解释 (资料来源):

    一个 libvirt Domain 是一个运行在虚拟机器上的操作系统的实例,它可以指一个运行着的虚拟机,或者用于启动虚拟机的配置。

    Xen 的解释(资料来源):

    对 Xen 来说,一个 domain 就是指一个虚拟机,其 domain 概念如下:

    好吧,这些说法还是有细微差别,下文中的 Domain 就当是虚拟机吧。其它术语:

    术语
    解释
    Domain 域
    一个运行在被虚拟化的机器上的,由 hypervisor 提供的操作系统实例
    Hypervisor 虚机管理程序
    一个虚拟化一个物理服务器为多个虚拟机的软件层。
    Node 节点
    一个物理服务器。它可能有多种类型,比如存储节点,集群节点和数据库节点等。
    Storage Pool 存储池
    一个存储介质的集合,比如物理硬盘驱动器的集合。一个存储池被细分为卷,卷会被分配给一个或者多个域。
    Volume 卷
    一个从存储池中分配出来的存储空间。一个卷可能会分配给一个或者多个域使用,并且往往被用作域内的虚拟硬盘驱动器。

    1.1 XML 描述

    Guest domain 是用 XML 配置来描述的。libvirt 使用 XML 文件格式来保存它的所有对象的配置,包括 domain,网络、存储和其它元素。这样,用户就可以使用任何他们喜欢使用的编辑器来编辑这些XML配置了。

    比如,domain 中的设备使用 XML 元素 来表示其被分配的属性和子元素的一个示例如下:

    <domain type='qemu'>
       <name>demo</name>
       ...
       <devices>
          ...
          <disk type='file' device='disk'> ... </disk>
          <disk type='file' device='cdrom'> ... </disk>
          <input type='mouse' bus='ps2'/>
          ...
       </devices>
    </domain>
    libvirt 使用 XPath 技术来从XML 文档中选择node。 

    1.2. 过渡性 Guest Domain VS 持久性 Guest Domain

    Libivrt 区分两种不同类型的 domain:短暂性的(transient )和持久性的(persistent)。

    • 短暂性 domain 只在 domain 被关机( shutdown) 或者所在的主机(host)被重启(restart)之前存在。
    • 持久性 domain 会一直存在,直到被删除。
     
    无论它是什么类型,当一个 domain 被创建后,它的状态可以被保存进一个文件。之后,只要该文件存在,这个 domain 的状态就可以从无限次从该文件中被恢复( restored)。因此,即使是一个短暂性的domain,它也可以被反复地恢复。
     
    创建短暂性的 domain 与创建持久性 domain 有一点不同。对持久性domain来说,它必须在其启动前定义(define)好。而短暂性虚机可以被一次性被创建和启动。操作两种类型的domain的命令也有些区别。当性domain被创建和关闭时,其需要的所有部件(比如存储、网络、设备等)都必须提前被准备好。

    1.3 Domain 状态

     一个 Guest domain 可能处于的状态:
    • Undified (未定义的):这是起始状态。这时 libvirt 不会知道 domain 的任何信息,因为这时候 domain尚未被定义或者创建。
    • Defined (定义了的)/ Stopped (停止的):domain 已经被定义,但是不在运行(running)。只有持久性 domains 才能处于该状态。当一个短暂性 domain 被停止或者关机时,它就不存在了。
    • Running (运行中的):domain 被创建而且启动了,无论是短暂性domain还是持久性domain。任何处于该状态的 domain 都已经在主机的 hypervisor 中被执行了。
    • Paused (中止了的):Hypervisor 上对该 domain 的运行被挂起(suspended)了。它的状态被临时保存(比如到内存中),直到它被继续(resumed)。domain 本身不知道它处于是否被中止状态。
    • Saved (保存了的):类似中止(Paused) 状态,除了domain 的状态被保存在持久性存储比如硬盘上。处于该状态上的 domain 可以被恢复 (restored)。
     
    下图描述了 domain 的状态机。方框表示状态,箭头表示使得状态变更的命令。
     
    Image:Vm lifecycle graph.png
     从改图中可以看出,对持久性 domain,shtudown 命令可以将其从运行(running) 状态变为定义(defined)状态;对短暂性 domain 而言,它会从运行(running) 状态变为变为未定义(undefined) 状态。 

    1.4 快照

    一个快照是虚机的操作系统和它的所有应用(applications )在某个时刻的视图。在虚拟化领域,提供可以被恢复的虚机快照是个非常基本的功能。快照允许用户保存虚机在某个时刻的状态,然后在将来某个时候回滚到该状态。基本的用例包括,创建快照、安装新的应用、更新或者升级,然后回滚到之前的某个时间点。显然,在快照生成之后发生的任何操作都不会包含在快照中。一个快照不会持续更新。它只表示虚机的某个时间上的状态。 

    1.5 迁移 

    一个运行中的 domain 或者虚机可以被迁移到另一个主机上,只要虚机的存储是在主机之间共享的,并且目标主机的CPU能够支持虚机的CPU模式。根据类型和应用,虚机迁移可以不导致虚机上运行的服务的中断。 

    Libvirt 支持多种不同的迁移模式:
    • Standard (标准模式):该模式下,一个 domain 的资源在从源主机迁移到目标主机时,它会处于被挂起(suspended)状态。迁移结束后,虚机在新的主机上继续运行。迁移所花的时间和 domain 的内存大小直接相关。
    • Live vs non-live(实时 VS 非实时模式):当使用实时迁移模式时,domain 不会被中止,它的所有服务都继续运行。一开始,目的主机上的 domain 或者虚机会处于停止状态,而且在domain的状态在网络传输的过程中,domain 在目的主机上实际上是不可见的。实时迁移和它上面所运行的应用的类型有直接关系的。当实时迁移一个 domain 时,它已经被分配的内存会被发送到目的主机,与此同时,其内存的任何改变都会被监视(watched)然后也会被发到目的主机。原主机上的 domain 会一直保持它的状态,直到两个节点上的 domain 的内存达到完全达到一致了。这时,目的主机上的 domain 变为 active 状态,原主机上的 domain 变为 passive 或者不可见状态。
    • Peer-to-peer (对等模式):该模式下,当原主机和目的主机能够直接通信。
    • Tunnelled (隧道模式) :该模式下,在原主机和目的主机之间会建立一个隧道 (tunnel),比如 SSH 隧道。两个主机之间的所有通信都会经过该隧道。
    • Direct (直接模式):该模式下,libivrt 使用 hypervisor 来发起迁移,迁移过程完全被 hypervisor 控制。这种模式下,源主机和目的主机的 hypervisor 往往是可以直接交互的(比如,原主机和目的主机上的 Xen 能够直接交互,而不需要libvirt 的干预)

    迁移要求:

    • 使用路径和位置相同的共享存储
    • 两个物理主机上的 hypervisor 的版本完全相同
    • 相同的网络配置
    • 目的主机上有相同的或者更好的CPU。CPU必须来自同一生产厂家,目的主机上的 CPU flags 必须是原主机上的CPU flags 的超集。
    这里有个成功迁移所需要的 checklist: here

    1.6 删除 domain 时的数据安全性

     一些应用可能会存储敏感数据,这些数据必须被安全地处理。在任何文件系统中都一样,当一个虚机从一个系统中被删除的时候,只是文件系统的指针被删除。存储介质上的数据块任然存在,只是它们在文件系统中被标识为空。当然,这取决于你的文件系统。我们希望,当一个应用处理这种敏感数据的时候,这些机器必须物理上被安全保护,而且网络防护也必须是被防护的。安全在任何时候都很重要。
     

    2. 任务 (Tasks)

    2.1 创建一个 domain  

    为了运行一个 domain,首先必须创建一个 domain。有很多方式可以创建一个 domain。
    (1)这篇文章描述了使用 Virtual Machine Manager GUI 来创建一个domain。
    (2)下面的代码使用 virt-install 命令来创建一个 domain:
    # virt-install 
                 --connect qemu:///system 
                 --virt-type kvm 
                 --name MyNewVM 
                 --ram 512 
                 --disk path=/var/lib/libvirt/images/MyNewVM.img,size=8 
                 --vnc 
                 --cdrom /var/lib/libvirt/images/Fedora-14-x86_64-Live-KDE.iso 
                 --network network=default,mac=52:54:00:9c:94:3b 
                 --os-variant fedora14

    该命令创建一个名为 'MyNewVM' 的 domain,它有 512M 内存和8G磁盘空间,使用KVM。你可以阅读该命令的手册。 

    (3)最后一种方式是创建 domain 和 卷 (volume)的 XML 定义,然后使用 virsh 的 vol-create 和 define 命令。

    卷 (volume)会被加入一个池(pool)中。默认的话,一个名为  "default" 的池会存在。这是一个目录类型的池,它的意思是所有的卷都以文件形式存在于一个目录中。详细信息,你可以读  this page 。

    一个卷的 XML定义例子(new_volume.xml):
    <volume>
     <name>sparse.img</name>
     <capacity unit="G">10</capacity>
    </volume>
    它定义了一个容量为 10G 的卷。使用如下命令来在 'default' 池中创建该卷:
    # virsh vol-create default new_volume.xml
    Domain 的 XML 定义的例子 (MyNewVM.xml) 如下:
    <domain type='kvm'>
      <name>MyNewVM</name>
      <currentMemory>524288</currentMemory>
      <memory>524288</memory>
      <uuid>30d18a08-d6d8-d5d4-f675-8c42c11d6c62</uuid>
      <os>
        <type arch='x86_64'>hvm</type>
        <boot dev='hd'/>
      </os>
      <features>
        <acpi/><apic/><pae/>
      </features>
      <clock offset="utc"/>
      <on_poweroff>destroy</on_poweroff>
      <on_reboot>restart</on_reboot>
      <on_crash>restart</on_crash>
      <vcpu>1</vcpu>
      <devices>
        <emulator>/usr/bin/qemu-kvm</emulator>
        <disk type='file' device='disk'>
          <driver name='qemu' type='raw'/>
          <source file='/var/lib/libvirt/images/MyNewVM.img'/>
          <target dev='vda' bus='virtio'/>
        </disk>
        <disk type='block' device='cdrom'>
          <target dev='hdc' bus='ide'/>
          <readonly/>
        </disk>
        <interface type='network'>
          <source network='default'/>
          <mac address='52:54:00:9c:94:3b'/>
          <model type='virtio'/>
        </interface>
        <input type='tablet' bus='usb'/>
        <graphics type='vnc' port='-1'/>
        <console type='pty'/>
        <sound model='ac97'/>
        <video>
          <model type='cirrus'/>
        </video>
      </devices>
    </domain>

    定义一个持久性的domain:

    # virsh define MyNewVM.xml

    Domain 的 XML 格式有很多的可选元素你可能觉得有用。因此,可以阅读 this page ,它包含完整的参考。 

    2.2 编辑一个 domain

     可以使用任何编辑器来编辑一个 domain。你需要设置 $VISUAL or $EDITOR 环境变量来指定编辑器,然后运行:
    # virsh edit <domain>

    如果这些变量都不存在,默认会使用 vi。当编辑器关闭的时候,libvirt 会自动检查其变化并应用这些改变。你也可以在 Virtual Machine Manager 编辑 domain。

    2.3 启动一个domain

     当一个 domain 被创建后,你可以启动它。你可以使用Virtual Machine Manager,或者运行 virsh start <domain> 命令,比如:
    # virsh start MyNewVM
    该命令可能从零启动(boot up)一个 domain 或者从之前保存的一个状态上恢复 domain。请阅读 virsh 的 managedsave 命令 。重要的是,如果它的任何部件比如 network 还没有起来的话,一个 domain 不会被启动起来。
     
    就像之前提到的那样,一个 transient domain 可以不需要提前定义(define)而直接被启动:
    # virsh create /path/to/MyNewVM.xml

    2.4 停止或者重启(reboot)domain

    停止一个运行中的 domain:

    # virsh shutdown <domain>

    重启一个持久性的 domain:

    # virsh reboot <domain>
    注意:重启一个暂时性的 domain 是不可能的,因为当它被关闭 (shutdown)后它就变成了 undefined 状态。

    粗野的关机(inelegant shutdown),等同于直接拔电源:

    # virsh destroy <domain>
     
    Stopping 是指中止一个运行着的domain 的过程。包括两个方法: shutdown 和 destroy。
    • shutdown 是个优雅(graceful)的停止过程,它会发一个信号给 domain 的操作系统,通知它立刻关机。domain 只有在 OS 成功关闭后才停止。该过程类似于在物理机器上运行 shutdown 命令。
    • destroy 是立刻中止 domain。该过程类似于拔掉物理机器的电源。 

    2.5 中止(Pause)domain

    使用 suspend 命令来中止一个domain:

    # virsh suspend <domain>

    当一个虚机处于挂起( suspended) 状态时,它会继续占用系统内存,但不会占用处理器资源。这时候也不会有磁盘和网络IO操作。 

    2.6 继续(unpause/resume)domain

    使用 resume 命令来继续一个domain:

    # virsh resume <domain> 
    • Suspend and resume 是指将一个domain 临时性的保存到内存中的过程。一段时间后,可以继续该 domain 到其原始的运行状态。Suspend 不保存 domain 的内存到持久性文件。 
    • Save 和 restore 是指将一个运行着的 domain 的状态保存到文件,以及从文件中恢复的过程。
    需要指出的是,save/restore 只会保存内存状态,不会保存存储状态。因此,当一个虚机被恢复时,其所使用的存储必须和虚机被保存时的存储状态一致。对基础性使用来说,这意味着虚机只能从被保存的文件中恢复一次。要运行多次恢复,应用需要在虚机被保存时生成一个快照,然后在恢复虚机时恢复快照。libvirt 将来的一个改进会在保存内存状态的同时进行自动化的快照。 

    2.7 对domain做快照

    使用 snapshot-create 命令来对 domain 做快照:

    # virsh snapshot-create <domain>

    2.8 列表domain 所有的快照

    使用 snapshot-list 命令来获取 domain 的所有快照列表:

    # virsh snapshot-list <domain>

    结果比如:

     Name                 Creation Time             State
    ---------------------------------------------------
     1295973577           2011-01-25 17:39:37 +0100 running
     1295978837           2011-01-25 19:07:17 +0100 running

    2.9 从快照恢复一个domain

    使用 snapshot-restore 命令来从一个快照恢复一个domain:

    # virsh snapshot-restore <domain> <snapshotname>

    2.10 删除domain 的一个快照

    使用 snapshot-delete 命令来删除一个快照:

    # virsh snapshot-delete <domain> <snapshotname>

    2.11 迁移 (Migration )

     Libvirt 支持 domain 的迁移。这意味着你可以把 domain 经过网络从一个主机迁移到另一个主机。迁移的两种主要模式:
    • 普通迁移(Plain migration):原主机开通一个与目的主机的 TCP 连接来发送迁移的数据。如果TCP 端口没有被指定,那么 libvirt 会自己在 49152-49215 区间内选择一个端口。因此你需要在目的主机的防火墙上开启该端口。
    • 隧道迁移(Tunneled migration):原主机创建一个与目的主机之间的连接隧道。它允许加密数据流。它不需要额外的防火墙操作,但是只在 qemu 0.12+ 和 libvirt 0.7.2 以后才支持。
    要进行成功的迁移,很多事情要做。比如,存储设置。被迁移的 domain 的所有卷都必须保存在同样的路径上。读  this page 来获取完整的check list。我们建议你使用 secure migration。当迁移前的检查都完成后,可以使用migrate 命令来进行迁移:
    # virsh migrate <domain> <remote host URI> --migrateuri tcp://<remote host>:<port>

    2.12 删除一个domain

    使用virsh 的 undefine 命令来删除一个 domain:

    # virsh undefine <domain>

    同样地,你也可以在 Virtual Machine Manager 中删除一个 domain。可以阅读这篇文章.

  • 相关阅读:
    windows中administrator 和 administrators两个账户的区别
    如何去掉打印网页时自带的网址以及页码等内容
    Oracle左连接,右连接
    oracle服务器本地能够登录但是局域网内其他机器不能访问的解决方法
    错误Name node is in safe mode的解决方法
    oracle数据库中对varchar类型求max的解决方法
    JBoss中配置数据源出现错误:“Failed to register driver for: com.mysql.jdbc.Driver”的解决方法
    学习junit和hamcrest的使用
    Ubuntu10.10如何给用户添加sudo权限
    ORACLE 9i卸载并重新安装
  • 原文地址:https://www.cnblogs.com/sammyliu/p/4486712.html
Copyright © 2020-2023  润新知