• KVM 一键批量创建虚拟机 自动设置IP


    一、原理

    1. 需要先创建基础镜像,后续的镜像都是基于该镜像创建的差量镜像。基础镜像不允许修改(需要注意)。
    2. 基础镜像需要设置要一些基本内容。
    3. 通过 virt-edit 实现的设置ip.
    4. ip 信息统一用 <title> 来进行标记。 使用virsh list --title进行查看 机器和IP

    完成的功能:
    输入机器名称和ip,就能创建我们想要的虚拟机了。ip会自动帮我们设置好。

    解决的问题:

    1. 之前创建机器后需要手动去设置IP. virt-edit 进行编辑网络文件。
    2. 创建完机器,我们不知道机器对应的哪个IP. 使用 <title> 来进行标记。 使用virsh list --title进行查看 机器和IP对应关系

    二、基础镜像

    2.1、创建基础镜像

    • 内存为8G 和2核
    • 磁盘为50G
    • vnc 端口使用随机
    • 网络设置为桥接
    • 机器设置为自动启动
    virt-install --name base-image --virt-type kvm --memory 8096 --vcpus 2 --cdrom=/home/kvm/iso/CentOS-7-x86_64-Minimal-1908.iso --disk /home/kvm/data/base-image.qcow2,size=50,format=qcow2  --graphics vnc,listen=0.0.0.0  --network network=net-br --autostart  
    

    2.2、 完善基础镜像

    1. 增加 console 登陆

      grubby --update-kernel=ALL --args="console=ttyS0,115200n8"
      
    2. vnc 端口设置随机

    3. 使用桥接网络

    4. 设置网络配置

      BOOTPROTO=static  
      ONBOOT=yes
      IPADDR=192.168.1.12
      NETMASK=255.255.255.0
      GATEWAY=192.168.1.1
      DNS1=192.168.1.1
      # 注释uuid
      

    2.3、基础镜像设置权限

    由于使用的是差量镜像的模式,所以基础镜像不允许修改。

    chattr +i   /opt/kvm/data/base-image.qcow2
    

    3.4 设置 title

    编辑基础镜像的 xml 文件,增加 title。

     <title>192.168.1.156</title>
    

    3.5、基础镜像XML

    <!--
    WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
    OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
      virsh edit base-image
    or other application using the libvirt API.
    -->
    
    <domain type='kvm'>
      <name>base-image</name>
      <uuid>12348899-e829-4217-a0ff-f30eee4d2b31</uuid>
      <title>192.168.1.199</title>
      <memory unit='KiB'>16777216</memory>
      <currentMemory unit='KiB'>8388608</currentMemory>
      <vcpu placement='static' current='2'>4</vcpu>
      <os>
        <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
        <boot dev='hd'/>
      </os>
      <features>
        <acpi/>
        <apic/>
      </features>
      <cpu mode='custom' match='exact' check='partial'>
        <model fallback='allow'>Broadwell-IBRS</model>
        <feature policy='require' name='spec-ctrl'/>
      </cpu>
      <clock offset='utc'>
        <timer name='rtc' tickpolicy='catchup'/>
        <timer name='pit' tickpolicy='delay'/>
        <timer name='hpet' present='no'/>
      </clock>
      <on_poweroff>destroy</on_poweroff>
      <on_reboot>restart</on_reboot>
      <on_crash>destroy</on_crash>
      <pm>
        <suspend-to-mem enabled='no'/>
        <suspend-to-disk enabled='no'/>
      </pm>
      <devices>
        <emulator>/usr/libexec/qemu-kvm</emulator>
        <disk type='file' device='disk'>
          <driver name='qemu' type='qcow2'/>
          <source file='/opt/kvm/data/base-image.qcow2'/>
          <target dev='vda' bus='virtio'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
        </disk>
        <disk type='file' device='cdrom'>
          <driver name='qemu' type='raw'/>
          <target dev='hda' bus='ide'/>
          <readonly/>
          <address type='drive' controller='0' bus='0' target='0' unit='0'/>
        </disk>
        <controller type='usb' index='0' model='ich9-ehci1'>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
        </controller>
        <controller type='usb' index='0' model='ich9-uhci1'>
          <master startport='0'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
        </controller>
        <controller type='usb' index='0' model='ich9-uhci2'>
          <master startport='2'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
        </controller>
        <controller type='usb' index='0' model='ich9-uhci3'>
          <master startport='4'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
        </controller>
        <controller type='pci' index='0' model='pci-root'/>
        <controller type='ide' index='0'>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
        </controller>
        <controller type='virtio-serial' index='0'>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
        </controller>
        <interface type='network'>
          <mac address='52:54:00:28:99:22'/>
          <source network='net-br'/>
          <model type='virtio'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
        </interface>
        <serial type='pty'>
          <target type='isa-serial' port='0'>
            <model name='isa-serial'/>
          </target>
        </serial>
        <console type='pty'>
          <target type='serial' port='0'/>
        </console>
        <channel type='unix'>
          <target type='virtio' name='org.qemu.guest_agent.0'/>
          <address type='virtio-serial' controller='0' bus='0' port='1'/>
        </channel>
        <input type='tablet' bus='usb'>
          <address type='usb' bus='0' port='1'/>
        </input>
        <input type='mouse' bus='ps2'/>
        <input type='keyboard' bus='ps2'/>
        <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='en-us'>
          <listen type='address' address='0.0.0.0'/>
        </graphics>
        <video>
          <model type='cirrus' vram='16384' heads='1' primary='yes'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
        </video>
        <memballoon model='virtio'>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
        </memballoon>
        <rng model='virtio'>
          <backend model='random'>/dev/urandom</backend>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
        </rng>
      </devices>
    </domain>
    

    三、批量创建机器脚本

    因为需要使用 virt-edit,所以需要安装libguestfs-tools
    yum install -y libguestfs-tools

    #!/bin/bash
    #######################################################
    # $Name:        create_kvm_machine.sh
    # $Version:     v1.0
    # $Function:    create kvm machine
    # $Author:      dongjiaxiao
    # $Create Date: 2020-04-12
    # $Description: shell
    ######################################################
    #set -x
    # 检查基础镜像和xml是否存在并生成uuid,mac 信息
    function check(){
    	if [ ! -f "${xmls_dir}${base_xml}" ]&&[ ! -f "${images_dir}${base_img}" ] # 判断基础xml和基础镜像是否存在
    	then
    		echo "基础镜像或者基础镜像xml不存在"
    		exit 1
    	else
       		vir_uuid=`uuidgen`
    		vir_mac="52:54:$(dd if=/dev/urandom count=1 2>/dev/null | md5sum |sed -r 's/^(..)(..)(..)(..).*$/1:2:3:4/')"
    		vir_name=$machine_name        
    	fi 
    	
    }
    #创建磁盘
    function create_disk(){
    	chattr -i  ${images_dir}$base_img
    	qemu-img create -f qcow2 -b ${images_dir}$base_img ${images_dir}${vir_name}.qcow2 ${vir_disk}G  &>/dev/null
    }
    #添加磁盘
    function attach_disk(){
    	qemu-img create -f qcow2  ${images_dir}${vir_name}-2.qcow2  ${vir_attach_disk}G  >/dev/null
    	virsh attach-disk ${vir_name} ${images_dir}${vir_name}-2.qcow2 vdb --cache writeback --subdriver qcow2 --persistent >/dev/null
    	
    }
    
    #配置xml ,替换内存cpu 等信息并导入
    function conf_xml(){
    	cp  ${xmls_dir}${base_xml}  /tmp/${vir_name}.xml
    	sed -i "s#<memory unit='KiB'>.*</memory>#<memory unit='KiB'>${vir_mem}</memory>#"  /tmp/${vir_name}.xml 
    	sed -i "s#<currentMemory unit='KiB'>.*</currentMemory>#<currentMemory unit='KiB'>${vir_mem}</currentMemory>#"   /tmp/${vir_name}.xml 
    	sed -i "s#<vcpu placement='static'>.*</vcpu>#<vcpu placement='static'>${vir_cpu}</vcpu>#" /tmp/${vir_name}.xml
    	sed -i "s/<name>.*</name>/<name>${vir_name}</name>/" /tmp/${vir_name}.xml
    	sed -i "s/<uuid>.*</uuid>/<uuid>${vir_uuid}</uuid>/" /tmp/${vir_name}.xml
    	sed -i "s/<title>.*</title>/<title>${vir_ip}</title>/" /tmp/${vir_name}.xml
    	sed -i "s#<source file=.*/>#<source file='${images_dir}${vir_name}.qcow2'/>#" /tmp/${vir_name}.xml
    	sed -i "s/<mac address=.*/>/<mac address='$vir_mac' />/" /tmp/${vir_name}.xml
    	virsh define /tmp/${vir_name}.xml >/dev/null
    	virt-edit -d ${vir_name}  /etc/sysconfig/network-scripts/ifcfg-eth0  -e "s#IPADDR=".*"#IPADDR="${vir_ip}"#"  # 替换ip
    }
    
    #启动并设置开机自启
    function start_vir(){
    	virsh start ${vir_name} >/dev/null
    	virsh autostart ${vir_name} >/dev/null
    	chattr +i  ${images_dir}$base_img
    }
    #记录创建日志
    function create_vir_log(){
    	echo "$(date +%F_%T)  vir_name: ${vir_name} vir_ip: ${vir_ip} !"   >>$vir_log_file
    	echo "$(date +%F_%T)  vir_name: ${vir_name} vir_ip: ${vir_ip} 创建成功!" 
    }
    
    main(){
        images_dir="/home/kvm/data/" # 镜像存储的位置
        base_img="base-image.qcow2"  # 基础镜像的名称
        xmls_dir="/etc/libvirt/qemu/"  # xml 的位置
        base_xml="base-image.xml"   # 基础xml的名称 
        vir_log_file="/tmp/kvm_create_log.txt" # 创建日志文件
        vir_disk=50 # 磁盘默认为50G  
        vir_cpu=2 # cpu默认为2核
        vir_mem=8388608 # 内存默认为8G
        echo -e "服务器配置选项:
     1: 2核8G 50G(测试) 
     2: 1核8G 50G(开发) 
     3: 2核8G 100G(数据库) 
     4: 4核20G 200G" 
        read  -t 30 -p  "输入你选择的配置的编号(1-4):" number
        read  -t 90 -p "输入想要创建的IP(192.168.1.1):"  vir_ip
        read  -t 120 -p "输入想要创建的机器名称(haha-biz-1234567-test):"  machine_name
        if [ -z "$vir_ip" ] || [  -z "$machine_name" ] # 判断是否输入ip和机器名称
        then
           echo "请输入ip和机器名称"
           exit -1
        fi
        case "$number" in
            [1] )
                check
                create_disk
                conf_xml
                start_vir
                create_vir_log
            ;;
            [2] )
                vir_cpu=1  # 设置为1核
                check
                create_disk
                conf_xml
                start_vir
                create_vir_log
            ;;
            [3] )
                vir_disk=100 #设置为磁盘100G盘
                check
                create_disk
                conf_xml
                start_vir
                create_vir_log
            ;;
            [4] )
                base_img="dc-base-image.qcow2"
                vir_cpu=4  # 设置为4核
                vir_mem=20971520 #设置内存为20G
                vir_disk=20 #设置为磁盘200G盘
                vir_attach_disk=200 # 设置附加盘的大小
                check
                create_disk
                conf_xml
                start_vir
                attach_disk
                create_vir_log
            ;;
            *) echo "输入编号(1-4)";;
        esac
    }
    main
    

    四、挂载磁盘多种方式

    扩展对象为: 虚拟机

    4.1 扩容现有的磁盘

    • 这种方式只能增加不能缩小
    • 需要先把虚拟机关闭。(注意)
    • 宿主机操作

      [root@djx-kvm-123456-test opt]# virsh  shutdown   djx-mysql-djxmysq-test
      [root@djx-kvm-123456-test opt]# qemu-img info /home/kvm/data/djx-mysql-djxmysq-test.qcow2
      image: /home/kvm/data/djx-mysql-djxmysq-test.qcow2
      file format: qcow2
      virtual size: 100G (107374182400 bytes)
      disk size: 131M
      cluster_size: 65536
      backing file: /home/kvm/data/base-image.qcow2
      Format specific information:
          compat: 1.1
          lazy refcounts: false
      [root@djx-kvm-af3r34t-test opt]# qemu-img resize /home/kvm/data/djx-mysql-djxmysq-test.qcow2 +3G
      Image resized.
      [root@djx-kvm-af3r34t-test opt]# qemu-img info /home/kvm/data/djx-mysql-djxmysq-test.qcow2
      image: /home/kvm/data/djx-mysql-djxmysq-test.qcow2
      file format: qcow2
      virtual size: 103G (110595407872 bytes)
      disk size: 254M
      cluster_size: 65536
      backing file: /home/kvm/data/base-image.qcow2
      Format specific information:
          compat: 1.1
          lazy refcounts: false
      
      
    • 虚拟机操作

    虚拟机可以进行两种类型的操作:(以下两步是冲突的,只能2选1)
    1、是使用新增空间扩容现有的磁盘
    2、是使用新增空间创建新的分区

    • 使用新增空间扩容现有的磁盘

      # 内核版本大于3.6.0
      
      # 安装 growpart或者xfsprogs扩容格式化工具
      yum install cloud-utils-growpart
      yum install xfsprogs
      # 运行fdisk -l命令查看现有云盘大小
      [root@localhost ~]# df -h 
      Filesystem      Size  Used Avail Use% Mounted on
      devtmpfs        3.9G     0  3.9G   0% /dev
      tmpfs           3.9G     0  3.9G   0% /dev/shm
      tmpfs           3.9G  8.5M  3.9G   1% /run
      tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
      /dev/vda2        50G  1.2G   49G   3% /
      /dev/vda1       497M  134M  363M  27% /boot
      tmpfs           783M     0  783M   0% /run/user/0
      [root@localhost ~]# fdisk  -l 
      
      Disk /dev/vda: 107.4 GB, 107374182400 bytes, 209715200 sectors
      Units = sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disk label type: dos
      Disk identifier: 0x000a6596
      
         Device Boot      Start         End      Blocks   Id  System
      /dev/vda1   *        2048     1026047      512000   83  Linux
      /dev/vda2         1026048   104857599    51915776   83  Linux
      # 查看分区的文件系统类型
      [root@localhost ~]# blkid  /dev/vda2 
      /dev/vda2: UUID="be6f97e3-13c3-46ea-9694-78a575272bb8" TYPE="xfs" 
      # 调用growpart为需要扩容的云盘和对应的第几个分区扩容
      [root@localhost ~]# growpart   /dev/vda 2
      CHANGED: partition=2 start=1026048 old: size=103831552 end=104857600 new: size=208689119 end=209715167
      # 运行xfs_growfs <PartitionName>命令调用xfs_growfs扩容文件系统。 
      #  xfs 文件系统使用xfs_growfs   ,ext4 文件系统使用 resize2fs 
      [root@localhost ~]# xfs_growfs  /dev/vda2
      meta-data=/dev/vda2              isize=512    agcount=4, agsize=3244736 blks
               =                       sectsz=512   attr=2, projid32bit=1
               =                       crc=1        finobt=0 spinodes=0
      data     =                       bsize=4096   blocks=12978944, imaxpct=25
               =                       sunit=0      swidth=0 blks
      naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
      log      =internal               bsize=4096   blocks=6337, version=2
               =                       sectsz=512   sunit=0 blks, lazy-count=1
      realtime =none                   extsz=4096   blocks=0, rtextents=0
      data blocks changed from 12978944 to 26086139
      
      
    • 使用新增空间创建新的分区(与上一步冲突的)

      [root@localhost ~]# fdisk  /dev/vda 
      Welcome to fdisk (util-linux 2.23.2).
      
      Changes will remain in memory only, until you decide to write them.
      Be careful before using the write command.
      
      
      Command (m for help): m
      Command action
         a   toggle a bootable flag
         b   edit bsd disklabel
         c   toggle the dos compatibility flag
         d   delete a partition
         g   create a new empty GPT partition table
         G   create an IRIX (SGI) partition table
         l   list known partition types
         m   print this menu
         n   add a new partition
         o   create a new empty DOS partition table
         p   print the partition table
         q   quit without saving changes
         s   create a new empty Sun disklabel
         t   change a partition's system id
         u   change display/entry units
         v   verify the partition table
         w   write table to disk and exit
         x   extra functionality (experts only)
      
      Command (m for help): n
      Partition type:
         p   primary (2 primary, 0 extended, 2 free)
         e   extended
      Select (default p): p
      Partition number (3,4, default 3):  
      First sector (104857600-209715199, default 104857600): 
      Using default value 104857600
      Last sector, +sectors or +size{K,M,G} (104857600-209715199, default 209715199): 
      Using default value 209715199
      Partition 3 of type Linux and of size 50 GiB is set
      
      Command (m for help): w
      The partition table has been altered!
      
      Calling ioctl() to re-read partition table.
      
      WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
      The kernel still uses the old table. The new table will be used at
      the next reboot or after you run partprobe(8) or kpartx(8)
      Syncing disks.
      [root@localhost ~]# fdisk  -l
      
      Disk /dev/vda: 107.4 GB, 107374182400 bytes, 209715200 sectors
      Units = sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disk label type: dos
      Disk identifier: 0x000a6596
      
         Device Boot      Start         End      Blocks   Id  System
      /dev/vda1   *        2048     1026047      512000   83  Linux
      /dev/vda2         1026048   104857599    51915776   83  Linux
      /dev/vda3       104857600   209715199    52428800   83  Linux
      # 然后需要重启机器。不然直接挂载的话是挂载不了的。
      # 格式化磁盘
      [root@localhost ~]mkfs.xfs  /dev/vda3 
      [root@localhost ~]# mount  /dev/vda3  /home
      # 如果没有重启 ,报错 mount: special device /dev/vda3 does not exist
      
      # 还需要设置开动挂载
      

    4.2 添加新的磁盘

    • 宿主机操作

      [root@k5-m2 ~]# qemu-img create -f qcow2  /home/kvm/data/djx-biz-djx1234-dev-2.qcow2  10G
      Formatting '/home/kvm/data/djx-biz-djx1234-dev-2.qcow2', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off
      [root@k5-m2 ~]# virsh attach-disk djx-biz-djx1234-dev  /home/kvm/data/djx-biz-djx1234-dev-2.qcow2 vdb --cache writeback --subdriver qcow2 --persistent
      Disk attached successfully
      
      [root@djx-kvm-af3r34t-test data]# virsh domblklist  djx-biz-djx1234-dev
      Target     Source
      ------------------------------------------------
      vda        /home/kvm/data/djx-biz-djx1234-dev.qcow2
      vdb        /home/kvm/data/djx-biz-djx1234-dev-2.qcow2
      hda        -
      
      
    • 虚拟机操作

      [root@localhost ~]# fdisk  -l 
      
      Disk /dev/vda: 85.9 GB, 85899345920 bytes, 167772160 sectors
      Units = sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disk label type: dos
      Disk identifier: 0x000a6596
      
         Device Boot      Start         End      Blocks   Id  System
      /dev/vda1   *        2048     1026047      512000   83  Linux
      /dev/vda2         1026048   104857599    51915776   83  Linux
      /dev/vda3       104857600   167772126    31457263+  83  Linux
      
      Disk /dev/vdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
      Units = sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      # 我们可以在系统盘这边看到我们新增加的磁盘,然后我们可以对该磁盘进行初始化和分区,并挂载使用了,注意在挂载的时候需要注意设置开机自动挂载。
      具体操作见 7.1 虚拟机操作-使用新增空间创建新的分区
      

    五、常用操作命令

    • 查看虚拟机对应的ip

      virsh list --title
      
    • 登录虚拟机

      • 通过 console

        virsh console djx-biz-qawsed4-test
        
      • 通过 ssh

      • 通过 vnc

        vnc 端口为随机。通过查找对应的进程来获取。

    • virsh list [--all] #查看所有KVM虚拟机

    • virsh dominfo name # 查看虚拟机 CPU/内存的使用率

    • virsh start name #启动KVM虚拟机

    • virsh shutdown name #正常关闭KVM虚拟机、基本是关不掉的

    • virsh autostart name # 设置开机自启

    • virsh autostart –disable name # 关闭开机自启

    • virsh destroy name #强制关闭KVM虚拟机(类似于直接断电)

    • virsh suspend name #挂起KVM虚拟机

    • virsh resume name #恢复挂起的KVM虚拟机

    • virsh dumpxml name #查看KVM虚拟机配置文件

    • virsh edit name #编辑KVM虚拟机的xml配置文件

    • virsh undefine name #彻底删除KVM虚拟机,不可逆,如果想找回来,需要备份/etc/libvirt/qemu的xml文件

    • virsh snapshot-create name #创建快照

    • virsh snapshot-delete name --current/--snapshotname #删除快照

    • virsh snapshot-dumpxml name #导出XML

    • virsh snapshot-list name #查看快照

  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/operationhome/p/12813437.html
Copyright © 2020-2023  润新知