• 虚拟化技术之kvm虚拟机创建工具qemu-kvm


      在前边的博客中我们介绍了如何创建kvm虚拟机,以及一些常用的工具的介绍和使用,今天我们来了解下kvm原始工具qemu-kvm;为什么说qemu-kvm是一个原始的工具呢,如果你用kvm虚拟机,心细的你一定会发现我们不管用什么工具创建kvm虚拟机,在宿主机上表现的都是一个以/usr/libexec/qemu-kvm的进程;这意味着我们之前用的工具它们都调用了qemu-kvm这个工具来创建虚拟机,从而我们在宿主机上看到的都是qemu-kvm进程;如下所示:

      提示:以上centos7这个虚拟机是我们之前使用virt-install这个工具在命令行中直接创建的;

      qemu-kvm这个工具是使用kvm虚拟机时核心工具,从上面的进程信息可以看到,它可以完整的实现一个虚拟机实例,模拟出各种IO设备;其实我们在使用内核kvm功能时,我们只安装qemu-kvm就可以使用qemu-kvm这个用户空间工具来使用内核kvm功能了;

      好了,接下来我们来看看这个神奇的工具qemu-kvm吧!!qemu-kvm这个工具默认安装以后,它会把二进制文件放到/usr/libexec/这个目录下,它这样做的主要目的是不让用户直接在命令行执行它,为了我们不用每次都写绝对路径,我们可以把这个工具链接到我们的PATH环境变量的目录下。

      1、链接qemu-kvm到/usr/bin/目录下

    [root@node1 ~]# ll /usr/libexec/qemu-kvm 
    -rwxr-xr-x 1 root root 5259704 5月  12 23:44 /usr/libexec/qemu-kvm
    [root@node1 ~]# ln -sv /usr/libexec/qemu-kvm /usr/bin/
    "/usr/bin/qemu-kvm" -> "/usr/libexec/qemu-kvm"
    [root@node1 ~]# ll /usr/bin/qemu-kvm 
    lrwxrwxrwx 1 root root 21 8月  21 18:20 /usr/bin/qemu-kvm -> /usr/libexec/qemu-kvm
    [root@node1 ~]# 
    

      2、查看qemu-kvm的帮助

      提示:从上面的过滤信息可了解到,qemu-kvm这个工具有标准选项,块设备相关选项,usb相关选项,显示相关选项,网络相关选项,字符设备相关选项,引导相关选项等等;

      3、qemu-kvm工具使用语法格式

    [root@node1 ~]# qemu-kvm -h
    QEMU emulator version 1.5.3 (qemu-kvm-1.5.3-173.el7_8.3), Copyright (c) 2003-2008 Fabrice Bellard
    
    WARNING: Direct use of qemu-kvm from the command line is not supported by Red Hat.
    WARNING: Use libvirt as the stable management interface.
    WARNING: Some command line options listed here may not be available in future releases.
    
    usage: qemu-kvm [options] [disk_image]
    
    'disk_image' is a raw hard disk image for IDE hard disk 0
    

      提示:从上面的帮助信息可以看到,qemu-kvm这个工具使用很简单,就是qemu-kvm +一堆选项来创建虚拟机;

      4、qemu-kvm标准选项

        -machine [type=]name:-machine help是用来获取支持的主机类型列表,该选项用来指定虚拟主机的类型;支持的类型有kvm, xen, tcg,默认不指定是tcg类型;

        -cpu cpu:-cpu help来获取支持的cpu类型列表;用于指定要模拟的CPU型号;-cpu hsot表示模拟和宿主机一样信号的cpu

        -smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]:用于指定cpu架构,其中socket表示有几颗CPU;cores表示每颗cup有几核心;threads表示每个CPU核心有机线程;maxcpus=socket*cores*threads;n等于小于maxcpus即可;

        -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;once表示第一次启动使用什么设备引导,once=d表示第一次启动使用光驱设备引导;

        -m megs:以M为单位指定虚拟机的内存大小;

        -name NAME:指定当前虚拟机的名称,要惟一;

      5、块设备相关的选项

        -hda/-hdb file:指明IDE总线类型的磁盘映射文件路径;第0和第1个;依次类推-hdc/-hdd file就表示第2和第3个IDE类型的磁盘;通常这种方式使用的很少,比较常用的方式是直接用-drive 来指定设备总线的类型;

        -cdrom file:指定要使用光盘映像文件;

        -drive [file=file][,if=type][,media=d][,index=i] [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]:用来指定虚拟设备的相关属性;其中file表示映像文件;if=TYPE:块设备总线类型,常用的总线类型有ide, scsi, sd, floppy, virtio等等;media=TYPE:介质类型,常用的介质类型有cdrom和disk;index=i:设定同一类型设备多个设备的编号;cache=writethrough|writeback|none|directsync|unsafe:缓存方式;none表示不使用cache;format=f:磁盘映像文件的格式;

      6、显示相关选项

        -display type:显示的类型,sdl, curses, none和vnc;

        -nographic:不使用图形接口; 不使用图形接口就表示没有显卡,没有显卡就只能使用串口来串行显示;

        -vga [std|cirrus|vmware|qxl|xenfb|none]:模拟出的显卡的型号;

        -vnc display[,option[,option[,...]]]]:启动一个vnc server来显示虚拟机接口; 让qemu进程监听一个vnc接口;在前边的博客中我们也介绍过vnc,vnc会与窗口号进行关联,第0号窗口就对应宿主机的5900端口;我们可以这样理解,第n号窗口,它对应宿主机上的端口就是5900+n;这里的n是从0开始;通常我们这里指定的都是窗口号;当然也是可以值指定监听的地址和端口,也可以指定密码;

        -monitor stdio:在标准输出上显示monitor界面;Ctrl-a, c:在console和monitor之间切换;

      7、网络相关选项

        -net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]:用于指定创建虚拟机时在虚拟机上对应的接口相关属性;model=type:指明模拟出的网卡的型号,常用的网卡型号有ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio;可以使用qemu-kvm -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]:用于指定创建虚拟机时在宿主机上对应的接口相关属性;script=file:启动虚拟机时要执行的脚本,默认为/etc/qemu-ifup(一般需要手动编写);downscript=dfile:关闭虚拟机时要执行的脚本,/etc/qemu-ifdown(不需要手动编写,它自身就可以不依赖脚本从而卸载掉相关接口);ifname=NAME:自定义接口名称;

      8、其他选项

        -daemonize:以守护进程运行;

      好了,简单的了解了上述的选项以后我们就可以来使用qemu-kvm创建一个虚拟机了;

      示例:用qemu-kvm来创建虚拟机

      准备工作

      创建磁盘,这个步骤如果还不熟悉,请参考我的博客《虚拟化技术之kvm磁盘管理工具qemu-img》;

    [root@node1 ~]# ll /kvm/images/
    总用量 1560712
    -rw-r--r-- 1 qemu qemu 1598226432 8月  21 19:08 centos7.qcow2
    [root@node1 ~]# qemu-img create -f qcow2 /kvm/images/test.img 5G
    Formatting '/kvm/images/test.img', fmt=qcow2 size=5368709120 encryption=off cluster_size=65536 lazy_refcounts=off 
    [root@node1 ~]# ll /kvm/images/
    总用量 1560908
    -rw-r--r-- 1 qemu qemu 1598226432 8月  21 19:08 centos7.qcow2
    -rw-r--r-- 1 root root     197120 8月  21 19:18 test.img
    [root@node1 ~]#
    

      准备/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
    View Code

      提示:以上脚本就做了一件事,判断传过来的网卡是否存在,如果存在就把它关联到$bridge指定的桥上,并启动起来;如果传过来的网卡名称不存在,则报错没有指定的网卡,然后退出;最后别忘记给这个脚本加上可执行权限;

      查看宿主机上是否有br0,没有就创建一个br0,并把宿主机网卡ens33桥接到br0上;

    [root@node1 ~]# ifconfig -a
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.0.41  netmask 255.255.255.0  broadcast 192.168.0.255
            inet6 fe80::20c:29ff:fe9a:dbd6  prefixlen 64  scopeid 0x20<link>
            ether 00:0c:29:9a:db:d6  txqueuelen 1000  (Ethernet)
            RX packets 3943  bytes 356924 (348.5 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 2719  bytes 545299 (532.5 KiB)
            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 40  bytes 3112 (3.0 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 40  bytes 3112 (3.0 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
            ether 52:54:00:45:06:15  txqueuelen 1000  (Ethernet)
            RX packets 285  bytes 18774 (18.3 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 246  bytes 19814 (19.3 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    virbr0-nic: flags=4098<BROADCAST,MULTICAST>  mtu 1500
            ether 52:54:00:45:06:15  txqueuelen 1000  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet6 fe80::fc54:ff:feff:51f1  prefixlen 64  scopeid 0x20<link>
            ether fe:54:00:ff:51:f1  txqueuelen 1000  (Ethernet)
            RX packets 285  bytes 22764 (22.2 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 4051  bytes 217914 (212.8 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [root@node1 ~]# 
    

      提示:从上面的输出信息可以看到br0并不存在;

      手动创建br0配置文件,并修改ens33的配置文件

    [root@node1 network-scripts]# cat ifcfg-br0 
    TYPE=Bridge
    NAME=br0
    DEVICE=br0
    ONBOOT=yes
    IPADDR=192.168.0.41
    PREFIX=24
    GATEWAY=192.168.0.1
    DNS1=192.168.0.1
    [root@node1 network-scripts]# cat ifcfg-ens33
    TYPE=Ethernet
    NAME=ens33
    DEVICE=ens33
    ONBOOT=yes
    BRIDGE=br0
    [root@node1 network-scripts]# 
    

      重启网络

    [root@node1 network-scripts]# systemctl restart network
    [root@node1 network-scripts]# 
    [root@node1 network-scripts]# ifconfig
    br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.0.41  netmask 255.255.255.0  broadcast 192.168.0.255
            inet6 fe80::cc1c:b2ff:fe49:1138  prefixlen 64  scopeid 0x20<link>
            ether 00:0c:29:9a:db:d6  txqueuelen 1000  (Ethernet)
            RX packets 20  bytes 2000 (1.9 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 36  bytes 4708 (4.5 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            ether 00:0c:29:9a:db:d6  txqueuelen 1000  (Ethernet)
            RX packets 4544  bytes 411254 (401.6 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 3108  bytes 608414 (594.1 KiB)
            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 40  bytes 3112 (3.0 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 40  bytes 3112 (3.0 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
            ether 52:54:00:45:06:15  txqueuelen 1000  (Ethernet)
            RX packets 287  bytes 18878 (18.4 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 248  bytes 19946 (19.4 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet6 fe80::fc54:ff:feff:51f1  prefixlen 64  scopeid 0x20<link>
            ether fe:54:00:ff:51:f1  txqueuelen 1000  (Ethernet)
            RX packets 287  bytes 22896 (22.3 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 4312  bytes 231514 (226.0 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [root@node1 network-scripts]#
    

      提示:如果重启网络后,crt没有断开,说明我们配置的网络没有问题;从上面的信息可以看到br0已经创建,并且拥有一个地址我们在配置文件中指定的ip地址,而ens33它直接桥接到br0上了;

      准备好以脚本,磁盘文件,网络环境后,我们就可以来创建一个桥接到br0的虚拟机

    [root@node1 network-scripts]# virsh list --all
     Id    名称                         状态
    ----------------------------------------------------
     1     centos7                        running
    
    [root@node1 network-scripts]# qemu-kvm -name test 
    > -smp 2,maxcpus=4,sockets=2,cores=2 
    > -m 1024 
    > -cpu host 
    > -drive file=/kvm/images/test.img,media=disk,if=virtio,cache=writeback,format=qcow2, 
    > -drive file=/kvm/iso/CentOS-7-x86_64-Minimal-1708.iso,media=cdrom 
    > -boot order=dc,once=d 
    > -vnc :1 
    > -net nic,macaddr=52:54:00:00:00:01,model=virtio 
    > -net tap,script=/etc/qemu-ifup 
    > -daemonize
    [root@node1 network-scripts]# virsh list --all
     Id    名称                         状态
    ----------------------------------------------------
     1     centos7                        running
    
    [root@node1 network-scripts]#
    

      提示:默认直接手动使用qemu-kvm创建的虚拟机,在virsh list 中是看不到的;

      提示:从上面的截图来看,我们创建的虚拟机应该正常跑起来了,我们指定的1号窗口对应的端口已经处于监听状态,在进程列表中也能看到我们手动执行的命令也运行成进程;

      验证:用vnc连接宿主机的1号窗口,看看是否有虚拟机运行?

      提示:通过vnc连接1号窗口,可以看到我们指定的虚拟机已经创建好,正等着我们去装系统;

      提示:装好系统以后,我们需要关闭虚拟机(直接kill掉宿主机对应的进程即可),启动虚拟机时我们需要把光驱给卸载掉(不指定光驱设备),或者修改启动次序,不然它会一直以光驱做系统引导;

      关闭虚拟机

      修改启动次序,再次启动虚拟机

      提示:这里我们在原有的命令上,把once=d修改成once=c,其他选项都不要变;意思本次创建虚拟机,第一引导设备上是第一块硬盘;

      现在用vnc连接宿主机的1号窗口,看看虚拟机里装的系统是否启动起来了呢?

      提示:可以看到虚拟机里的系统已经正常启动了;从上面的过程来看,qemu-kvm本质上没有像virt-manager那样用图形界面创建虚拟机,装系统简单,我们需要手动的去指定各种设备,以及解决启动顺序,网络等等问题;所以通常qemu-kvm是通过一个磁盘镜像模板(就是装有系统的磁盘文件),然后配合网络环境来启动虚拟机;

      从上面vnc连接虚拟机控制台看,eth0处于关闭状态,接下来我们把eth0启动起来,看看它是否获取同宿主机br0桥上同网段的ip地址呢?

      提示:临时启动eth0以后,可以看到eth0上就获取到了一个192.168.0.0网段地址,和宿主机br0在同一网段,说明虚拟机的网络是桥接到宿主机上的物理网卡上;以上是临时启动eth0,如果要开机自动启动,需要修改其配置文件即可;

  • 相关阅读:
    error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
    E: 无法获得锁 /var/lib/apt/lists/lock
    卸载nginx
    服务器文件传输
    一些重要的sql命令
    设置某个字段的值是唯一的
    mysql注释的方法
    认证 (authentication) 和授权 (authorization) 的区别
    neutron_lib: 一个进程内的发布与订阅
    人工智能导论作业
  • 原文地址:https://www.cnblogs.com/qiuhom-1874/p/13542970.html
Copyright © 2020-2023  润新知