KVM#KVM自动化管理系统

    科技2022-08-29  98

    KVM虚拟机自动化管理系统脚本

    #!/bin/bash # Author:kakaops # Email:17852032278@139.com source kvm-func.sh clear menu while true do clear && menu read -p ">>:" keyword clear && menu case $keyword in 1|a) vmall ;; 2|b) baseos ;; 3|c) copyvm ;; 4|d) diskadd ;; 5|e) memadd ;; 6|f) clone ;; 7|g) guazai ;; 8|h) juan ;; 9|i) snapshot ;; 10|g) net_bri ;; q|Q) echo -e "\e[1;34m退出=============\e[0m" exit ;; *) echo -e "\e[1;35m输入无效,请重新输入\e[0m" ;; esac done

    KVM虚拟机自动化管理系统函数库

    #!/bin/bash # Author:kakaops # Email:17852032278@139.com # 一级菜单 function menu(){ cat<<! 欢迎使用kvm虚拟机管理系统 =================================================================================== 1|a) 查看正在运行的虚拟机和全部虚拟机 2|b) 虚拟机基本管理命令 3|c) 快速创建一个虚拟机(请先确保已   4|d) 给指定的虚拟机添加指定容量的硬盘 经在kvm中安装了一个虚拟机模板) 5|e) 给指定的虚拟机添加制定容量的mem内存  6|f) 虚拟机的快速克隆 7|g) 虚拟机挂载到主机            8|h) 虚拟机创建存储卷 9|i) 创建虚拟机快照i 10|g) 配置桥接网卡 q|Q) 退出kvm虚拟机管理系统 =================================================================================== ! } # 查看正在运行的虚拟机和全部虚拟机 function vmall(){ echo -e "\e[32;1m正在运行的虚拟机\e[0m" echo "$(virsh list)" echo -e "\e[34;1m全部的虚拟机\e[0m" echo "$(virsh list --all)" echo "10s后自动返回到主菜单" sleep 10 } # 请选择虚拟机基本管理命令 function menu2(){ cat<<! =================================================================  1、启动虚拟机   2、暂停虚拟机   3、恢复虚拟机  4、关闭虚拟机     5、强制断电关机  6、重启虚拟机  7、强制断电重启    8、删除虚拟机   9、设置开机自启  10、关闭开机自启 11、查看运行虚拟机ip 12 、查看域磁盘信息 13、删除域磁盘   Q|q、退出基本命令模块 连续输入两次q,返回主菜单 ================================================================= ! } # 通过循环读取文件。可以实现echo多行加颜色 function readline(){ while read line do echo -e "\e[31;1m${line}\e[0m" done < a.txt rm -rf a.txt } function baseos(){ while true do menu2 echo "您可以进行的操作的虚拟机:" echo "$(virsh list --all)" read -p "输入要操作的虚拟机名>>:" vmname read -p "输入要进行的操作>>:" number case $number in 1) virsh start "${vmname}" &> a.txt readline ;; 2) virsh suspend "${vmname}" &> a.txt readline ;; 3) virsh resume "${vmname}" &>a.txt readline ;; 4) virsh shutdown "${vmname}" &>a.txt readline sleep 10 ;; 5) virsh destroy "${vmname}" &>a.txt readline ;; 6) virsh reboot "${vmname}" &>a.txt readline ;; 7) virsh reset "${vmname}" &>a.txt readline sleep 10 ;; 8) virsh undefine "${vmname}" &>a.txt readline ;; 9) virsh autostart "${vmname}" &>a.txt readline ;; 10) virsh autostart --disable "${vmname}" &>a.txt readline ;; 11) virsh domifaddr "${vmname}" &>a.txt readline ;; 12) virsh domblklist "${vmname}" &>a.txt readline ;; 13) virsh domblklist "${vmname}" while true do read -p "输入要删除的磁盘名>>:" diskdel virsh domblklist sunlizhen |awk '{print $1}' >a.txt grep -w "${diskdel}" a.txt &>/dev/null if [ $? -eq 0 ];then rm -rf a.txt break else echo "磁盘不存在,请重新输入" fi done virsh detach-disk "${vmname}" "${diskdel}" --persistent virsh domblklist "${vmname}" echo -e "\e[33;1m磁盘"${diskdel}"已经成功从域"${vmname}"删除\e[0m" ;; q|Q) clear && menu break ;; *) echo -e "\e[31;1m输入无效,请重新输入\e[0m" ;; esac done } # 镜像模板快速创建虚拟机,自动生成uuid和mac地址,用强大的sed修改配置文件 function copyvm(){ echo "您现有的虚拟机模板为:" echo "$(virsh list --all)" virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt while true do read -p "请输入模板虚拟机名称>>:" old read -p "请输入要创建的虚拟机名称>>:" new grep -w "${old}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "$old" ] && [ "$new" ];then rm -rf b.txt break else echo "请输入已经存在的虚拟机模板,且输入不能为空,请重新输入" fi done echo "正在进行镜像模板复制" cp /etc/libvirt/qemu/"${old}".xml /etc/libvirt/qemu/"${new}".xml cp /var/lib/libvirt/images/"${old}".qcow2 /var/lib/libvirt/images/"${new}".qcow2 && \ echo "镜像模板复制成功,正在修改新虚拟机的配置文件" sleep 1 cd /etc/libvirt/qemu sed -ri "s#<name>"$old"</name>#<name>$new</name>#" "${new}".xml sed -ri "s#<uuid>[[:alnum:]-]*</uuid>#<uuid>$(uuidgen)</uuid>#" "${new}".xml sed -ri "s#(<source file='/var/lib/libvirt/images/)"${old}"(.qcow2')#\1"${new}"\2#" "${new}".xml n=$(echo -n 52:54:00; dd bs=1 count=3 if=/dev/random 2>/dev/null | hexdump -v -e '/1 ":X"') sed -ri "s#<mac address='52:54:00:[[:alnum:]:]*'/>#<mac address='"$n"'/>#" "${new}".xml virsh define "${new}".xml && systemctl restart libvirtd && \ echo "已经成功创建新虚拟机${new}" && virsh list --all grep "net.ipv4.ip_forward = 1/" /etc/sysctl.conf if [ $? -eq 0 ];then pass else sed -ri '$ a net.ipv4.ip_forward = 1' /etc/sysctl.conf fi } # 动态给指定虚拟机添加指定容量的磁盘,创建磁盘模板,筛选未定义的磁盘名 function diskadd(){ echo "请选择已经存在的虚拟机添加磁盘" echo "$(virsh list --all)" read -p "请输入需要添加磁盘的虚拟机名称>>:" vm_name read -p "请输入需要添加磁盘的容量,例如2G>>:" disk_size virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt while true do grep -w "${vm_name}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "${vm_name}" ];then break else echo "输入的虚拟机不存在,请重新输入" read -p "请输入需要添加磁盘的虚拟机名称>>:" vm_name fi done while true do if [[ ! "${disk_size}" =~ G$ ]] || [[ ! "${disk_size::-1}" =~ ^[0-9]+$ ]];then echo "输入的容量格式不符合要求,请重新输入,例如2G" read -p "请输入需要添加磁盘的容量,例如2G>>:" disk_size else break fi done cd /var/lib/libvirt/images/ mkdir "${vm_name}".disk &>/dev/null qemu-img create -f qcow2 "${vm_name}".disk/"${vm_name}".qcow2 "${disk_size}" >/dev/null if [ -e disk_mod.xml ];then rm -rf disk_mod.xml fi cat >>disk_mod.xml<<! echo "<disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='writeback' io='threads'/> <source file='"\${vdisk_path}"'/> <target dev='"\${device_name}"' bus='virtio'/> </disk>" ! #cat disk_mod.xml virsh domblklist "${vm_name}" |awk -F "(vd)" '/\// {print $2}'|awk '{print $1}' >read.txt declare -A disk_arr while read line do disk_arr[$line]=1 done < read.txt for i in {a..z} do w=${disk_arr[$i]} echo $w if [ -z "$w" ];then disk_name=vd$i echo -e "\e[33;1m添加的磁盘名称是$disk_name\e[0m" break fi done vdisk_path=/var/lib/libvirt/images/"${vm_name}".disk/"${vm_name}".qcow2 device_name="${disk_name}" #cat disk_mod.xml echo "${vdisk_path}" echo "${device_name}" source disk_mod.xml > disk.xml cat disk.xml virsh attach-device "$vm_name" disk.xml --persistent virsh domblklist "${vm_name}" echo -e "\e[32;1m已经成功为虚拟机"${vm_name}"添加大小为"${disk_size}"的磁盘"${device_name}"\e[0m" echo -e "\e[32;1m"${vm_name}"的所有新添加的磁盘为您存放在"${vdisk_path}"\e[0m" rm -rf b.txt rm -rf read.txt rm -rf disk_mod.xml rm -rf disk.xml sleep 8 } function memadd(){ echo "请选择已经存在的虚拟机添加内存mem" echo "$(virsh list --all)" read -p "请输入需要添加内存mem的虚拟机名称>>:" vm_name virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt while true do grep -w "${vm_name}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "${vm_name}" ];then rm -rf b.txt break else echo "您输入的虚拟机不存在,请重新输入" read -p "请输入需要添加内存mem的虚拟机名称>>:" vm_name fi done read -p " 是否为虚拟机"${vm_name}"重新设定最大内存(Y|N),如果您选择同意Y,将会关闭此虚拟机,设置内存完成后,将会为您重新开启此虚拟机,请慎重修改此虚拟机最大内存,如果分配内存过大,将会导致此虚拟机无法开机,如果您选择N,不同意关闭此虚拟机,会为您在线添加内存mem>>:" chose while true do case $chose in Y) read -p "请输入需要添加内存mem的容量,例如2G>>:" disk_size while true do if [[ ! "${disk_size}" =~ G$ ]] || [[ ! "${disk_size::-1}" =~ ^[0-9]+$ ]];then echo "输入的容量格式不符合要求,请重新输入,例如2G" read -p "请输入需要添加磁盘的容量,例如2G>>:" disk_size else break fi done virsh destroy "${vm_name}" &>/dev/null virsh setmaxmem "${vm_name}" "${disk_size}" --config virsh start "${vm_name}" >a.txt readline break ;; N) read -p "请输入需要添加内存mem的容量,例如2G>>:" disk_size while true do if [[ ! "${disk_size}" =~ G$ ]] || [[ ! "${disk_size::-1}" =~ ^[0-9]+$ ]];then echo "输入的容量格式不符合要求,请重新输入,例如2G" read -p "请输入需要添加磁盘的容量,例如2G>>:" disk_size else break fi done virsh setmem sunlizhen "$disk_size" break ;; *) echo "输入无效,请重新输入" read -p "是否为"${vm_name}"重新设定最大内存(Y|N),如果您选择同意Y,将会关闭虚拟机"${vm_name}">>:" chose esac done echo -e "\e[32;1m域"${vm_name}"的当前信息\e[0m" virsh dominfo "${vm_name}" } #进行虚拟机的快速克隆 function clone(){ cat<<! 请选择克隆模式 1、快速克隆 2、自定义克隆 q、退出 ! while true do read -p ">>:" modd case $modd in 1) intname startlist virsh destroy "${vm_name}" &>/dev/null virt-clone -o "${vm_name}" --auto-clone if [ "$a" == 1 ];then virsh start "${vm_name}" &>/dev/null fi break ;; 2) intname read -p "请输入新的虚拟机名称>>:" newname while true do if [ "$newname" ];then read -p "请输入要用的磁盘镜像绝对路径,输入为空则用模板机的镜像卷,输入错误的路径会创建失败>>:" newfile if [ "$newfile" ];then startlist virsh destroy "${vm_name}" &>/dev/null virt-clone -o "${vm_name}" -n "${newname}" -f "${newfile}" if [ "$a" == 1 ];then virsh start "${vm_name}" &>/dev/null fi break else startlist virsh destroy "${vm_name}" &>/dev/null virt-clone -o "${vm_name}" -n "${newname}" --auto-clone if [ "$a" == 1 ];then virsh start "${vm_name}" &>/dev/null fi break fi fi done break ;; q) exit ;; *) echo "输入无效,请重新输入" ;; esac done virsh list --all >a.txt readline } function intname(){ echo "您可以选择的虚拟机模板有,正在运行的域不能进行克隆,如果您选择了正在运行的域,那么将会为您执行关机命令,克隆结束后会恢复其运行状态:" virsh list --all read -p "请输入需要进行克隆的模板机的虚拟机名称>>:" vm_name virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt while true do grep -w "${vm_name}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "${vm_name}" ];then rm -rf b.txt break else echo "您输入的虚拟机不存在,请重新输入" read -p "请输入需要进行克隆的模板机的虚拟机名称>>:" vm_name fi done } function startlist(){ virsh list |awk '{print $2}' >a.txt grep -w "${vm_name}" a.txt &>/dev/null if [ $? -eq 0 ];then a=1 fi } # 挂载指定虚拟机到真机指定目录 function guazai(){ virsh list --all read -p "请输入需要进行挂载的虚拟机名称,输入需要进行克隆的模板机的虚拟机名称,如果模板机处于运行状态会为您进行关机,挂载成功后会为您开启模板虚拟 机>>:" vm_name virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt while true do grep -w "${vm_name}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "${vm_name}" ];then rm -rf b.txt break else echo "您输入的虚拟机不存在,请重新输入" read -p "请输入需要进行克隆的模板机的虚拟机名称,如果模板机处于运行状态会为您进行关机,挂载成功后会为您开启模板虚拟机>>:" vm_name fi done while true do read -p "请输入宿主机被挂载目录绝对路径,保证路径格式正确,建议输入一个未创建的空目录路径(例如:如果您输入错误格式的目录路径/mnt///gua/,系统仍然会为你创建目录/mnt/gua/,但是会造成磁盘挂载失败)>>:" dir ls "$dir" &>/dev/null if [ $? -eq 0 ];then break else n=${dir:0:1} if [[ "$n" =~ "/" ]];then mkdir -p "$dir" break else echo "您输入的格式不正确,请重新输入" fi fi done startlist virsh destroy "${vm_name}" >/dev/null guestmount -d "${vm_name}" -m /dev/centos/root --rw "${dir}" if [ "$a" == 1 ];then virsh start "${vm_name}" >/dev/null fi echo -e "\e[34;1m虚拟机挂载成功\e[0m" ls "${dir}" sleep 5 } # 构建kvm存储池 function juan(){ function poolcreate(){ while true do while true do read -p "输要构建的存储池的名称>>:" poolname if [ "$poolname" ];then break else echo "输入不能为空" continue fi done while true do read -p "请输入用于构建存储池的目录路径>>:" dir ls "$dir" &>/dev/null if [ $? -eq 0 ];then break else n=${dir:0:1} if [[ "$n" =~ "/" ]];then mkdir -p "$dir" break else echo "您输入的格式不正确,请重新输入" fi fi done echo -e "\e[35;1m正在为您定义和构建存储池\e[0m" &&\ virsh pool-define-as "$poolname" --type dir --target "$dir" &&\ virsh pool-build "$poolname" if [ $? -eq 0 ];then virsh pool-list --all echo -e "\e[35;1m存储池构建成功,您可以接着对存储池进行其他操作\e[0m" break else continue fi done } poolcreate function poollist(){ cat<< ! 1) 激活已经定义的存储池 2) 为存储池设置开机自启 3) 取消存储池的开机自启 4) 在存储池中创建qcow2格式的虚拟镜像卷 5) 在存储池中删除虚拟镜像卷 6) 取消激活存储池 7) 删除存储池目录 8) 取消定义存储池 9) 返回主菜单 ! } function dowhat(){ while true do echo "请输入您要进行操作的存储池名称" read -p ">>:" vmname virsh pool-list --all |awk '{print $1}' >b.txt grep -w "$vmname" b.txt &>/dev/null if [ $? -eq 0 ] && [ "$vmname" ];then rm -rf b.txt break else echo ”输入的存储池不存在,或者不符合要求“ continue fi done } function juan(){ while true do echo "请输入虚拟卷名称,不用写扩展名" read -p ">>:" juanname if [ $juanname ];then break else echo "输入错误,请重新输入" break fi done } function size(){ while true do echo "输入要创建的虚拟卷的大小,比如2G:" read -p ">>:" disk_size if [[ ! "${disk_size}" =~ G$ ]] || [[ ! "${disk_size::-1}" =~ ^[0-9]+$ ]];then echo "输入错误,请重新输入" continue else break fi done } function diroo(){ while true do read -p "请输入要删除的存储池目录路径>>:" dir ls "$dir" &>/dev/null if [ $? -eq 0 ];then break else n=${dir:0:1} if [[ "$n" =~ "/" ]];then mkdir -p "$dir" break else echo "您输入的格式不正确,请重新输入" fi fi done } function koko(){ while true do virsh pool-list --all poollist dowhat echo "请输入要进行的操作代号" read -p ">>:" num case $num in 1) virsh pool-start "$vmname" ;; 2) virsh pool-autostart "$vmname" ;; 3) virsh pool-autostart --disable "$vmname" ;; 4) juan size virsh vol-create-as "$vmname" "${juanname}".qcow2 "$disk_size" --format qcow2 ;; 5) juan virsh vol-delete --pool "$vmname" "${juanname}".qcow2 ;; 6) virsh pool-destroy "$vmname" ;; 7) diroo virsh pool-delete "$dir" ;; 8) virsh pool-undefine "$vmname" ;; 9) break ;; *) echo "输入错误,请重新输入" ;; esac done } function cunchujuan(){ while true do cat<<! y) 继续对存储池进行其他操作 n) 不进行操作,继续进行存储池构建 q) 返回主菜单 ! read -p ">>:" num case $num in y) koko ;; n) poolcreate ;; q) break ;; *) echo "输入无效,请重新输入" esac done } cunchujuan } # 创建虚拟机快照 function snapmenu(){ cat<<! 1)、创建快照 2)、查看快照 3)、恢复快照 4)、删除快照 5)、回主菜单 ! } function snapshot_create(){ while true do virsh list --all virsh list --all |awk -F'[ ]*' '{print $3}' >b.txt read -p "输入虚拟机名称>>:" vm_name grep -w "${vm_name}" b.txt &>/dev/null if [ $? -eq 0 ] && [ "${vm_name}" ];then rm -rf b.txt break else echo "您输入的虚拟机不存在,请重新输入" continue fi done } function no_name(){ while true do virsh snapshot-list "$vm_name" virsh snapshot-list "$vm_name" >b.txt read -p "输入快照名称>>:" snapname grep -w "$snapname" b.txt if [ $? -ne 0 ] && [ "$snapname" ];then rm -rf b.txt break else echo "输入错误,请重新输入" continue fi done } function yes_name(){ while true do virsh snapshot-list "$vm_name" virsh snapshot-list "$vm_name" >b.txt read -p "输入快照名称>>:" snapname grep -w "$snapname" b.txt if [ $? -eq 0 ] && [ "$snapname" ];then rm -rf b.txt break else echo "输入错误,请重新输入" continue fi done } function snapshot(){ while true do snapmenu read -p ">>:" num case $num in 1) snapshot_create no_name virsh snapshot-create-as "${vm_name}" "$snapname" virsh snapshot-list "$vm_name" ;; 2) snapshot_create virsh snapshot-list "$vm_name" ;; 3) snapshot_create yes_name virsh shutdown "$vm_name" &>>/dev/null virsh snapshot-revert "$vm_name" "$snapname" virsh snapshot-list "$vm_name" ;; 4) snapshot_create yes_name virsh snapshot-delete --snapshotname "$snapname" "$vm_name" virsh snapshot-list "$vm_name" ;; 5) break ;; *) echo "输入错误,请重新输入" ;; esac done } # 配置一个桥接网络 function add_bri(){ cd /etc/sysconfig/network-scripts/ cat >>bri_mode<<! echo "TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT="yes" BOOTPROTO=static IPADDR="\$ip_addr" GATEWAY="\$gate_addr" NETMASK=255.255.255.0 DNS1=114.114.114.114 DNS2=8.8.8.8" ! ip_addr=$(ip a|grep "scope global"|grep "dynamic"|awk -F'[/ ]+' '{print $3}') gate=$(echo "$ip_addr"|awk -F'.' 'BEGIN{OFS="."} {print $1,$2,$3}') gate_addr=${gate}.1 source bri_mode > ifcfg-br0 card=$(ip a|grep ^2|awk -F'[ : ]' '{print $3}') cp ifcfg-${card}{,.back} cat >>ifcfg-"$card"<<! NAME=$card DEVICE=$card ONBOOT=yes BRIDGE=br0 ! systemctl restart network systemctl restart libvirtd } function del_bir(){ cd /etc/sysconfig/network-scripts/ rm -rvf ifcfg-br0 mv ifcfg-enp0s25{,.bak} mv ifcfg-enp0s25{.back,} systemctl restart libvirtd systemctl restart network } function net_bri(){ while true do cat<<! 1) 配置桥接网卡   2) 删除桥接网卡 q) 回主菜单 ! read -p ">>:" num case $num in 1) add_bri ;; 2) del_bir ;; q) break ;; *) echo "输入无效,请重新输入" ;; esac done }
    Processed: 0.009, SQL: 9