1.       首页附注

 

我在本文中使用主机名为server1.example.comIP地址为192.168.0.100的机器作为KVM主机。

由于我们将以根用户权限(root privilege)运行本文介绍的所有步骤,所以可以用字符串sudo为本教程中的所有命令加上前缀,或者只需输入下面这个命令,立即成为根用户。

 

sudo su

 

 

2. 安装KVMvmbuilder

首先检查你的处理器是否支持硬件虚拟化;如果支持,下面这个命令

 

egrep '(vmx|svm)' --color=always /proc/cpuinfo

 

应该会显示这样的内容:

root@server1:~# egrep '(vmx|svm)' --color=always /proc/cpuinfo

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush

mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl extd_apicid

pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dnowprefetch lbrv

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush

mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl extd_apicid

pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dnowprefetch lbrv

root@server1:~#

要是什么都没显示,那么你的处理器不支持硬件虚拟化,你必须在此停住。

想安装KVMvmbuilder(创建基于Ubuntu的虚拟机的一个脚本),我们运行:

 

apt-get install ubuntu-virt-server python-vm-builder kvm-ipxe

 

然后运行该命令,确保它准备好运行KVM:
$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

要是缺漏了什么,它会告诉你KVM加速无法使用。在采用根权限的情况下运行,获得让它正常运行的暗示信息(hint),就像这样:

$ sudo kvm-ok
[sudo] password for carla: 
INFO: /dev/kvm does not exist(/dev/kvm不存在)
HINT: sudo modprobe kvm_intel
INFO: Your CPU supports KVM extensions(你的处理器支持KVM扩展)
INFO: KVM (vmx) is disabled by your BIOS(KVM [vmx]被你的BIOS禁用)
HINT: Enter your BIOS setup and enable Virtualization Technology (VT), 
(进入你的BIOS设置界面,启用虚拟化技术[VT],)
and then hard poweroff/poweron your system
(然后对你的系统执行硬关机/开机操作)
KVM acceleration can NOT be used(KVM加速无法使用)

之后,我们必须将用户作为目前登录的用户(根用户)添加到群组libvirtd

 

adduser `id -un` libvirtd

adduser `id -un` kvm

 

你需要退出,重新登录,那样新的群组成员资格才生效。

想检查KVM是否已成功安装,运行

 

virsh -c qemu:///system list

 

它显示的内容应该像这样:

root@server1:~# virsh -c qemu:///system list

 Id Name                 State

----------------------------------

 

root@server1:~#

如果它显示的而是错误,那么准是出了什么问题。

接下来,我们需要在服务器上建立网桥,以便可以从其他主机访问我们的虚拟机,好像虚拟机是网络中的物理系统。

为此,我们安装了程序包bridge-utils......

 

apt-get install bridge-utils

 

并配置网桥。打开/etc/network/interfaces

 

vi /etc/network/interfaces

 

在改动之前,我的文件像下面这样子:

该文件描述了系统上可用的网络接口,

以及如何激活这些网络接口。欲知详情,请参阅接口(5)。

回送网络接口

auto lo

iface lo inet loopback

主网络接口

auto eth0

iface eth0 inet static

        address 192.168.0.100

        netmask 255.255.255.0

        network 192.168.0.0

        broadcast 192.168.0.255

        gateway 192.168.0.1

        dns-nameservers 8.8.8.8 8.8.4.4

我对文件作了更改,以便像下面这样子:

该文件描述了系统上可用的网络接口,

以及如何激活这些网络接口。欲知详情,请参阅接口(5)。

回送网络接口

auto lo

iface lo inet loopback

主网络接口

auto eth0

iface eth0 inet manual

auto br0

iface br0 inet static

        address 192.168.0.100

        network 192.168.0.0

        netmask 255.255.255.0

        broadcast 192.168.0.255

        gateway 192.168.0.1

        dns-nameservers 8.8.8.8 8.8.4.4

        bridge_ports eth0

        bridge_fd 9

        bridge_hello 2

        bridge_maxage 12

        bridge_stp off

 

(确保你的网络使用了正确的设置!)

重新启动网络……

 

/etc/init.d/networking restart

 

然后运行

 

ifconfig

 

现在它应该显示了网桥(br0):

root@server1:~# ifconfig

br0       Link encap:Ethernet  HWaddr 00:1e:90:f3:f0:02

          inet addr:192.168.0.100  Bcast:192.168.0.255  Mask:255.255.255.0

          inet6 addr: fe80::21e:90ff:fef3:f002/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:29 errors:0 dropped:0 overruns:0 frame:0

          TX packets:29 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:1934 (1.9 KB)  TX bytes:2844 (2.8 KB)

eth0      Link encap:Ethernet  HWaddr 00:1e:90:f3:f0:02

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:44613 errors:0 dropped:0 overruns:0 frame:0

          TX packets:23445 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:63663064 (63.6 MB)  TX bytes:1792940 (1.7 MB)

          Interrupt:41 Base address:0xa000

lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:16436  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

virbr0    Link encap:Ethernet  HWaddr 2a:4a:49:13:de:8f

          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@server1:~#

在我们开始运行第一个虚拟机之前,建议重新启动系统:

 

reboot

 

如果你没有重启,可能会在/var/log/libvirt/qemu/目录的虚拟机日志中看到错误,比如/dev/kvm: Permission denied

 

3.创建基于镜像的虚拟机

 

现在我们可以创建第一个虚拟机:基于镜像的虚拟机(如果你预计该虚拟机会有大量的流量和频繁的读写操作,可以改而使用基于LVM的虚拟机,如下面第6节所示——基于镜像的虚拟机其硬盘输入/输出操作很频繁)。

我想在/var/lib/libvirt/images/目录中创建虚拟机(无法在/root目录中创建虚拟机,因为libvirt-qemu用户在该目录中没有读取权限)。

我们将为想要创建的每个虚拟机建立一个新的目录,比如/var/lib/libvirt/images/vm1/var/lib/libvirt/images/vm2/var/lib/libvirt/images/vm3等等,因为每个虚拟机都会有一个子目录,名为ubuntu-kvm;很显然,在/var/lib/libvirt/images/vm1中只有这样一个目录。比如说,如果你试图在/var/lib/libvirt/images/vm1创建第二个虚拟机,就会看到错误消息,表明ubuntu-kvm已经存在(除非你使用--dest=DESTDIR变量运行vmbuilder):

root@server1:/var/lib/libvirt/images/vm1# vmbuilder kvm ubuntu -c vm2.cfg

2009-05-07 16:32:44,185 INFO     Cleaning up

ubuntu-kvm already exists

root@server1:/var/lib/libvirt/images/vm1#

我们会使用vmbuilder工具来创建虚拟机。你可以在此(https://help.ubuntu.com/community/JeOSVMBuilder)进一步了解vmbuildervmbuilder使用模板来创建虚拟机——该模板位于/etc/vmbuilder/libvirt/目录中。我们先创建一个副本:

 

mkdir -p /var/lib/libvirt/images/vm1/mytemplates/libvirt

cp /etc/vmbuilder/libvirt/* /var/lib/libvirt/images/vm1/mytemplates/libvirt/

 

现在我们进入到虚拟机的分区。我们创建了一个文件,名为vmbuilder.partition……

 

vi /var/lib/libvirt/images/vm1/vmbuilder.partition

 

并定义所需的分区,如下所示:

root 8000

swap 4000

---

/var 20000

这定义了大小为800MB的根分区(/)、4000MB的交换分区以及20000MB/var分区。---这一行表示,下列分区(本例中的/var)在另外的磁盘镜像上(也就是说这将创建两个磁盘镜像,一个用于根分区和交换分区,另一个用于/var分区)。当然,你可以随意定义自己喜欢的任何分区(只要你还定义了根分区和交换分区);当然,它们可以在一个磁盘镜像中——这只是个例子。

我想在虚拟机中安装openssh-server。为了确保每个虚拟机都获得一个独特的OpenSSH密钥,我们创建虚拟机时无法安装openssh-server。因此,我们创建了名为boot.sh的脚本,虚拟机第一次启动时,就会执行该脚本。它会安装openssh-server(借助独特密钥);用户第一次登录后,它还会迫使用户更改密码。(我将让虚拟机使用默认的用户名administrator,默认密码是howtoforge):

 

vi /var/lib/libvirt/images/vm1/boot.sh

 

虚拟机第一次启动时,该脚本将运行。

它以根用户来运行。

到期终止用户帐户

passwd -e administrator

安装openssh-server

apt-get update

apt-get install -qqy --force-yes openssh-server

确保你把用户名administrator换成了默认登录名。

(你可以在这里进一步了解这方面:https://help.ubuntu.com/community/JeOSVMBuilder#First%20boot

(你还可以定义在此https://help.ubuntu.com/community/JeOSVMBuilder#First%20login描述的“首次登录”脚本)

现在看一下

 

vmbuilder kvm ubuntu --help

 

即可了解可用的选项。

想创建第一个虚拟机vm1,我们进入到虚拟机目录……

 

cd /var/lib/libvirt/images/vm1/

 

并运行vmbuilder,如下所示:

 

vmbuilder kvm ubuntu --suite=precise --flavour=virtual --arch=amd64 --mirror=http://de.archive.ubuntu.com/ubuntu -o --

libvirt=qemu:///system --ip=192.168.0.101 --gw=192.168.0.1 --part=vmbuilder.partition --templates=mytemplates --user=administrator --

name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --

firstboot=/var/lib/libvirt/images/vm1/boot.sh --mem=256 --hostname=vm1 --bridge=br0

 

--mirror=http://mirrors.163.com/ubuntu--------more fast

大多数选项不言自明。--part指定了有分区详细信息的文件,相对于我们的工作目录(这就是我们在运行vmbuilder之前为什么要进入到虚拟机目录),--templates指定了保存模板文件的目录(再次相对于我们的工作目录),--firstboot指定了首次启动脚本。--libvirt=qemu:///system告诉KVM把该虚拟机添加到可用虚拟机的列表。--addpkg让你可以指定创建虚拟机过程中想安装的Ubuntu程序包(上文解释了为什么不该把openssh-server添加到该列表中,而是应该使用首次启动脚本)。 --bridge建立了桥接网络;由于我们已在第2节建立了网桥br0,我们在此指定该网桥。

--mirror这一行,你可以使用--mirror来指定官方的Ubuntu库,比如http://de.archive.ubuntu.com/ubuntu。如果你略去--mirror,那么就会使用默认的Ubuntu库(http://archive.ubuntu.com/ubuntu)。

如果你用--ip参数选项符指定IP地址,要确保你还使用--gw参数选项符指定了正确的网关IP(不然,vmbuilder会假设它是网络中的第一个有效地址,实则不然)。网关IP通常与你在/etc/network/interfaces中所用的一样(参阅第2节)。

创建过程可能要花几分钟。

之后,你能在/etc/libvirt/qemu/ (=> /etc/libvirt/qemu/vm1.xml)中找到该虚拟机的XML配置文件:

 

ls -l /etc/libvirt/qemu/

 

root@server1:/var/lib/libvirt/images/vm1# ls -l /etc/libvirt/qemu/

total 8

drwxr-xr-x 3 root root 4096 May 21 13:00 networks

-rw------- 1 root root 2082 May 21 13:15 vm1.xml

root@server1:/var/lib/libvirt/images/vm1#

磁盘镜像位于我们虚拟机目录的ubuntu-kvm/子目录中:

 

ls -l /var/lib/libvirt/images/vm1/ubuntu-kvm/

 

root@server1:/var/lib/libvirt/images/vm1# ls -l /var/lib/libvirt/images/vm1/ubuntu-kvm/

total 604312

-rw-r--r-- 1 root root 324337664 May 21 13:14 tmpE4IiRv.qcow2

-rw-r--r-- 1 root root 294715392 May 21 13:15 tmpxvSVOT.qcow2

root@server1:/var/lib/libvirt/images/vm1#

4. 创建第二个虚拟机

 

如果你想创建第二个虚拟机(vm2),这里简要概述一下命令:

mkdir -p /var/lib/libvirt/images/vm2/mytemplates/libvirt

cp /etc/vmbuilder/libvirt/* /var/lib/libvirt/images/vm2/mytemplates/libvirt/

vi /var/lib/libvirt/images/vm2/vmbuilder.partition

vi /var/lib/libvirt/images/vm2/boot.sh

cd /var/lib/libvirt/images/vm2/

vmbuilder kvm ubuntu --suite=precise --flavour=virtual --arch=amd64 --mirror=http://de.archive.ubuntu.com/ubuntu -o --

libvirt=qemu:///system --ip=192.168.0.102 --gw=192.168.0.1 --part=vmbuilder.partition --templates=mytemplates --user=administrator --

name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --

firstboot=/var/lib/libvirt/images/vm2/boot.sh --mem=256 --hostname=vm2 --bridge=br0

请注意:如果你把-d DESTDIR变量传递给vmbuilder命令,就没必要为虚拟机创建新目录(/var/lib/libvirt/images/vm2)——它让你可以在你已经创建了另一个虚拟机的目录中创建虚拟机。这种情况下,你没必要创建新的vmbuilder.partitionboot.sh文件,也没必要改动模板,而是只要使用现有文件:

cd /var/lib/libvirt/images/vm1/

vmbuilder kvm ubuntu --suite=precise --flavour=virtual --arch=amd64 --mirror=http://de.archive.ubuntu.com/ubuntu -o --

libvirt=qemu:///system --ip=192.168.0.102 --gw=192.168.0.1 --part=vmbuilder.partition --templates=mytemplates --user=administrator --

name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --

firstboot=/var/lib/libvirt/images/vm1/boot.sh --mem=256 --hostname=vm2 --bridge=br0 -d vm2-kvm

 

5. 管理虚拟机

 

可以通过virsh(虚拟外壳)来管理虚拟机。想连接到虚拟外壳,运行:

 

virsh --connect qemu:///system

 

虚拟外壳的样子如下:

root@server1:~# virsh --connect qemu:///system

Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands

       'quit' to quit

virsh #

现在,你可以在虚拟外壳上输入命令来管理虚拟机。运行

 

Help

 

即可获得可用命令列表:

virsh # help

Grouped commands:

 

 域管理命令(帮助关键字'domain')::

attach-device                  XML文件附加设备

    attach-disk                    附加磁盘设备

    attach-interface               附加网络接口

    autostart                    自动启动域

    blkdeviotune                 设定或查询块设备输入/输出调整参数

    blkiotune                   获取或设定块输入/输出参数

    blockpull                   从支持镜像填充磁盘

    blockjob                   管理活动的块操作

    blockresize                 为域的块设备调整大小

    console                    连接到客户机控制台

    cpu-baseline                计算基准处理器

    cpu-compare               比较主机处理器与XML文件描述的处理器

    create                    XML文件创建域

    define                    XML文件定义(但不启动)域

destroy                   销毁(停止)域

detach-device              XML文件分离设备

    detach-disk                分离磁盘设备

    detach-interface            分享网络接口

    domid                    把域名或UUID转换成域编号

    domif-setlink              设定虚拟接口的链路状态

    domjobabort               放弃活动的域任务

    domjobinfo                域任务信息

domname                  把域编号或UUID转换成域名

domuuid                   把域名或编号转换成域UUID

domxml-from-native         把原生配置转换成域XML

    domxml-to-native            把域XML转换成原生配置

    dump                     把域的核心转储到文件中,以便分析

    dumpxml                   XML中的域信息

edit                       为域编辑XML配置

inject-nmi                   NMI注入到客户机

send-key                    将键码发送到客户机

managedsave                域状态的托管保存

managedsave-remove          清除域的托管保存

maxvcpus                   连接虚拟处理器最大值

    memtune                    获取或设定内存参数

    migrate                     把域迁移到另一个主机

    migrate-setmaxdowntime       设定可以容忍的最长停机时间

    migrate-setspeed              设定最大迁移带宽

migrate-getspeed             获取最大迁移带宽

reboot                       重启域

    reset                        重置域

    restore                       从文件中的保存状态恢复域

    resume                      恢复运行域

    save                         将域状态保存到文件

    save-image-define              为域的保存状态文件重新定义XML

save-image-dumpxml            XML中的保存状态域信息

save-image-edit                为域的保存状态文件编辑XML

schedinfo                     显示/设定调度器参数

    screenshot                     获取当前域控制台的屏幕截图,并保存到文件中

    setmaxmem                     改变最大内存限额

    setmem                         改变内存分配

    setvcpus                       改变虚拟处理器的数量

    shutdown                      从容地关闭域

    start                          启动(之前定义的)非活动域

    suspend                       暂停域

    ttyconsole                     tty控制台

    undefine                       取消定义域

    update-device                  XML文件更新设备

    vcpucount                      域虚拟处理器数量

    vcpuinfo                       详细的域虚拟处理器信息

    vcpupin                        控制或查询域虚拟处理器亲近性

    version                        显示版本

vncdisplay                     vnc显示

 

 域监控命令(帮助关键字'monitor'):

domblkinfo                     域块设备大小信息

domblklist                     列出所有域块

    domblkstat                     获取一个域的设备块统计信息

    domcontrol                     域控制台界面状态

    domif-getlink                  获取虚拟接口的链路状态

    domifstat                      获取域的网络接口统计信息

    dominfo                        域信息

    dommemstat                     获取域的内存统计信息

    domstate                       域状态

list                          列出域

 

 主机和虚拟机管理程序命令(帮助关键字'host'):

    capabilities                   功能

    connect                        (重新)连接至虚拟机管理程序

    freecell                       NUMA闲置内存

    hostname                       打印虚拟机管理程序主机名

    nodecpustats                   打印节点的处理器统计信息

    nodeinfo                       节点信息

    nodememstats                   打印节点的内存统计信息.

    nodesuspend                    将主机节点暂停一段特定的时间

    qemu-attach                    QEMU附加

qemu-monitor-command           QEMU监测器命令

sysinfo                        打印虚拟机管理程序的系统信息

uri                           打印虚拟机管理程序canonical URI

 

 接口命令(帮助关键字'interface'):

    iface-begin                    拍摄当前接口设置的快照,以后可以提交(iface-commit)或恢复(iface-rollback)

    iface-bridge                   建立网桥设备,并与现有网络设备相连

    iface-commit                   实行自iface-begin和闲置恢复点以来所作的变化

    iface-define                   XML文件定义(但不启动)物理主机接口

    iface-destroy                  销毁物理主机接口(禁用它/ "if-down"

    iface-dumpxml                  XML中的接口信息

    iface-edit                     为物理主机接口编辑XML配置

    iface-list                     列出物理主机接口

    iface-mac                     把接口名称转换成接口MAC地址

iface-name                    把接口MAC地址转换成接口名称

iface-rollback                 恢复到通过iface-begin创建的之前保存的配置

    iface-start                    启动物理主机接口(启用它/ "if-up"

    iface-unbridge                 分离从属设备后,取消定义网桥设备

iface-undefine                 取消定义物理主机接口(将它从配置中移除)

 

 网络过滤器命令(帮助关键字'filter'):

    nwfilter-define                XML文件定义或更新网络过滤器

    nwfilter-dumpxml               XML中的网络过滤器信息

    nwfilter-edit                  为网络过滤器编辑XML配置

    nwfilter-list                  列出网络过滤器

nwfilter-undefine              取消定义网络过滤器

 

 网络命令(帮助关键字'network'):

    net-autostart                 自动启动网络

    net-create                     XML文件创建网络

    net-define                     XML文件定义(但不启动)网络

    net-destroy                    销毁(停止)网络

    net-dumpxml                    XML中的网络信息

    net-edit                       为网络编辑XML配置

    net-info                       网络信息

    net-list                       列出网络

    net-name                       把网络UUID转换成网络名称

    net-start                     启动(之前定义)的非活动网络

    net-undefine                   取消定义非活动网络

net-uuid                       把网络名称转换成网络UUID

 

 节点设备命令(帮助关键字'nodedev'):

    nodedev-create                 在节点上创建由XML文件定义的设备

    nodedev-destroy                销毁(停止)节点上的设备

    nodedev-dettach                将节点设备与设备驱动程序分离

    nodedev-dumpxml              XML中的节点设备详细信息

nodedev-list                   列举该主机上的设备

nodedev-reattach               重新将节点设备连接至设备驱动程序

nodedev-reset                  重置节点设备

 

 密钥(帮助关键字'secret'):

    secret-define                  XML文件定义或改动密钥

    secret-dumpxml                 XML中的密钥属性

    secret-get-value               输出密钥值

    secret-list                    列出密钥

secret-set-value               设定密钥值

secret-undefine                取消定义密钥

 

 快照命令(帮助关键字'snapshot'):

    snapshot-create                XML创建快照

    snapshot-create-as             从一组变更创建快照

    snapshot-current               获取或设定当前快照

    snapshot-delete                删除域的快照

snapshot-dumpxml               转储域快照的XML

snapshot-edit                  编辑快照的XML

    snapshot-list                  列出域的快照

    snapshot-parent                获取快照母版的名称

snapshot-revert                使域回复到快照

 

 存储池命令(帮助关键字'pool'):

    find-storage-pool-sources-as   查找潜在的存储池来源

    find-storage-pool-sources      发现潜在的存储池来源

    pool-autostart                 自动启动存储池

    pool-build                    建立存储池

    pool-create-as                 从一组变量创建存储池

    pool-create                    XML文件创建存储池

    pool-define-as                 从一组变量定义存储池

    pool-define                    XML文件定义(但不启动)存储池

pool-delete                    删除存储池

pool-destroy                   销毁(停止)存储池

    pool-dumpxml                  XML中的存储池信息

    pool-edit                      为存储池编辑XML配置

    pool-info                      存储池信息

    pool-list                      列出存储池

    pool-name                     把存储池UUID转换成存储池名称

    pool-refresh                   刷新存储池

    pool-start                     启动(之前定义)的非活动存储池

    pool-undefine                  取消定义非活动存储池

pool-uuid                     把存储池名称转换成存储池UUID

 

存储卷命令(帮助关键字'volume'):

    vol-clone                     克隆存储卷

    vol-create-as                  从一组变量创建存储卷

    vol-create                     XML文件创建存储卷

    vol-create-from                创建存储卷,使用另一个存储卷作为输入

vol-delete                     删除存储卷

vol-download                   下载存储卷到文件

    vol-dumpxml                   XML中的存储卷信息

    vol-info                       存储卷信息

    vol-key                       返回某个存储卷名称或路径的存储卷密钥

    vol-list                      列出存储卷

    vol-name                       返回某个存储卷密钥或路径的存储卷名称

    vol-path                      返回某个存储卷名称或密钥的存储卷路径

    vol-pool                      返回某个存储卷密钥或路径的存储池

    vol-upload                     将文件上传到存储池

vol-wipe                       清除存储卷

 

 虚拟外壳命令(帮助关键字virsh'):

    cd                             变更当前目录

    echo                          回显变量

    exit                           退出这个交互式终端

    help                           打印帮助

    pwd                           打印当前目录

quit                           退出这个交互式终端

 

virsh #

 

list

 

显示所有运行中虚拟机:

 

list --all

 

显示所有虚拟机,包括运行中虚拟机和非活动虚拟机:

virsh # list --all

 Id Name                 State

----------------------------------

  - vm1                  shut off

  - vm2                  shut off

virsh #

在你第一次启动新虚拟机之前,必须从XML文件来定义(该文件位于/etc/libvirt/qemu/目录):

 

define /etc/libvirt/qemu/vm1.xml

 

请注意:只要你改动/etc/libvirt/qemu/中的虚拟机XML文件,就必须再次运行define命令!

现在你可以启动虚拟机:

 

start vm1

 

片刻过后,你应该可以使用PuTTYSSH客户程序,连接到虚拟机;以默认的用户名和密码登录。第一次登录后,你会看到要求更改密码的提示。

 

list

 

现在应该显示虚拟机是运行中:

virsh # list

 Id Name                 State

----------------------------------

  1 vm1                  running

virsh #

想停止虚拟机,运行

 

shutdown vm1

 

想立即停止虚拟机(也就是拔掉电源),运行

 

destroy vm1

 

暂停虚拟机:

 

suspend vm1

 

恢复运行虚拟机:

 

resume vm1

 

上面这些是最重要的命令。

输入

 

Quit

 

即可退出虚拟外壳。

6. 创建基于LVM的虚拟机

 

基于LVM的虚拟机与基于镜像的虚拟机相比有一些优点。它们的硬盘输入/输出不大频繁,而且更容易备份(使用LVM快照)。

想使用基于LVM的虚拟机,你就需要一个卷组,它要有未分配给任何逻辑卷的一些闲置空间。在本例中,我使用了大小约为465GB的卷组/dev/vg0……

 

vgdisplay

 

root@server1:~# vgdisplay

  --- Volume group ---

  VG Name               vg0

  System ID

  Format                lvm2

  Metadata Areas        1

  Metadata Sequence No  3

  VG Access             read/write

  VG Status             resizable

  MAX LV                0

  Cur LV                2

  Open LV               2

  Max PV                0

  Cur PV                1

  Act PV                1

  VG Size               465.29 GiB

  PE Size               4.00 MiB

  Total PE              119115

  Alloc PE / Size       24079 / 94.06 GiB

  Free  PE / Size       95036 / 371.23 GiB

  VG UUID               PRenhH-0MvN-wXCL-nl4i-IfsQ-J6fc-2raYLD

root@server1:~#

该卷组包含大小约为100GB的逻辑卷/dev/vg0/root和大小约为1GB的逻辑卷/dev/vg0/swap_1,其余空间未分配,可供虚拟机使用:

 

lvdisplay

 

root@server1:~# lvdisplay

  --- Logical volume ---

  LV Name                /dev/vg0/root

  VG Name                vg0

  LV UUID                dwnORf-yG3U-x1ZC-Bet1-TOoc-q1Dd-KZnbtw

  LV Write Access        read/write

  LV Status              available

  # open                 1

  LV Size                93.13 GiB

  Current LE             23841

  Segments               1

  Allocation             inherit

  Read ahead sectors     auto

  - currently set to     256

  Block device           252:0

  --- Logical volume ---

  LV Name                /dev/vg0/swap_1

  VG Name                vg0

  LV UUID                ZdPKO6-sZrr-tIRb-PPcl-aWBj-QAUU-fnYUuP

  LV Write Access        read/write

  LV Status              available

  # open                 2

  LV Size                952.00 MiB

  Current LE             238

  Segments               1

  Allocation             inherit

  Read ahead sectors     auto

  - currently set to     256

  Block device           252:1

root@server1:~#

现在我将创建虚拟机vm5,作为基于LVM的虚拟机。我们可以再度使用vmbuilder命令。vmbuilder知道--raw选项,该选项允许将虚拟机写入到块设备(如/dev/vg0/vm5)——我试用了该选项;不过它没有返回错误,我也启动不了虚拟机(start vm5也没有显示任何错误,但是我根本无法访问该虚拟机。)因此,我将先创建vm5,作为基于镜像的虚拟机,然后转换成基于LVM的虚拟机。

 

mkdir -p /var/lib/libvirt/images/vm5/mytemplates/libvirt

cp /etc/vmbuilder/libvirt/* /var/lib/libvirt/images/vm5/mytemplates/libvirt/

 

确保你在仅仅一个镜像文件中创建所有分区,所以在vmbuilder.partition文件中不要使用---

 

vi /var/lib/libvirt/images/vm5/vmbuilder.partition

 

root 8000

swap 2000

/var 10000

 

vi /var/lib/libvirt/images/vm5/boot.sh

 

虚拟机第一次启动时,该脚本将运行。

它以根用户来运行。

到期终止用户帐户

passwd -e administrator

安装openssh-server

apt-get update

apt-get install -qqy --force-yes openssh-server

 

cd /var/lib/libvirt/images/vm5/

vmbuilder kvm ubuntu --suite=precise --flavour=virtual --arch=amd64 --mirror=http://de.archive.ubuntu.com/ubuntu -o --

libvirt=qemu:///system --ip=192.168.0.105 --gw=192.168.0.1 --part=vmbuilder.partition --templates=mytemplates --user=administrator --

name=Administrator --pass=howtoforge --addpkg=vim-nox --addpkg=unattended-upgrades --addpkg=acpid --

firstboot=/var/lib/libvirt/images/vm5/boot.sh --mem=256 --hostname=vm5 --bridge=br0

 

你可以从vmbuilder.partition文件看到,虚拟机将使用最多20GB的空间,于是我们现在创建一个大小为20GB的逻辑卷,名为/dev/vg0/vm5

 

lvcreate -L20G -n vm5 vg0

 

别在新的逻辑卷中创建文件系统!

我们将使用qemu-img命令,把镜像转换成基于LVM的虚拟机。

现在我们进入到虚拟机的ubuntu-kvm/目录……

 

cd /var/lib/libvirt/images/vm5/ubuntu-kvm/

 

即可发现我们的镜像是如何命名的:

 

ls -l

 

root@server1:/var/lib/libvirt/images/vm5/ubuntu-kvm# ls -l

total 592140

-rw-r--r-- 1 root root 606470144 May 21 14:06 tmpesHsUI.qcow2

root@server1:/var/lib/libvirt/images/vm5/ubuntu-kvm#

由于我们已知道了镜像的名称(tmpN27tbO.qcow2),可按如下方式来转换它:

 

qemu-img convert tmpesHsUI.qcow2 -O raw /dev/vg0/vm5

 

之后,你可以删除磁盘镜像:

 

rm -f tmpesHsUI.qcow2

 

 

现在,我们必须改动虚拟机的配置……

 

virsh edit vm5

 

并改变下列部分……

[...]

   

     

     

     

     

 

   

[...]

以便看起来像下面这样:

[...]

   

     

     

     

     

 

   

[...]

现在,你可以使用virsh来管理虚拟机:

 

virsh --connect qemu:///system

 

由于我们已改动了虚拟机的XML文件,必须先运行define命令……

 

define /etc/libvirt/qemu/vm5.xml

 

然后启动虚拟机:

 

start vm5

 

 

7. 相关链接

KVMUbuntu社区说明文档):https://help.ubuntu.com/community/KVM

vmbuilderhttps://help.ubuntu.com/community/JeOSVMBuilder

JeOSvmbuilderhttp://doc.ubuntu.com/ubuntu/serverguide/C/jeos-and-vmbuilder.html

Ubuntuhttp://www.ubuntu.com/ 

 http://virtual.51cto.com/art/201206/341911_3.htm