kvm是linux中主机级虚拟化的一种实现方式,它使用kvm.ko模块安装后能将内核慢慢转变为hypervisor,只保留原来的用户空间来对虚拟机进行管理,而qemu-kvm是对kvm的api经行使用的用户空间的程序,它能虚拟化所有的I/O设备。

KVM的组件:

  • kvm.ko:模块
    API
  • qemu-kvm:用户空间的工具程序;

安装前需要确认你的CPU是否支持硬件虚拟化,可以使用命令查看grep -E -i "(svm|vmx)" /proc/cpuinfo但是并没有显示是因为虚拟机中默认是不支持的,vmware可以设置支持硬件虚拟化


然后我们安装kvm模块

modprobe kvm 验证内核是否支持虚拟化技术,查看dev目录下是否生成字符设备

ll -h /dev/kvm

这就表示我们的虚拟机已经支持kvm虚拟技术了,接下来如果想要在里面创建虚拟机先要安装用户空间的工具程序。

libvirt-daemon-kvm qemu-kvm libvirt-manager libvirt

接下来我们可以直接启动服务

systemctl start libvirtd

我们可以使用virsh命令来创建桥,原来的网卡就成为了交换机,没有地址了。可能会提示创建失败,并且断开链接,只需要重启下主机就好了。

virsh iface-bridge ens33 br0

运行图形管理程序(ssh需要加-X远程连接才能看到)

virt-manager &


运行中的一个kvm虚拟机就是一个qemu-kvm进程,运行qemu-kvm程序并传递给它合适的选项及参数即能完成虚拟机启动,终止此进程即能关闭虚拟机;

上面介绍的是virt-manager的使用方法,如果想要使用qemu-kvm的命令需要将二进制文件复制到/bin或/sbin目录下因为默认的命令路径并不在/bin或/sbin下,我们也可以创建一个符号链接ln -sv /usr/libexec/qemu-kvm /usr/bin/

语法:

标准选项:
    -machine [type=]name:-machine help来获取列表,用于指定模拟的主机类型; 
    -cpu cpu:-cpu help来获取列表;用于指定要模拟的CPU型号;
    -smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]:指明虚拟机上vcpu的数量及拓扑;
    -boot [order=drives][,once=drives][,menu=on|off] [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off]
        order:各设备的引导次序:c表示第一块硬盘,d表示第一个光驱设备;-boot order=dc,once=d
    -m megs:虚拟机的内存大小;
    -name NAME:当前虚拟机的名称,要惟一;
    
块设备相关的选项:
    -hda/-hdb file:指明IDE总线类型的磁盘映射文件路径;第0和第1个;
    -hdc/-hdd file:第2和第3个;
    
    -cdrom file:指定要使用光盘映像文件; 
    
    -drive [file=file][,if=type][,media=d][,index=i] [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]:
        file=/PATH/TO/SOME_IMAGE_FILE:映像文件路径;
        if=TYPE:块设备总线类型,ide, scsi, sd, floppy, virtio,...
        media=TYPE:介质类型,cdrom和disk;
        index=i:设定同一类型设备多个设备的编号;
        cache=writethrough|writeback|none|directsync|unsafe:缓存方式;
        format=f:磁盘映像文件的格式;
        
显示选项:
     -display type:显示的类型,sdl, curses, none和vnc;
    -nographic:不使用图形接口; 
    -vga [std|cirrus|vmware|qxl|xenfb|none]:模拟出的显卡的型号;
    -vnc display[,option[,option[,...]]]]:启动一个vnc server来显示虚拟机接口; 让qemu进程监听一个vnc接口5900; 
        display:
            (1) HOST:N
                在HOST主机的第N个桌面号输出vnc;
                    5900+N
            (2) unix:/PATH/TO/SOCK_FILE
            (3) none
            
        options:
            password:连接此服务所需要的密码;
    
    -monitor stdio:在标准输出上显示monitor界面;
        Ctrl-a, c:在console和monitor之间切换;
        Ctrl-a, h
    
    
网络选项:
    -net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]
        为虚拟机创建一个网络接口,并将其添加至指定的VLAN;
        model=type:指明模拟出的网卡的型号,ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio;
            -net nic,model=?
        macaddr=mac:指明mac地址;52:54:00:
        
    -net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]:
        通过物理的TAP网络接口连接至vlan n;
        script=file:启动虚拟机时要执行的脚本,默认为/etc/qemu-ifup
        downscript=dfile:关闭虚拟机时要执行的脚本,/etc/qemu-ifdown
        ifname=NAME:自定义接口名称;
        
        /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 specified."
                exit 1
            fi	
            
    其它选项:
        -daemonize:以守护进程运行;

演示使用命令行启动安装一个虚拟机

qemu-img info /root/img/cirros-0.3.4-x86_64-disk.img
#查看一个img文件的属性
 qemu-img create -f qcow2 -o preallocation=metadata,size=80G /root/img/cros.img
#创建一个镜像文件
qemu-kvm -name cros -m 256 -cpu host -smp 2,cores=2,sockets=1 -drive file=/root/img/cros.img,if=virtio,media=disk,cache=writeback,format=qcow2 -vnc :0
#利用上面创建的镜像文件创建了一个虚拟机
yum install tigervnc -y
#安装一个vnc界面
vncview :0
#连接第0个终端

虚拟机安装并不难,难得是实现网络,虚拟机内部的虚拟网卡一端连接到一个宿主机中虚拟的二层交换机(桥,br0),那么可以认为一张虚拟网卡在虚拟机本地,一张在对端的网络中。创建两个接口
仅主机模式是宿主机也创建一张虚拟网卡,一半在虚拟的二层交换机上,一半在宿主机上,就可以实现宿主机和各虚拟机的通信了
ip link add vethx.1 type veth peer name vethx.2 可以使用网络名称空间模拟另一个用户空间。
ip netns add router1 创建一个名称空间router1
ip link set dev vethx.2 netns router1 将另一张网卡放进这个名称空间
ip netns exec router1 ifconfig -a 对这个名称空间执行ifconfig命令,相当于就是另一个虚拟机,这时他们之间可以互相通信
这是一台宿主机中的两个虚拟机实例之间的通信实现方式,如果虚拟机想要与外部网络通信的话可以做NAT,但这样会暴露内部的服务,且如果两台宿主机的虚拟机实例想要通信会更复杂,这时候就可以在两台宿主机之间搭建一个隧道类似于VPN(当然这里使用VPN技术也可以达到目的)
在kvm中还可以使用virsh来对虚拟机进行管理,但一般都是使用virt-manager,virsh对我们了解基础原理很有帮助
语法:

virsh [OPTION]... COMMAND [ARG]..

子命令的分类:
    Domain Management (help keyword 'domain')
    Domain Monitoring (help keyword 'monitor')
    Host and Hypervisor (help keyword 'host')
    Interface (help keyword 'interface')
    Networking (help keyword 'network')
    Network Filter (help keyword 'filter')
    Snapshot (help keyword 'snapshot')
    Storage Pool (help keyword 'pool')
    Storage Volume (help keyword 'volume')
    
Domain Management (help keyword 'domain')
    create:从xml格式的配置文件创建并启动虚拟机;
    define:从xml格式的配置文件创建虚拟机;
    
    destroy:强行关机;
    shutdown:关机;
    reboot:重启;
    
    undefine:删除虚拟机;
    
    suspend/resume:暂停于内存中,或继续运行暂停状态的虚拟机;
    
    save/restore:保存虚拟机的当前状态至文件中,或从指定文件恢复虚拟机;
    
    console:连接至指定domain的控制台;
    
    attach-disk/detach-disk:磁盘设备的热插拔;
    
    attach-interface/detach-interface:网络接口设备的热插拔;
        type:bridge
        source:BRIDGE_NAME
        
        注意 :无须事先创建网络接口设备;
        
Domain Monitoring (help keyword 'monitor')
    domiflist
    domblklist
    ...