Centos7使用KVM安装虚拟机

本文主要介绍在centos7 上使用KVM(Kernel-based Virtual Machine)安装和管理虚拟机步骤, 不对虚拟化和KVM做深入讨论

官方文档 是个PDF, 由于外网打开慢, 最好下载下来放本地。

KVM 简介

KVM(Kernel-based Virtual Machine) 是一个Linux内核模块,允计用户空间进程使用硬件虚拟化特性,支持Intel和AMD cpu。KVM模块使得虚拟机可以像一个普通用户进程一样运行。

KVM 使用 QEMU实现I/O硬件模拟,QEMU是运行在用户空间的一种模拟器,能够以非常好的性能模拟各种处理器,配合KVM模块, 性能几乎可以接近物理机。KVM使用libvirt的API和工具来管理虚拟机,常用的工具有:virshvirt- installvirt-clone

环境准备

物理机

首先,得有一台物理机, 安装好centos7系统。
安装得所有虚拟机cpu数、内存大小、磁盘空间 之和,是可以超过物理机实际大小的。

虚拟化技术

首先要确认在BIOS设置里面开启了虚拟化技术(Virtualization Technology ), 如果没有开启,要重启电脑,进BIOS设置。
然后,检查处理器是否支持虚拟化技术(不是必须, 不支持的话, 性能不好):

1
$ grep -E 'svm|vmx' /proc/cpuinfo
  • vmx 是intel 处理器的
  • svm 是AMD的

如果有内容显示出来, 说明就是支持的。

安装依赖

1
$ yum install -y qemu-kvm libvirt libvirt-python libguestfs-tools virt-install

启用libvirtd服务

1
2
$ systemctl enable libvirtd 
$ systemctl start libvirtd

查看内核模块是否加载

1
2
3
4
$ lsmod | grep kvm
kvm_intel 188644 12 (只能Intel平台有这个)
kvm 621480 1 kvm_intel
irqbypass 13503 7 kvm

如果没有加载,运行

1
2
$ modprobe kvm
$ modprobe kvm-intel

然后再检查一下

操作系统安装文件

支持网络安装,本地安装, 鉴于我们的网速, 建议先下载好iso到本地。

配置网络桥接

默认情况下, 虚拟机只能通过内部网段192.168.122.0访问宿主机和同一宿主机上的其它虚拟机。如果想让虚拟机正常联网, 需要通过桥接,按如下步骤配置网桥:

  1. 修改目前网卡配置文件/etc/sysconfig/network-scripts/ifcfg-enp3s0, 这个文件名,每台机器可能不一样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    TYPE="Ethernet"
    #添加这一行配置
    BRIDGE=br0
    PROXY_METHOD="none"
    BROWSER_ONLY="no"
    BOOTPROTO="none"
    DEFROUTE="yes"
    IPV4_FAILURE_FATAL="no"
    IPV6INIT="yes"
    IPV6_AUTOCONF="yes"
    IPV6_DEFROUTE="yes"
    IPV6_FAILURE_FATAL="no"
    IPV6_ADDR_GEN_MODE="stable-privacy"
    NAME="enp3s0"
    UUID="3813d279-4934-4cf1-aadd-5248a2ff1828"
    DEVICE="enp3s0"
    ONBOOT="yes"
    #分配ip这几行要注释掉
    #IPADDR="192.168.5.160"
    #PREFIX="24"
    #GATEWAY="192.168.5.1"
    #DNS1="192.168.5.1"
    IPV6_PRIVACY="no"
  2. 创建桥接网卡配置文件/etc/sysconfig/network-scripts/ifcfg-br0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    TYPE="Bridge"
    PROXY_METHOD="none"
    BROWSER_ONLY="no"
    BOOTPROTO="none"
    DEFROUTE="yes"
    IPV4_FAILURE_FATAL="no"
    IPV6INIT="no"
    IPV6_AUTOCONF="yes"
    IPV6_DEFROUTE="yes"
    IPV6_FAILURE_FATAL="no"
    IPV6_ADDR_GEN_MODE="stable-privacy"
    NAME="br0"
    #UUID="3813d279-4934-4cf1-aadd-5248a2ff1828"
    DEVICE="br0"
    ONBOOT="yes"
    # ip配置和原网卡一致
    IPADDR="192.168.5.160"
    PREFIX="24"
    GATEWAY="192.168.5.1"
    DNS1="192.168.5.1"
    IPV6_PRIVACY="no"
  3. 重启网络服务

    1
    $ service network restart
  4. 检查宿主机网络是否正常

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $ ifconfig
    br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 192.168.5.160 netmask 255.255.255.0 broadcast 192.168.5.255
    inet6 fe80::a1f:71ff:fe08:882 prefixlen 64 scopeid 0x20<link>
    ether 08:1f:71:08:08:82 txqueuelen 1000 (Ethernet)
    RX packets 158 bytes 13663 (13.3 KiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 23 bytes 2062 (2.0 KiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    ether 08:1f:71:08:08:82 txqueuelen 1000 (Ethernet)
    RX packets 7730654 bytes 5696887592 (5.3 GiB)
    RX errors 0 dropped 20 overruns 0 frame 0
    TX packets 973360 bytes 83120547 (79.2 MiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
    inet 127.0.0.1 netmask 255.0.0.0
    inet6 ::1 prefixlen 128 scopeid 0x10<host>
    loop txqueuelen 1000 (Local Loopback)
    RX packets 32 bytes 2592 (2.5 KiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 32 bytes 2592 (2.5 KiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    可以看到br0 的ip是和原来一样的, 说明正常了。 可以ping一下内网其它机器, 外网域名来进一步确认

防火墙和SELINUX

直接关掉

1
2
3
4
$ setenforce 0
$ vim /etc/sysconfig/selinux
SELINUX=disabled
$ systemctl stop firewalld

生产环境不允许的话,参考原文操作

环境准备完毕!

创建虚拟机

1
2
3
4
5
6
7
8
9
$ virt-install \
--network bridge:br0 \
--name vm61 \
--ram=2048 \
--vcpus=2 \
--disk path=/home/vm-images/vm61.img,size=100 \
--graphics none \
--location=/tmp/CentOS-7-x86_64-DVD-1908.iso \
--extra-args="console=tty0 console=ttyS0,115200"

如此就创建了一个磁盘100G,内存2048M,2核 的虚拟机, 参数说明:

  • --network: 指定网卡, 这里选择前面创建的网桥br0
  • --name: 虚拟机名称
  • --ram:虚拟机内存, 单位MB
  • --vcpu : cpu数量
  • --disk path=/home/vm-images/vm61.img,size=100 : 虚拟机镜像文件存放的路径(确保这个目录挂载的盘有足够的空间),size参数指定虚拟机磁盘空间的大小
  • --graphics : 设置安装程序是否使用图形化界面,设置none的话,在安装过程中全直接使用文件方式在控制台配置虚拟机一些必要配置
  • --location=/tmp/CentOS-7-x86_64-DVD-1908.iso: 指定虚拟机要安装的操作系统的镜像文件位置, 可以是本地的, 也可以指定网络地址。我们这里指定的是本地的
  • --extra-args="console=tty0 console=ttyS0,115200": 此选项的值,在安装程序启动的时候作为启动参数使用。 我们设置的值,告诉安装程序运行的时候要开启控制台, 这个非常重要, 不要没有办法进行安装配置

更详细的说明请看

1
$ man virt-install

安装过程中有很多需要配置的地方,请按控制台提示依次进行设置。 前面有[!]标记的都是必须要设置的, [x]标记的表示已经设置完成的, []表示可选项

复制虚拟机

一般情况下, 我们都会创建多个虚拟机, 如果虚拟机的配置都相同,使用复制功能就很方便了,几秒钟建一个不是梦。

比如要所前面创建的虚拟机vm61复制一个叫vm62:

  1. 暂停被复制的虚拟机。

    1
    $ virsh suspend vm61
  2. 运行复制命令

    1
    $ virt-clone --connect qemu:///system --original vm61 --name vm62 --file /home/vm-images/vm62.img

    这步快的话几秒钟, 时长由被复制虚拟机的实际大小决定

  3. 恢复被复制机器

    1
    $ virsh resume vm61
  4. 刚复制出来的虚拟机是停止状态的, 需要启动它:

    1
    $ virsh start vm62

复制出来的机器和原机器所有属性(cpu,内存,磁盘空间等)一样, 只能修改一下MAC地址。 如果被复制机器使用的是静态ip, 那两个机器的ip都是一样的,那就有问题, 新机器会连不上网。这种情况需要使用宿主机通过控制台连上去修改ip配置, 后面会讲到怎么连。

管理虚拟机

常用命令

展示全部虚拟机, 加上--all 选项所有状态都会显示, 不加则 只显示running

1
2
3
4
5
6
$ virsh list --all
Id 名称 状态
----------------------------------------------------
6 vm61 running
8 vm62 running
- vm63 关闭

显示虚拟机信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ virsh dominfo vm61
Id: 6
名称: vm61
UUID: 354134f5-fd04-42ee-a49f-ddb3c4b65d96
OS 类型: hvm
状态: running
CPU: 2
CPU 时间: 1240.4s
最大内存: 2097152 KiB
使用的内存: 2097152 KiB
持久: 是
自动启动: 启用
管理的保存: 否
安全性模式: selinux
安全性 DOI: 0
安全性标签: system_u:system_r:svirt_t:s0:c987,c1009 (enforcing)

关闭虚拟机

1
2
$ virsh shutdown vm63
域 vm63 被关闭

启动虚拟机

1
2
$ virsh start vm63
域 vm63 已开始

开启自动启动,开启后宿主机启动,虚拟机就会自动启动

1
2
$ virsh autostart vm61
域 vm61标记为自动开始

关闭自动启动

1
2
$ virsh autostart --disable vm61
域 vm61取消标记为自动开始

虚拟机控制台访问

如前面复制虚拟机时讲到的, 如果虚拟机网络配置有问题, 不能远程访问。 那这时候就只能使用宿主机通过连接虚拟机控制台来操作虚拟机了。 控制台访问设置如下:

  1. 首先在宿主机的/etc/grub.conf 文件( 如果还没有该文件,就新建一个)添加如下内容:

    1
    console=tty0 console=ttyS0,115200
  2. 重启虚拟机

  3. 在宿主机上运行

    1
    2
    3
    $ virsh console vm61
    连接到域 vm61
    换码符为 ^]

    出现这个提示的时候,要再按一下回车键,就进入虚拟机的控制台了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    virsh console vm61
    连接到域 vm61
    换码符为 ^]


    CentOS Linux 7 (Core)
    Kernel 3.10.0-1062.el7.x86_64 on an x86_64

    vm61 login:

    这是虚拟机的登录界面。 如果要退出虚拟机控制台,按 组合键CTRL+], 这个输入的其实就是^]。 这就回到了宿主机的控制台了

删除虚拟机

需要删除某个虚拟机的话,需要如下几步:

  1. 先关闭虚拟机

    1
    # virsh shutdown vm61

    如果关机失败,可用如下命令强制关掉:

    1
    # virsh destroy vm61
  2. 取消虚拟机定义:

    1
    # virsh undefine vm61
  3. 最后删除掉虚拟机的镜像文件:

    1
    # rm /home/vm-images/vm61.img