2.2 KVM基本操作

系列 - 虚拟化技术

1. KVM 软件包安装

安装 KVM 虚拟化软件包之前,需要确保服务器满足以下硬件条件:

  • CPU:64 位,且必须开启虚拟化功能(Intel 的 VT-x 或 AMD 的 AMD-V)。
  • 操作系统:64 位的 CentOS 或 RedHat,建议 6.0 以上版本。
  • 内存:至少 2GB(建议 4GB 以上以保证虚拟机运行流畅)。
  • 存储:至少 6GB 可用空间。

可以使用以下命令检查 CPU 是否开启了虚拟化功能:

bash

egrep 'vmx|svm' /proc/cpuinfo

如果输出结果中包含 vmx(Intel CPU)或 svm(AMD CPU),说明已经开启了 CPU 虚拟化功能。如果没有输出任何内容,则说明没有开启虚拟化支持。

提示
在物理服务器上需要在 BIOS 中开启虚拟化;如果是在虚拟机(例如 VMware)中进行实验,请确保在处理器的设置中勾选了“开启虚拟化(Intel VT-x/EPT 或 AMD-V/RVI)”选项。

确认硬件支持后,就可以安装 KVM 及其相关管理工具了:

bash

yum install -y qemu-kvm libvirt virt-install bridge-utils qemu-img

这里安装的几个核心软件包作用如下:

  • qemu-kvm:KVM 的基础包,包含 KVM 内核模块和 QEMU 模拟器。
  • libvirt:提供管理虚拟机和底层 Hypervisor 的 API 接口。
  • virt-install:用于通过命令行创建和克隆虚拟机的工具。
  • bridge-utils:Linux 网桥管理工具包,用于配置虚拟机的桥接网络。
  • virt-manager:KVM 的图形化管理工具(如果没有图形界面可不装)。
  • qemu-img:QEMU 的磁盘镜像管理工具,用来创建和管理虚拟磁盘。

安装完成后,需要启动虚拟化管理服务 libvirtd 并设置为开机自动启动:

bash

systemctl start libvirtd
systemctl enable libvirtd

接着,检查 KVM 相关的内核模块是否已经成功加载:

bash

lsmod | grep kvm

如果能看到类似 kvm_intelkvm 的输出,就说明 KVM 模块已经成功加载并准备就绪了。


2. 虚拟机创建

在 Linux 中,创建虚拟机常用的方式有三种:

  1. 使用 virt-manager 可视化工具创建。
  2. 使用 virt-install 命令行创建。
  3. 通过编辑 XML 配置文件创建。

如果你有图形化的桌面环境,可以通过 virt-manager 工具方便地创建虚拟机。

1)在命令行中输入 virt-manager 启动图形化管理工具。

图 2-35 virt-manager 图形化界面

2)点击菜单栏的“File(文件)”选项,选择“New Virtual Machine(新建虚拟机)”。此时会弹出向导对话框,让你选择操作系统的安装方式,主要有 4 种:

  • 通过 ISO 文件安装
  • 通过网络安装
  • 通过 PXE 安装
  • 通过现有磁盘镜像文件安装

图 2-36 操作系统安装方式

3)这里以“通过 ISO 文件安装”为例。点击“Forward(前进)”后,浏览并选择准备好的 ISO 镜像文件。通常系统会自动识别出操作系统类型和版本。

图 2-37 操作系统选择与配置

4)为虚拟机分配内存和 vcpu(虚拟 CPU 核心数)。可以根据实际需求进行调整。

图 2-38 虚拟机规格配置

5)为虚拟机创建虚拟磁盘,并设置其存储容量。

图 2-39 虚拟机存储配置

6)最后,给虚拟机设置一个名称,并确认虚拟机网络。点击“Finish(完成)”后,系统就会开始创建虚拟机,并进入操作系统的安装环节。

图 2-40 虚拟机配置确认

在没有图形界面的服务器上,virt-install 是最常用的创建工具。我们可以使用 ISO 镜像文件全新安装虚拟机,也可以直接使用已经装好系统的虚拟磁盘来导入创建(这样就不需要再经历漫长的系统安装过程)。

关闭防火墙和 SELinux

在进行后续实验前,为了避免安装过程中遇到网络或权限拦截问题,需要先关闭防火墙和 SELinux:

bash

systemctl stop firewalld.service
systemctl disable firewalld.service
setenforce 0
vi /etc/selinux/config
# 将 SELINUX 的值修改为 disabled
SELINUX=disabled

在使用命令行安装虚拟机时,我们通常会借助 VNC 客户端连接指定的端口号,才能看到虚拟机的安装界面并完成安装流程。

1)检查 VNC 端口是否被占用。VNC 默认从 5900 端口开始,我们这里暂时使用 5910 端口进行实验:

bash

netstat -tuln | grep 5910

如果命令执行后没有任何输出,说明 5910 端口没有被占用。如果有输出,请更换其他未使用的端口。

2)执行 virt-install 命令开始创建并安装虚拟机:

bash

virt-install --name vm001 \
--ram 1024 --vcpus 1 --network bridge=br0 \
--disk size=20 --cdrom /mnt/CentOS-7-x86_64-Minimal-2009.iso \
--boot hd,cdrom --graphics vnc,listen=0.0.0.0,port=5910

参数说明:

  • --name vm001:指定虚拟机的名字为 vm001。
  • --ram 1024:指定虚拟机的内存为 1024MB。
  • --vcpus 1:指定虚拟 CPU 的数量。
  • --network bridge=br0:指定虚拟机网络桥接到 br0 网桥上(如果 br0 不存在,需先通过 brctl addbr br0 命令创建)。
  • --disk size=20:指定虚拟磁盘容量为 20GB。
  • --cdrom /mnt/...:指定安装虚拟机使用的 ISO 操作系统镜像路径。
  • --boot hd,cdrom:指定启动顺序,这里设置为先从磁盘启动,再从光驱启动。
  • --graphics vnc...:指定使用 VNC 作为图形输出,并监听在 0.0.0.0 的 5910 端口。

命令执行完毕后,会在后台启动虚拟机。你需要在自己的电脑上使用 VNC 客户端工具连接 宿主机IP:5910 进行系统的安装。 同时,系统会自动在 /var/lib/libvirt/images 目录下生成一个名为 vm001.qcow2 的虚拟磁盘文件,并在 /etc/libvirt/qemu 目录下生成一个对应的 vm001.xml 配置文件。

如果我们已经有一个装好系统的虚拟磁盘文件(如刚才的 vm001.qcow2),就可以直接克隆出新的虚拟机。

1)复制原有的虚拟磁盘文件,作为新虚拟机的磁盘:

bash

cp /var/lib/libvirt/images/vm001.qcow2 /var/lib/libvirt/images/vm002.qcow2

2)修改新磁盘文件的用户和用户组,并赋予其合适的权限,以保证 KVM 可以正常读取:

bash

chown qemu:qemu /var/lib/libvirt/images/vm002.qcow2
chmod 600 /var/lib/libvirt/images/vm002.qcow2

3)执行命令导入并创建新虚拟机 vm002

bash

virt-install --name vm002 \
--ram 1024 --vcpus 1 --network bridge=br1 \
--disk /var/lib/libvirt/images/vm002.qcow2 \
--import

参数说明:

  • --disk ...:直接指向我们刚刚准备好的、带有操作系统的虚拟磁盘文件。
  • --import:表示跳过安装过程,直接从磁盘导入系统并启动。

每台虚拟机都有一个专属的 XML 配置文件(保存在 /etc/libvirt/qemu 目录中)。KVM 启动时就是根据这些配置文件来生成虚拟机的。我们可以通过修改现有的配置文件来快速创建新的虚拟机。

1)同样,先复制一份虚拟磁盘文件给新虚拟机使用,并设置好权限:

bash

cp /var/lib/libvirt/images/vm001.qcow2 /var/lib/libvirt/images/vm003.qcow2
chown qemu:qemu /var/lib/libvirt/images/vm003.qcow2
chmod 600 /var/lib/libvirt/images/vm003.qcow2

2)复制现有的 vm001.xml 配置文件,改名为 vm003.xml

bash

cp /etc/libvirt/qemu/vm001.xml /etc/libvirt/qemu/vm003.xml

3)编辑新的配置文件 vm003.xml,重点修改以下几个部分以防止冲突:

xml

<!-- 修改虚拟机名称 -->
<name>vm003</name>

<!-- 修改 UUID(直接删掉这一行或者修改字母数字均可) -->
<uuid>54e8426d-c72a-4979-b9fb-8d0e6448d1de</uuid>

<!-- 修改磁盘文件路径,使其指向新复制的 vm003.qcow2 -->
<disk type='file' device='disk'>
  <!-- 省略其他内容 -->
  <source file='/var/lib/libvirt/images/vm003.qcow2'/>
</disk>

<!-- 修改网卡的 MAC 地址(可以直接删掉这一行,让系统自动分配一个新的 MAC) -->
<interface type='bridge'>
  <mac address='52:54:00:44:f1:0c'/>
</interface>

4)使用修改好的 XML 配置文件定义并注册新的虚拟机:

bash

virsh define /etc/libvirt/qemu/vm003.xml

3. 虚拟机日常管理

熟练使用 virsh 命令可以帮助我们高效管理虚拟机的运行状态。

1)查看当前虚拟机列表

bash

virsh list --all

输出会显示各个虚拟机的状态(如 running 运行中、shut off 关闭状态等)。

2)开启指定的虚拟机

bash

virsh start vm001

3)重启指定的虚拟机

bash

virsh reboot vm001

4)正常关闭虚拟机(相当于向系统发送关机信号):

bash

virsh shutdown vm001

5)强制断电关闭虚拟机(强制停止运行,适用于系统死机等情况):

bash

virsh destroy vm001

6)设置虚拟机随物理宿主机开机自动启动

bash

virsh autostart vm001

7)取消虚拟机的开机自启动

bash

virsh autostart --disable vm001

4. 虚拟机快照管理

快照功能可以保存虚拟机在某一特定时刻的状态。在进行系统升级或修改重要配置前打个快照,如果出现问题可以快速回滚。

1)查看指定虚拟机的快照列表

bash

virsh snapshot-list vm001

2)为虚拟机创建一个新快照(例如命名为 snapshot3):

bash

virsh snapshot-create-as --domain vm001 --name snapshot3

3)恢复虚拟机到指定的快照状态(注意:这会覆盖当前的数据):

bash

virsh snapshot-revert vm001 snapshot1

4)删除不再需要的快照

bash

virsh snapshot-delete vm001 snapshot3

5. 虚拟机存储管理

在 KVM 中,模拟磁盘的实体被称为“卷(Volume)”,而这些卷被存放在“存储池(Storage Pool)”里。管理存储主要就是对这两者进行管理。

存储池可以是本地的一个目录,也可以是其他复杂的存储形式。我们以最常见的目录型存储池为例。

1)查看所有存储池的列表

bash

virsh pool-list --all

2)定义一个新的目录型存储池(比如命名为 data,对应系统上的 /data 目录):

bash

mkdir /data
virsh pool-define-as data --type dir --target /data

3)构建存储池(对于目录型存储池主要是初始化工作):

bash

virsh pool-build data

4)启动存储池(启动后状态会变为 active):

bash

virsh pool-start data

5)设置存储池开机自动启动

bash

virsh pool-autostart data

6)查看存储池的详细信息(例如容量大小、可用空间等):

bash

virsh pool-info data

7)查看存储池的 XML 配置信息

bash

virsh pool-dumpxml data

8)关闭存储池

bash

virsh pool-destroy data

9)删除存储池的定义(让 KVM 不再管理这个存储池,但不会删除硬盘上的实际文件数据):

bash

virsh pool-undefine data

“卷”就是实际给虚拟机用的一块块虚拟硬盘(比如 qcow2 文件)。

1)查看某个存储池下的卷列表

bash

virsh vol-list data --details

2)在存储池中创建一个新卷(例如创建容量为 1GB 的卷 vol2):

bash

virsh vol-create-as --pool data --name vol2 --capacity 1G

3)查看卷的 XML 配置信息

bash

virsh vol-dumpxml vol2 --pool data

4)删除存储池中的某个卷

危险
删除卷会彻底清空上面的所有数据,请确认数据已备份或不再需要时再执行此操作。

bash

virsh vol-delete vol2 --pool data

6. 虚拟网络管理

KVM 的虚拟网络主要分为三种模式:

  • NAT 模式:虚拟机通过地址转换与外部通信(能上网,但外网无法直接访问虚拟机)。
  • Routed 模式(路由模式):虚拟机通过宿主机的路由功能与外界通信。
  • Isolated 模式(隔离模式):虚拟机不与外界通信,仅限内部互联。
开启包转发

如果使用 NAT 或 Routed 模式,宿主机其实充当了路由器的角色。因此,必须要修改 Linux 内核参数来开启 IP 包转发功能:

bash

vi /etc/sysctl.conf
# 添加或修改以下内容:
net.ipv4.ip_forward=1

# 使修改立即生效
sysctl -p

和虚拟机一样,每个虚拟网络也有自己的 XML 配置文件,存放在 /etc/libvirt/qemu/networks 目录下。

1)查看当前虚拟网络列表

bash

virsh net-list --all

2)创建虚拟网络

  • 创建 NAT 模式网络: 编写一个 net1.xml 文件配置,指定其转发模式为 nat,并配置 DHCP 分配的 IP 段:

xml

<network>
  <name>net1</name>
  <forward mode='nat'/>
  <bridge name='br1' stp='on' delay='0'/>
  <ip address='192.168.1.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.1.2' end='192.168.1.254'/>
    </dhcp>
  </ip>
</network>

使用 net-create 创建的是临时网络(重启后失效),想要永久保存,需要使用 net-define 命令定义网络:

bash

virsh net-define /etc/libvirt/qemu/networks/net1.xml
  • 创建 Routed 模式网络: 路由模式的配置文件重点在于 forward mode='route',需要配置正确的网关和前缀:

xml

<network>
  <name>net2</name>
  <forward dev='ens33' mode='route'>
      <interface dev='ens33'/>
  </forward>
  <bridge name='br2' stp='on' delay='0'/>
  <domain name='net2'/>
  <ip address='192.168.2.1' netmask='255.255.255.0'>
  </ip>
  <route family='ipv4' address='192.168.2.0' prefix='24' gateway='192.168.2.1'/>
</network>

然后定义:

bash

virsh net-define /etc/libvirt/qemu/networks/net2.xml
  • 创建 Isolated 模式网络: 隔离模式的配置最简单,它没有 forward 标签,虚拟机只能在 br3 网桥内互通:

xml

<network>
  <name>net3</name>
  <bridge name='br3' stp='on' delay='0'/>
  <domain name='net3'/>
  <ip address='192.168.3.1' netmask='255.255.255.0'>
  </ip>
</network>

然后定义:

bash

virsh net-define /etc/libvirt/qemu/networks/net3.xml

3)启动虚拟网络(例如启动 net1):

bash

virsh net-start net1

4)设置虚拟网络自动启动

bash

virsh net-autostart net1

5)停止指定的虚拟网络

bash

virsh net-destroy net1

6)取消网络自动启动

bash

virsh net-autostart net1 --disable

7)删除虚拟网络的定义

bash

virsh net-undefine net1

想要更改某台虚拟机所连接的虚拟网络(例如让 vm001 连接到我们新建的 net1 或者 default 网络),我们需要去修改虚拟机的 XML 配置文件。

1)在操作前,请先关闭虚拟机:

bash

virsh destroy vm001

2)使用命令编辑虚拟机的配置文件:

bash

virsh edit vm001

3)找到 <interface> 部分,将 source network 的值改为你想让虚拟机加入的网络名称即可。

xml

<interface type='network'>
    <!-- 把 default 改为 net1 或其他网络的名字 -->
    <source network='default'/>
    <model type='virtio'/>
    <!-- 省略其他硬件配置 -->
</interface>

保存配置后,重启虚拟机 virsh start vm001,新的网络设置就会生效了。