KVM虚拟化

KVM虚拟化基础

虚拟化技术两种实现

  Type-I

    hypervisor ---> vm

    Xen、RHEV、ESXi

  Type-II

    host vmm ---> vms

    KVM、VMware Workstation、Virtual Box

    依赖底层操作系统

Kernel-based Virtual Machine

  It's linux kernel module

  if load this module , the kernel changed to hypervisor

  他没有访问硬件IO的能力,只能将请求交往用户空间进程,用户空间进程在将发出系统调用,内核处理完才将信息返回

  guest user program ---> guest OS kernel ---> host user program (qume) ---> host kernel ---> IO hardware

依赖于底层虚拟化指令集

    Intel VT-x, AMD AMD-V;

直接使用使用系统的

  安全子系统、网络协议栈、硬件IO功能 ...

KVM模块载入后系统的运行模式

  内核模式

    GuestOS执行I/O类操作,或其他特殊的指令

  用户模式

    代表guestOS请求IO类操作

  来宾模式

    运行虚拟机中的进程

  kvm hypervisor

KVM组件

/dev/kvm

    工作在内核空间,在用户空间,可通过ioctl()系统调用来完成VM创建、启动、管理虚拟机功能

    它是一个字符设备

    创建VM、为VM分配内存、读写VCPU的寄存器、向VCPU注入中断、运行VCPU等等

qemu进程

    工作于用户空间,主要用于实现模拟PC的IO设备

KVM特性

  内存管理

    将分配给VM的内存交换至SWAP

    支持使用Huge Page

    支持使用Intel EPT或AMD RVI技术完成内存地址映射

      GVA ---> GPA ---> HPA

      GVA ---> HPA (EPT、RVI技术)

    支持KSM (Kernel Same-page Merging)

  硬件支持

    取决于Linux内核

  存储

    DAS

    NAS

    SAN

    Redistribute Storage (GlustFS)

  实时迁移

    支持

  支持的GuestOS

    Linux

    Window

    FreeBSD

    OpenBSD

    OpenSolaris

  设备驱动

    IO设备的完全虚拟化 模拟硬件

    IO设备的半虚拟化 在GuestOS中安装驱动 in DOM0

      virtio

        virtio-blk 块设备虚拟化

        virtio-net 网络设备的虚拟化

        virtio-pci pci虚拟化

        virtio-console 控制台虚拟化

        virtio-ballon 内存空间动态扩展或缩进的虚拟化

KVM局限性

  一般局限性

    overcommit

      单台物理机节点上的虚拟机使用核心数最好不要超过物理机上的核心数

      因为CPU被分割给虚拟机独享占用,导致系统时间总是不太精确(根据CPUHz,机器周期决定)

      vmtool 能同步系统时钟和虚拟机时钟

  MAC地址

    VM数量特别大时,存在冲突的可能性

    实时迁移限制

      如果使用本地磁盘当做虚拟机磁盘,那么就不能实时迁移虚拟机

      两台物理机的时间必须同步

      两台物理主机必须有相同的网络配置

  性能局限性

    全虚拟化技术对于CPU、网络IO、磁盘IO、GPU损耗最大

    半虚拟技术对于、、、损耗次与全虚拟化

    透传、、、损耗最低

KVM管理工具栈

Qemu

    qemu-kvm   通过/dev/kvm api调用,创建、开启、管理虚拟机

    qemu-img   管理虚拟机磁盘镜像

    qemu-io    管理磁盘IO、网络IO

libvirt

    GUI Virtual Machine Manager

        virt-manager GUI方式创建、安装管理虚拟机

        virt-viewer 登录查看管理虚拟机

    CLI virtinst

        virt-install 存命令行模式下,完成虚拟机的创建、安装

        virsh

            命令行管理工具,能管理整个虚拟机生命周期,需要xmi文件

        virt-image 对镜像进行管理的

        virt-convent 转换技术,调用qemu-img实现

        virt-clone

QEMU简介

  qemu是一个广泛使用的开源计算机仿真器和虚拟机。当作为仿真器时,可以在一种架构上(如PC机)下运行另一种架构(如ARM)下的操作系统和程序

  而通过动态转化,其可以获得很高的运行效率。当作为一个虚拟机时,qemu可以通过直接使用真机的系统资源,让虚拟机系统能够获得接近于物理机的性能表现

  qemu支持xen或kvm模式下的虚拟化。当用kvm时,qemu可以虚拟x86、服务器和嵌入式powerpc,以及s390的系统

  qemu当运行与主机架构相同的目标架构时可以使用KVM。例如,当在一个x86兼容处理器上运行qemu-system-x86时,可以利用KVM加速,为宿主机和客户机提供更好的性能

QEMU主要提供了以下几个部分

  处理器模拟器

  仿真IO设备

  关联模拟的设备至真实的设备

  调试器

  与模拟器交互的用户接口

  PowerPC专用选项

  Sparc32专用选项

启用KVM虚拟化

grep -E --colors=auto "(vmx|svm)" /proc/cpuinfo

# 如果有显示,则表示支持硬件虚拟化

# 装载内核模块

modprobe kvm

modprobe kvm-intel 

lsmod

modinfo kvm

ls /dev/kvm

# 如存在模块说明,kernel已经被kvm寄居成为hypervisor

# 安装虚拟化管理工具

    yum grouplist | grep -i "virtualization"

    virtualization 提供qemu-kvm

    virtualization Client

        python-virtinst

        virt-manager

        virt-viewer

    virtualization Platform

        libvirt

        libvirt-client 

    virtualization Tool 

        libguestfs

VMM

对IO的驱动有三种模式

    自主VMM:VMM自行提供驱动和控制台

    混合VMM:借助于OS提供驱动

        依赖于外部OS实现权威

        自我提供权威

    寄宿式VMM

IO虚拟化模型

    模拟

    半虚拟化

    透传

查看系统信息

lspci

ls /sys/block

ls /sys/bus/

ls /sys/bus/virtio/devices

管理KVM虚拟机

qemu-kvm使用

安装

1 yum install -y qemu-kvm

核心工具

  # 不依赖管理员权限也能使用

  /usr/libexec/qemu-kvm

链接

  ln -sv /usr/libexec/qemu-kvm /usr/bin

官方文档

  https://qemu.weilnetz.de/doc/qemu-doc.html

使用格式

  # usage: qemu-kvm [options] [disk_image]

 

qemu-kvm标准选项

-name name  设定虚拟机名称

-M machine 指定要模拟的主机类型

    如Standard PC、ISA-only PC或Inter-Mac等,可以使用“qemu-kvm -M ?”获取所支持的所有类型

-m megs 设定虚拟机的内存大小M

-cpu model  设定CPU类型

    如coreduo、qemu64等,可以使用“qemu-kvm -cpu ?”  

-smp n[,cores=cores][,threads=threads][,sockets=sockets][,maxcpus=maxcpus]

    设定模拟的SMP架构中CPU的个数、每个CPU的核心数以及CPU的socket数目等

    PC机上最多可以模拟255颗CPU

    maxcpus用于指定热插入的CPU个数上限

    n = core * thread * socket

-numa opts  指定模拟多节点的numa设备

    非一致内存访问:

-fda file

-fdb file   使用指定文件file作为软盘镜像,file为/dev/fd0表示使用物理软驱

-hda file

-hdb file

-hdc file

-hdd file

-cdrom file 使用指定file作为CD-ROM镜像

    注意-cdrom不能和-hdc同时使用

    将file指定为/dev/cdrom可以直接使用物理光驱

-drive option[,option[,option]] 定义一个硬盘设备

    file=/path/to/somefile  硬盘映像文件路径

    if=interface    指定硬盘设备所链接的接口类型

        如ide、scsi、sd、mtu、floppy、pflash及virtio等
    
    index=index 设定同一种控制器类型中不同设备的索引号,即标识号

    media=media 定义介质类型为硬盘(disk)或光盘(cdrom)

    snapshot=snapshot

        writethrough 在缓存中写完数据,立即在内存中刷新数据

        writeback 在缓存中写玩数据,不立即同步好缓存,但缓存中更该一定量的数据后,在一并写到内存

        unsaf   性能最好

        none    不打开缓存功能

    format=format   指定映像文件的格式
    
        具体格式可参见qemu-img命令

-boot [order=drives][,once=drives][,menu=no|off]    定义启动设备的引导次序

    每种设备使用一个字符表示:不同的架构所支持的设备及其表示字符不尽相同

    在x86架构上,a、b表示软驱、c表示第一块硬盘、d表示第一个光驱设备,n-p表示网络适配器,默认为硬盘设备

    -boot order=dc,once=d

显示选项

# 显示选项用于定义虚拟机启动后的显示接口相关类型及属性等

SDL C语言开发,跨平台且开源多媒体程序库文件,提供图形化界面底层库文件

    在qemu中使用"-sdl"调用即可,当然操作系统需要先装上sdl的相关显示库

-curses 禁止图形化接口,并使用curses/ncurses作为交互接口

-alt-grab 使用Ctrl + Alt + Shift组合释放鼠标

-sdl 启动SDL

-spice option[,option[,...]]    启用spice远程桌面协议,其有许多子选项。

-vga type   指定要仿真的VGA接口类型

    # 常见类型

    cirrus  Cirrus Logic GD5446显示卡

    std 带有Bochs VBI扩展的标准VGA显示器卡

    vmware VMware SVGA-II兼容的显示适配器

    qxl QXL半虚拟化显示卡,在使用spice协议时推荐使用次类型

    none 禁用VGA卡

-vnc display[,option[,...]] 默认情况下,qemu使用SDL显示VGA输出

    使用VNC选项,可以让qemu监听在VNC上,并将VNC输出重定向至VNC回话

    使用VNC选项,必须使用 -k 选项指定键盘布局类型

    显示方式

        1. host: N

            监听于xxxx:5900+N的端口上

        2. unix:/path/to/socket_file

        3. none 

    options

        password 连接时需要验证密码密码,设定密码通过monitor接口使用change

        reverse “反向”连接至某处监听状态的vncviewer上

-monitor stdio   表示在标准输入输出上显示monitor界面

-nographic  默认情况下,qemu使用SDL来显示VGA输出,而此选项用于禁用图形接口,此时qemu类似一个简单的命令行程序,其仿真串口设备将被重定向到控制台

    使用Ctrl + ac 在Console和Monitor之间切换

    Ctrl + ah 显示帮助信息

    设置VNC密码

        change vnc password

qemu-kvm网络属性选项

参数使用

-net nic[,vlan=n][,macaddr=mac][,model=type][,name=name][,addr=addr][,vectors=v]

    创建一个新的网卡设备并连接至vlan中,PC架构上默认的NIC为e1000,macaddr用于为其指定MAC地址
    
    ,name用于指定一个在监控时显示的网上设备名称,qemu可以模拟多个类型的网卡设备,如

    ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio,smc91c111,lance及mcf_fec等

    不过,不同的平台架构上,其支持的类型可能只包含前述列表的一部分,可以使用命令来获取当前平台支持的类型

    qemu-kvm -net nic,model=?

-net tap[,vlan][,name=][,fd=h][,ifname=name][,script=file][,downscript=dfile]

    通过物理机的TAP网络接口连接至vlan n中,使用script=file指定的脚本(默认为/etc/qemu-ifup)来配置当前网络接口

    并使用downscript=file指定的脚本(默认/etc/qemu-ifdown)来撤销接口配置;使用script=no和downscript=no可分别用来禁止执行脚本

        vim /etc/qemu-ifup

        #! /bin/bash
        # 
        bridge=br0

        if [ -n "$1" ];then
            ip link set $1 up
            sleep 1
            brctl addif $bridge $1 
        [ $? -eq 0 ] && exit 0 || exit 1
            else
            echo "Error: no interface scpecified."
        exit 1
        fi

        # ifdown是自动实现的,可以不用写 

        vim /etc/qemu-ifdown

        #! /bin/bash
        # 
        bridge=br0

        if [ -n "$1" ];then
            brctl delif $bridge $1
            ip link set $1 down
            exit 0
        else
            echo "Error: no interface scpecified."
            exit 1
        fi
                
-net user[,option][,option][...]

    在用户模式配置网络栈,其不依赖于管理权限,有效选项有

        vlan=n  连接至vlan n,默认n=0

        name=name 指定接口的显示名称,常用于监控模式中

        net=addr[/mask] 设定GuestOS可见的IP网络,掩码可选,默认为10.0.2.0、/8

        host=addr 指定GuestOS中看到的物理机的IP地址,默认为指定网络中的第二个,即x.x.x.2

        dhcpstart=addr 指定DHCP服务器地址池中16各地址的起始地址IP,默认为第16个到第31个,x.x.x.16-x.x.x.31

        dns=addr 指定GuestOS可见的dns服务器,默认为GuestOS网络中的第三个地址,x.x.x.3

        tftp=dir 激活内置的tftp服务器,并使用指定的dir作为tftp服务器的默认根目录

        bootfile=file BOOTP文件名称,用于实现网络引导GuestOS,如
        
            qemu -hda linux.img -boot n -net user,tftp=/tftpserver/pub,bootfile=/pxelinux.0

KVM网络模型

隔离模型

    只允许虚拟机之间相互通信

    各虚拟机之间通过虚拟网桥实现通信

    实现

        1. 创建虚拟网桥

        2. 虚拟机的tap设备都添加到虚拟网桥上

路由模型

    各位虚拟机网关指向物理网卡虚拟的出来的虚拟网卡,并且该虚拟网卡连接虚拟网桥

    物理主机打开核心转发功能

    实现

        1. 虚拟机的tap设备都添加到虚拟网桥上

        2. 在虚拟机里配置默认网关,指向物理网卡

NAT模型

    在物理主机开启nat功能,内部虚拟机访问外网时,转换成物理主机上的外网接口地址去访问公网

    需要添加定义netfilter规则

    实现

        1. 虚拟机的tap设备都添加到虚拟网桥上

        2. 虚拟网桥上配置虚拟机的网关

        3. 在POSTROUTING上配置SNAT

桥接模式

    物理网卡被虚拟成网桥设备,开启混杂模式,监听所有mac地址

    真实的物理网卡被虚拟成一块虚拟网卡,该虚拟网卡使用原物理网卡上的mac地址

    网络包进来后,再根据mac地址转发

    实现

        1. 虚拟机的tap设备都添加到虚拟网桥上

        2. 虚拟网桥开启混杂模式监听网络中所有的流量

            ip link set dev br0  promisc on

            ip addr del x.x.x.x dev ens33; brctl addif br0 ens33; ip addr add x.x.x.x/x dev br0

管理桥设备

yum list all | grep -i bridge

modinfo bridge

# nmtui图形化管理网桥

brctl addbr br0

brctl stp br0 off

# 激活网桥

ip link set dev br0 down

brctl add 

brctl show 

brctl delbr br0

管理网卡对

ip link add veth1.0 type veth peer veth1.1

ip link set veth1.0 up

ip link set veth1.1 up

qemu-kvm其它选项

  块设备选项

  i386平台专用选项

  字符设备选项

  蓝牙设备选项

  Linux启动器专用选项

  调试/专家模式选项

qemu-img使用

# 支持多种虚拟化镜像文件格式

    vmdk VMware

    vdi VirtualBox

    raw dd命令,很多高级功能不支持

    qcow2 现在KVM、Xen广泛支持的格式

    ...

# 无损格式转换

    convert         

# 显示磁盘映像信息

    qemu-img info cirros-*

# 制作光盘映像文件

    qemu-img create -o ? -f qcow2 /images/windows/winxp.qcow2

    qemu-img create -o size=20G,preallocation=metadata -f qcow2 /images/windows/winxp.qcow2

    du -sh /images/windows/winxp.qcow2

安装使用一个kvm虚拟机

下载公共映像文件

为cloud环境测试vm提供的微缩版的Linux

1 wget https://launchpad.net/cirros/trunk/0.3.2/+download/cirros-0.3.2-source.tar.gz

启动第一个虚拟机工作在后台

qemu-kvm -m 128 -smp 2 -name test -daemonize -hda /images/kvm/cirros-0.3.4-i386.disk.img

用-drive指定磁盘映像文件高级功能

qemu-kvm -m 128 -name test -smp 2 -drive file=/images/kvm/cirros-0.3.4-i386.disk.img,if=virtio,media=disk,cache=writeback,format=qcow2

通过cdrom启动winxp,内外鼠标会不一致,没有加载USB驱动(-usbdevice tablet)

qemu-kvm -name winxp -smp 4,sockets=1,cores=2,threads=2 -m 512 -drive file=/images/kvm/winxp.img,if=ide,media=disk,cache=writeback,format=qcow2 -drive file=/root/winxp_ghost.iso,media=cdrom    

使用PXE安装虚拟机系统

qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d \
-drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2 \
-net nic,model=virtio,macaddr=x:x:x:x:x:x \
-net tap,ifname=rhel5.8,script=/etc/ifup \
-boot order=nc,once=n \
-vga cirrus -balloon virtio

其它安装linux虚拟机方式

# 下面的命令创建了一个名为rhel5.8的虚拟机,其RAM大小为512MB,有两颗CPU的SMP架构,默认引导设备为硬盘,有一个硬盘设备和一个光驱,
# 网络接口类型为virto,VGA模式为cirrus并启用了balloon功能

qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d \
-drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2 \
-drive file=/isos/rhel5.8.iso,index=1,media=cdrom \
-net nic,model=virtio,macaddr=x:x:x:x:x:x \
-vga cirrus -balloon virtio
# 需要注意的是,上述命令中使用的硬盘映像文件/VM/images/rhel5.8/hda需要事先使用qemu-kvm命令创建
# 在虚拟机创建并安装GuestOS完成之后,可以免去光驱设备直接启动

qemu-img create -o size=20G,preallocation=metadata -f qcow2 file=/VM/images/rhel5.8/hda

qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d \
-drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2 \
-net nic,model=virtio,macaddr=x:x:x:x:x:x \
-vga cirrus -balloon virtio
# 指定使用桥网络接口
qemu-kvm -m 128 -name test -smp 2 -drive file=/images/kvm/cirros-0.3.4-i386-disk.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic -net tap,script=/etc/if-up,downscript=no -nographic

使用vnc登录虚拟机

# 为可以登录使用、管理虚拟机,我们需要下载一个远程桌面登录工具VNC

    yum install -y tigervnc

    # 连接我本创建好的虚拟机

    vncviewer :5900

    # 启动qemu-kvm时,额外使用-monitor stdio选项,并使用

    change vnc password

# 管理虚拟机命令

    root@localhost#info

虚拟机迁移 VM Migration

static migtation

live migration

    整体迁移时间

    服务器停机时间

    对服务的性能的影响

在待迁入主机使用

    qemu-kvm -vnc :N -incoming tcp:0:7777

    # N桌面号,tcp指定接收端口

    vncviewer :590N

在源主机使用

    monitor接口

        migrate tcp:DEST_IP:DEST:PORT

        # migrate tcp:DEST:PORT

virtio半虚拟化

HVM 虚拟化CPU

  需要底层硬件支持

I/O半虚拟化分成两段

前端驱动(virtio前半段)

    virtio-blk, virtio-net, virtio-balloon, virtio-console

    Linux CentOS支持    4.8+, 5.3+, 6.0+, 7.0+

virtio  虚拟队列-virt-ring

transport

后端处理程序(virt backend drivers),在QEMU中实现

virt-balloon

balloon  让VM中运行的GuestOS运行时动态调整其内存大小

# qemu-kvm -balloon virtio 开启虚拟机内存动态调整

手动查看GuestOS的内存大小

    info balloon

    balloon N

virt-net

其依赖于GuestOS中的驱动,及Qemu中的后端驱动

GuestOS virtio_net.ko

# qemu-kvm -net nic,model=virtio

Host中的GSO,TSO

    关掉可能会提升性能,并不是严重依赖,非必要情况下可以不取

        ethtool -K $IF gso off

        ethtool -K $IF tso off

        ethtool -K $IF

vhost-net 用于取代工作于用户空间的qemu中为virtio-net实现的后端驱动,以达到实现性能提升的驱动

    -net tap[,vnet_hdr=on|off][,vhost=on|off]

    qemu-kvm -net tap,vnet_hdr=on,vhost=on

virtio-blk

其依赖于GuestOS中的驱动,及Qemu中的后端驱动

-drive file=/path/to/some_image_file,if=virtio

kvm_clock 半虚拟化的时钟

# grep -i "paravirt" /boot/config-2.6.32-504.el6.x86_64

CONFIG_PARAVIRT_GUEST=y

CONFIG_PARAVIRT=y

CONFIG_PARAVIRT_CLOCK=y

猜你喜欢

转载自www.cnblogs.com/cq146637/p/8932135.html