date: 2021-04-21title: kvm部署及维护 #标题
tags: kvm #标签
categories: kvm # 分类

最近打算重新学习下kvm,毕竟之前学习,有图形化的操作,不贴合实际应用场景。

环境准备

一台机器(磁盘、CPU、内存最好大些)用来做宿主机,如果你使用虚机来做测试环境,那么需要保证处理器勾选如下复选框:

kvm部署及维护 - 图1

检测CPU是否支持KVM

KVM 是基于 x86 虚拟化扩展(Intel VT 或者 AMD-V) 技术的虚拟机软件,所以查看 CPU 是否支持 VT 技术,就可以判断是否支持KVM。有返回结果,如果结果中有vmx(Intel)或svm(AMD)字样,就说明CPU的支持的。

  1. $ egrep 'vmx|svm' /proc/cpuinfo | wc -l
  2. 4

配置KVM基础环境

安装基础工具

  1. $ yum -y install qemu-kvm python-virtinst libvirt libvirt-python \
  2. virt-manager libguestfs-tools bridge-utils virt-install
  3. $ reboot # 安装完成后,最好重启操作系统
  4. $ lsmod | grep kvm # 重启后确认kvm模块已加载
  5. kvm_intel 183621 0
  6. kvm 586948 1 kvm_intel
  7. irqbypass 13503 1 kvm

设置libvirtd为开机自启

  1. $ systemctl start libvirtd && systemctl enable libvirtd

创建相关目录,存储镜像文件以及虚拟机磁盘文件

  1. $ mkdir /data/kvm/{disk,iso} -p
  2. # 下载镜像
  3. $ wget https://mirrors.sohu.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso \
  4. -O /data/kvm/iso/CentOS-7-x86_64-DVD-2009.iso

定义ks应答文件

  1. # 安装nginx
  2. $ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
  3. $ yum -y install nginx
  4. # 定义应答文件
  5. $ vim /usr/share/nginx/html/ks.cfg # 文件内容如下
  6. #version=DEVEL
  7. # System authorization information
  8. auth --enableshadow --passalgo=sha512
  9. # Use CDROM installation media
  10. cdrom
  11. # Use graphical install
  12. text
  13. # Run the Setup Agent on first boot
  14. firstboot --disable
  15. #ignoredisk --only-use=sda
  16. # Keyboard layouts
  17. keyboard --vckeymap=us --xlayouts='us'
  18. # System language
  19. lang zh_CN.UTF-8
  20. # Network information
  21. network --hostname=localhost.chinadaas
  22. # Root password
  23. # root密码生成方式:$ openssl passwd -1 "123.com"
  24. rootpw --iscrypted $1$Lo9vO2wd$ir6LWYaZ6GrhQLuUxgc2T1
  25. #firewalld disabled
  26. firewall --disabled
  27. #SELinux disabled
  28. selinux --disabled
  29. # System services
  30. services --disabled="NetworkManager,abrtd"
  31. # System timezone
  32. timezone Asia/Shanghai
  33. # System bootloader configuration
  34. #bootloader
  35. # 自动分区方案
  36. # bootloader --location=mbr --boot-drive=vda
  37. # autopart --type=lvm
  38. # clearpart --none --initlabel
  39. # 手动分区方案
  40. bootloader --location=mbr
  41. # Partition clearing information
  42. clearpart --all
  43. part /boot --fstype="xfs" --size=1024
  44. part pv.1 --fstype="lvmpv" --grow --size=1
  45. #分配所有空间给pv1 size设为1 加 --grow
  46. volgroup centos pv.1
  47. logvol / --fstype="xfs" --size=17408 --name=root --vgname=centos
  48. logvol /home --fstype="xfs" --size=10240 --name=home --vgname=centos
  49. logvol swap --fstype="swap" --size=2040 --name=swap --vgname=centos
  50. # 上述分区大小单位为 MB,最好指定的分区大小总空间,比实际磁盘空间小10M左右,否则可能空间不够。
  51. %packages
  52. @^infrastructure-server-environment
  53. @base
  54. @core
  55. %end
  56. %post
  57. cat > /etc/security/limits.conf << EOF
  58. * - nofile 650000
  59. * - memlock unlimited
  60. * - stack 655360
  61. * - nproc unlimited
  62. EOF
  63. #set ssh
  64. sed -i 's/^GSSAPIAuthentication yes$/GSSAPIAuthentication no/' /etc/ssh/sshd_config
  65. sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
  66. service sshd restart
  67. #define the backspace button can erase the last character typed
  68. echo 'stty erase ^H' >> /etc/profile
  69. echo "syntax on" >> /root/.vimrc
  70. cat > /etc/sysctl.conf << EOF
  71. kernel.sysrq = 0
  72. kernel.core_uses_pid = 1
  73. fs.file-max=655360
  74. kernel.msgmnb = 65536
  75. kernel.msgmax = 65536
  76. kernel.shmmax = 68719476736
  77. kernel.shmall = 4294967296
  78. kernel.pid_max = 655360
  79. net.ipv4.tcp_tw_reuse = 1
  80. net.ipv4.tcp_tw_recycle = 0
  81. net.ipv4.tcp_max_tw_buckets = 262144
  82. net.ipv4.tcp_fin_timeout = 30
  83. net.ipv4.tcp_timestamps = 0
  84. net.ipv4.tcp_sack = 1
  85. net.ipv4.tcp_window_scaling = 1
  86. net.ipv4.tcp_ecn = 0
  87. net.ipv4.tcp_keepalive_time = 600
  88. net.ipv4.tcp_keepalive_intvl = 30
  89. net.ipv4.tcp_keepalive_probes = 3
  90. net.ipv4.tcp_max_orphans = 655360
  91. net.ipv4.tcp_max_syn_backlog = 262144
  92. net.ipv4.tcp_mem = 65536 131072 262144
  93. net.ipv4.udp_mem = 65536 131072 262144
  94. net.ipv4.tcp_rmem = 4096 87380 16777216
  95. net.ipv4.tcp_wmem = 4096 16384 16777216
  96. net.ipv4.ip_local_port_range = 1024 65535
  97. net.ipv4.route.gc_timeout = 100
  98. # 禁止icmp重定向报文
  99. net.ipv4.conf.all.accept_redirects = 0
  100. # 禁止icmp源路由
  101. net.ipv4.conf.all.accept_source_route = 0
  102. net.core.somaxconn = 65535
  103. net.core.rmem_default = 8388608
  104. net.core.wmem_default = 8388608
  105. net.core.rmem_max = 16777216
  106. net.core.wmem_max = 16777216
  107. net.core.netdev_max_backlog = 262144
  108. vm.swappiness = 3
  109. vm.overcommit_memory = 1
  110. vm.max_map_count = 262144
  111. EOF
  112. # 终端美化
  113. echo "PS1='[\[\e[36m\]\#::\[\e[31m\]\u@\[\e[32m\]\h\[\e[36m\]::\w]\\$
  114. >>> \[\e[m\]'" >> /etc/profile
  115. # 关闭发邮件
  116. echo 'unset MAILCHECK' >> /etc/profile
  117. #reboot
  118. reboot
  119. %end
  120. %addon com_redhat_kdump --disable --reserve-mb='auto'
  121. %end
  122. # 启动nginx
  123. $ nginx

KVM网络配置

kvm虚拟机的网络配置有两种模式:桥接模式和NAT模式。两种模式区别如下:

  • NAT模式:也是用户模式,数据包由NAT方式通过主机的接口进行传送,可以访问公网,但是无法从外部访问虚拟机网络,所以一般不会用到。
  • Bridge:也就是桥接模式,这种模式允许虚拟机像一个独立的主机一样拥有网络,外部的机器可以直接访问到虚拟机内部,但需要网卡支持,一般有线网卡都支持。

NAT模式配置

nat模式配置比较简单,只需要在创建虚机时,指定--network network=default,表示使用默认网络即可,这里就不多写了,(它是借助KVM服务器的防火墙规则及IPtables规则来实现的,关闭KVM服务器的防火墙不会影响虚拟机ping外网,但是其iptables的默认配置必须存在,否则,虚拟机无法ping通外网)。

Bridge模式配置

停止网络服务
  1. $ systemctl stop NetworkManager

启用桥接接口br0
  1. $ virsh iface-bridge ens33 br0 # ens33为我的网卡名称
  2. 使用附加设备 br0 生成桥接 ens33 失败 # 如果卡在这里,再敲下回车
  3. 已启动桥接接口 br0
  4. $ ls /etc/sysconfig/network-scripts/ | grep br0
  5. ifcfg-br0 # 确认有此文件

创建虚拟机

创建虚拟磁盘

  1. # 创建两个虚机磁盘
  2. $ qemu-img create -f qcow2 /data/kvm/disk/vm01.qcow2 30G
  3. $ qemu-img create -f qcow2 /data/kvm/disk/vm02.qcow2 30G

常用的虚拟磁盘有三种格式:

  • RAW:裸格式。占用空间较大,性能比较好,但不支持快照功能。
  • qcow:copy on write(写时复制机制)。
  • qcow2:占用空间较小(按需进行分配磁盘空间,不管文件系统是否支持),性能相比较RAW稍差,,但它支持快照、压缩、加密功能。

注:磁盘文件最好挂载在LVS卷上,以便可以动态扩展卷空间。

创建一个虚机

  1. # 使用nat网络的虚机
  2. $ virt-install --os-type=linux --os-variant centos7.0 --name web01 --ram 2048 --vcpus 2 \
  3. --disk /data/kvm/disk/vm01.qcow2 --location /data/kvm/iso/CentOS-7.6-x86_64-DVD-1810.iso \
  4. --network network=default --graphics vnc,listen=0.0.0.0 --console pty,target_type=serial \
  5. -x "ks=http://192.168.20.6/ks.cfg" --autostart --noautoconsole
  6. # 使用Bridge网络的虚机
  7. $ virt-install --os-type=linux --os-variant centos7.0 --name web02 --ram 2048 --vcpus 2 \
  8. --disk /data/kvm/disk/vm02.qcow2 --location /data/kvm/iso/CentOS-7.6-x86_64-DVD-1810.iso \
  9. --network bridge=br0 --graphics vnc,listen=0.0.0.0 --console pty,target_type=serial \
  10. -x "ks=http://192.168.20.6/ks.cfg" --autostart --noautoconsole
  11. # --network bridge=br0:也可以写为 --network type=bridge,source=br0
  12. # 如果要使用lvm的存储池创建存储卷并安装虚机,则需要用`--disk vol=test_lvm/lvvol1` 来指定磁盘文件
  13. # 其中`test_lvm`是存储池名称,`lvvol1`是存储卷名称。
  14. # 附加:创建一个win7机器(win7.img文件无需提前创建,size的单位为G)
  15. $ virt-install --name win7 --hvm --ram 3072 --vcpus 2 --disk path=/data/win7.img,size=30 \
  16. --network network:default --accelerate --vnc --vncport=8621 --vnclisten=0.0.0.0 \
  17. --cdrom /data/win7.iso -d

各个选项参数解释如下:
—os-type:指定虚机系统;
— name:指定虚机名称;
—ram:指定内存大小,单位为M;
—vcpus:指定cpu核心数;
—disk:指定磁盘文件;
—location:指定本地系统iso镜像文件;
—network:指定网络,default为默认的nat模式,外网需要通过配置iptables规则访问,如果配置了bridge模式,也可以指定为:—network bridge=br0;
—graphics:开启VNC登录;
—console:开启console登录方式;
-x:指定ks文件,避免交互式创建虚机;
—noautoconsole:指定不自动试图连接到客户机控制台。
-d:表示输出调试信息。

注:宿主机必须可以访问到 ks=http://192.168.20.6/ks.cfg 指定的链接地址,ks.cfg为centos应答文件,此文件内容在上面有展示。

在后续测试中发现,上面的ks.cfg文件不兼容所有centos 7 .x镜像,如果你遇到虚机无法正常安装的情况,需要自己琢磨下ks.cfg文件如何定义,或者说不使用自动应答文件(删除-x "ks=http://192.168.20.6/ks.cfg"启动虚机的这条配置),自己手动安装操作系统。

登录到虚机

通过VNC登录到虚机

自行下载vnc客户端,输入kvm虚机所在的宿主机IP:port 登录到kvm虚机中,如下:

  1. # 查询宿主机对应的虚机web01的端口
  2. $ virsh vncdisplay web01
  3. :0
  4. # 查看出的结果是“:0”,解释如下:
  5. # “:0”表示监听5900端口;
  6. # “:1”表示监听5901端口;
  7. # 以此类推......

输入ip+端口,登录到虚机:

kvm部署及维护 - 图2

输入用户名/密码,即可登录到虚机中,如下:

kvm部署及维护 - 图3

使用console登录到机器

如果你执行virsh console $kvm-name指令后,卡在那里不动,则需要先使用其他方式登录到虚机中,执行grubby --update-kernel=ALL --args=”console=ttyS0”指令,然后重启虚机,就可以通过console登录到虚机了,如下:

  1. $ grubby --update-kernel=ALL --args=”console=ttyS0
  2. $ reboot

当机器重启后,即可输入如下指令,在宿主机上登录到机器上,如下:

  1. $ virsh console web01 # 登录到web01
  2. 连接到域 web01
  3. 换码符为 ^] # 按下回车键
  4. CentOS Linux 7 (Core)
  5. Kernel 3.10.0-957.el7.x86_64 on an x86_64
  6. # 输入用户名密码
  7. localhost login: root
  8. Password:
  9. Last login: Sat Jan 30 15:52:22 on ttyS0
  10. [1::root@localhost::~]#
  11. >>> ping baidu.com # ping百度测试下是否可以访问外网
  12. PING baidu.com (39.156.69.79) 56(84) bytes of data.
  13. 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=127 time=10.2 ms
  14. 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=127 time=12.1 ms
  15. # 若要退出kvm虚机终端,请按 Ctrl + ] 组合键。

克隆虚机

通过命令方式克隆(源虚机需要在关机或挂起状态下操作)

  1. $ virsh list --all # 查看现有虚机
  2. Id 名称 状态
  3. ----------------------------------------------------
  4. 9 web01 running
  5. $ virsh console web01
  6. $ vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 删除UUID
  7. UUID="c32c8fae-52e7-497e-a0d0-f9658316490f"
  8. $ virsh shutdown web01 # 需要先将web01关机
  9. web01 被关闭
  10. # 根据web01克隆出来web02(-f 指定的是web02这个虚机的磁盘文件,此文件无需提前创建)
  11. $ virt-clone -o web01 -n web02 -f /data/kvm/disk/vm02.qcow2
  12. 正在分配 'vm02.qcow2' | 30 GB 00:00:36
  13. $ virsh list --all # 再次查看虚机列表
  14. Id 名称 状态
  15. ----------------------------------------------------
  16. - web01 关闭
  17. - web02 关闭
  18. $ for i in 1 2;do virsh start web0${i};done # 启动两个虚机

注:克隆出来的虚机,需要登录到虚机中,修改mac地址为实际的mac地址(可通过ip a 指令查询),否则克隆出来的虚机无法获取IP。

通过修改文件的方式克隆(无需关闭源虚机)

查看虚机列表
  1. $ virsh list --all
  2. Id 名称 状态
  3. ----------------------------------------------------
  4. 11 web01 running
  5. 12 web02 running

创建新的虚机配置文件
  1. $ virsh dumpxml web01 > /etc/libvirt/qemu/web03.xml

拷贝磁盘文件
  1. $ cd /data/kvm/disk/
  2. $ cp -a vm01.qcow2 vm03.qcow2

修改虚机配置文件
  1. $ vim /etc/libvirt/qemu/web03.xml
  2. ....... # 省略部分内容
  3. <domain type='kvm' id='11'>
  4. <name>web03</name> # 修改虚机名称
  5. ~~<uuid>1911922e-7273-4f82-bf13-ecb4d901236b</uuid>~~ # 删除此行配置
  6. ....... # 省略部分内容
  7. <devices>
  8. <emulator>/usr/libexec/qemu-kvm</emulator>
  9. <disk type='file' device='disk'>
  10. <driver name='qemu' type='qcow2'/>
  11. <source file='/data/kvm/disk/vm03.qcow2'/> # 指定刚刚拷贝的新的磁盘文件
  12. ....... # 省略部分内容
  13. <mac address='52:54:00:cb:18:f3'/> # 删除mac地址

定义虚机

  1. $ virsh define /etc/libvirt/qemu/web03.xml
  2. 定义域 web03(从 /etc/libvirt/qemu/web03.xml

确认虚机已克隆完成

  1. $ virsh list --all # 可以查看到新增的web03
  2. Id 名称 状态
  3. ----------------------------------------------------
  4. 11 web01 running
  5. 12 web02 running
  6. - web03 关闭

注:克隆出来的虚机,需要登录到虚机中,修改mac地址为实际的mac地址(可通过ip a 指令查询),否则克隆出来的虚机无法获取IP。

kvm维护指令

virsh指令

查看虚机列表
  1. $ virsh list --all # 如果只查看运行状态的虚机,则无需 --all
  2. Id 名称 状态
  3. ----------------------------------------------------
  4. 1 web01 running
  5. - web02 关闭
  6. - web03 关闭

启动虚拟机
  1. $ virsh start 虚机名称

重启虚机
  1. $ virsh reboot 虚机名称

设置所有虚机为开机自启
  1. $ for i in $(virsh list --all | awk '{if(NR>2) print $2}');do virsh autostart $i;done

启动所有虚机
  1. for i in $(virsh list --all | grep -v running | awk '{if(NR>2) print $2}');do virsh start $i;done

关闭虚机
  1. $ virsh shutdown 虚拟机名称 #正常的关闭虚拟机
  2. $ virsh destroy 虚拟机名称 #强制关闭虚拟机(类似于拔电源)

备份虚机配置文件
  1. $ virsh dumpxml 虚拟机名称 > /root/test01-dum.xml

删除虚机
  1. $ virsh undefine 虚拟机名称 #删除虚拟机(注意:取消定义之后,磁盘文件需要手动删除)

还原虚机
  1. $ virsh define 备份的.xml虚拟机文件

编辑虚机配置文件
  1. $ virsh edit 虚拟机名称

更改虚机名称
  1. $ virsh domrename 原名字 要更改的名字

查看虚机信息
  1. $ virsh dominfo 虚拟机名称

设置开机自启
  1. $ virsh autostart 虚拟机名称

取消开机自启
  1. $ virsh autostart --disable 虚拟机名称

查看虚机对应的VNC连接端口号

默认第一个端口号为:5900(用“:0”表示),以此类推

  1. $ virsh vncdisplay 虚拟机名称

挂起虚机
  1. $ virsh suspend 虚拟机名称

取消挂起虚机
  1. $ virsh resume 虚拟机名称

console登陆虚拟机
  1. $ virsh console 虚拟机名称

查看磁盘信息
  1. $ virsh domblklist web01
  2. 目标
  3. ------------------------------------------------
  4. vda /data/kvm/disk/vm01.qcow2
  5. hda -

将将test.raw磁盘格式raw转换为qcow2
  1. $ qemu-img convert -f raw -O qcow2 test.raw test.qcow2

克隆虚机
  1. $ virt-clone --auto-clone -o 源虚机 -n 新虚机

查看磁盘文件分区信息
  1. $ virt-filesystems --long --parts --blkdevs -h -a /data/kvm/disk/vm01.qcow2
  2. Name Type MBR Size Parent
  3. /dev/sda1 partition 83 1.0G /dev/sda
  4. /dev/sda2 partition 8e 29G /dev/sda
  5. /dev/sda device - 30G -

qemu-img指令

qemu-img是一个功能强大的磁盘镜像管理工具。

查看虚拟机的磁盘信息
  1. $ qemu-img info /data/kvm/disk/vm01.qcow2
  2. image: /data/kvm/disk/vm01.qcow2
  3. file format: qcow2
  4. virtual size: 30G (32212254720 bytes)
  5. disk size: 1.6G
  6. cluster_size: 65536
  7. Format specific information:
  8. compat: 1.1
  9. lazy refcounts: false

创建raw格式的虚拟机磁盘
  1. $ qemu-img create /path/to/test.raw 2G

创建qcow2格式的虚拟机磁盘
  1. $ qemu-img create -f qcow2 /path/to/test2.qcow2 2G

调整磁盘大小
  1. # 最好先将虚机关机
  2. $ qemu-img info /data/kvm/disk/vm01.qcow2
  3. image: /data/kvm/disk/vm01.qcow2
  4. file format: qcow2
  5. virtual size: 30G (32212254720 bytes) # 当前大小为 30G
  6. disk size: 1.6G
  7. cluster_size: 65536
  8. Format specific information:
  9. compat: 1.1
  10. lazy refcounts: false
  11. $ qemu-img resize /data/kvm/disk/vm01.qcow2 +20G # 增大 20G
  12. Image resized.
  13. $ qemu-img info /data/kvm/disk/vm01.qcow2
  14. image: /data/kvm/disk/vm01.qcow2
  15. file format: qcow2
  16. virtual size: 50G (53687091200 bytes) # 已经增加至50G
  17. disk size: 1.6G
  18. cluster_size: 65536
  19. Format specific information:
  20. compat: 1.1
  21. lazy refcounts: false
  22. # 当扩容完成后,启动虚机,还需要登录到虚机,进行磁盘分区,挂载,才可以使用扩展的磁盘空间
  23. # 可能当分区后,无法识别新的分区,需要执行 partprobe /dev/vda 重新检测分区信息

快照管理

快照分类:

  • 按快照信息保存分为:

    • 内置快照:快照数据和base磁盘数据放在一个qcow2文件中;
    • 外置快照:快照数据单独的qcow2文件存放;
  • 按虚机状态可以分为:

    • 关机态快照:数据可以保持一执行;
    • 运行态快照:数据无法保证一致性,类似与系统crash后的磁盘数据。使用时可能需要fsck等操作;
  • 按磁盘数量可以分为:

    • 单盘:单盘快照不涉及原子性;
    • 多盘:涉及原子性,主要分为两个方面:1、所有快照点相同;2、所有盘要么都快照成功,要么都快照失败,主要依赖于qemu的transaction实现。

创建磁盘快照
  1. # -s指定标签
  2. $ qemu-img snapshot -c s1 /data/kvm/disk/vm02.qcow2

列出磁盘快照
  1. $ qemu-img snapshot -l /data/kvm/disk/vm02.qcow2
  2. Snapshot list:
  3. ID TAG VM SIZE DATE VM CLOCK
  4. 1 s1 0 2021-02-01 10:30:47 00:00:00.000
  5. # qemu-img info 也可以查看到快照
  6. $ qemu-img info /data/kvm/disk/vm02.qcow2
  7. image: /data/kvm/disk/vm02.qcow2
  8. file format: qcow2
  9. virtual size: 50G (53687091200 bytes)
  10. disk size: 1.7G
  11. cluster_size: 65536
  12. Snapshot list:
  13. ID TAG VM SIZE DATE VM CLOCK
  14. 1 s1 0 2021-02-01 10:30:47 00:00:00.000
  15. Format specific information:
  16. compat: 1.1
  17. lazy refcounts: false

回滚到某个磁盘快照
  1. $ qemu-img snapshot -a s1 /data/kvm/disk/vm02.qcow2

注:上述是对于磁盘创建的快照,而接下来是对于整个虚机创建快照

创建快照
  1. $ virsh snapshot-create 虚拟机名称

查看虚机快照列表
  1. $ virsh snapshot-list 虚拟机名称

恢复快照
  1. $ virsh snapshot-revert 虚机名称 快照名称

删除快照
  1. $ virsh snapshot-delete 虚机名称 快照名称