date: 2021-04-21title: kvm部署及维护 #标题
tags: kvm #标签
categories: kvm # 分类
最近打算重新学习下kvm,毕竟之前学习,有图形化的操作,不贴合实际应用场景。
环境准备
一台机器(磁盘、CPU、内存最好大些)用来做宿主机,如果你使用虚机来做测试环境,那么需要保证处理器勾选如下复选框:
检测CPU是否支持KVM
KVM 是基于 x86 虚拟化扩展(Intel VT 或者 AMD-V) 技术的虚拟机软件,所以查看 CPU 是否支持 VT 技术,就可以判断是否支持KVM。有返回结果,如果结果中有vmx(Intel)或svm(AMD)字样,就说明CPU的支持的。
$ egrep 'vmx|svm' /proc/cpuinfo | wc -l
4
配置KVM基础环境
安装基础工具
$ yum -y install qemu-kvm python-virtinst libvirt libvirt-python \
virt-manager libguestfs-tools bridge-utils virt-install
$ reboot # 安装完成后,最好重启操作系统
$ lsmod | grep kvm # 重启后确认kvm模块已加载
kvm_intel 183621 0
kvm 586948 1 kvm_intel
irqbypass 13503 1 kvm
设置libvirtd为开机自启
$ systemctl start libvirtd && systemctl enable libvirtd
创建相关目录,存储镜像文件以及虚拟机磁盘文件
$ mkdir /data/kvm/{disk,iso} -p
# 下载镜像
$ wget https://mirrors.sohu.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso \
-O /data/kvm/iso/CentOS-7-x86_64-DVD-2009.iso
定义ks应答文件
# 安装nginx
$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ yum -y install nginx
# 定义应答文件
$ vim /usr/share/nginx/html/ks.cfg # 文件内容如下
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
text
# Run the Setup Agent on first boot
firstboot --disable
#ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang zh_CN.UTF-8
# Network information
network --hostname=localhost.chinadaas
# Root password
# root密码生成方式:$ openssl passwd -1 "123.com"
rootpw --iscrypted $1$Lo9vO2wd$ir6LWYaZ6GrhQLuUxgc2T1
#firewalld disabled
firewall --disabled
#SELinux disabled
selinux --disabled
# System services
services --disabled="NetworkManager,abrtd"
# System timezone
timezone Asia/Shanghai
# System bootloader configuration
#bootloader
# 自动分区方案
# bootloader --location=mbr --boot-drive=vda
# autopart --type=lvm
# clearpart --none --initlabel
# 手动分区方案
bootloader --location=mbr
# Partition clearing information
clearpart --all
part /boot --fstype="xfs" --size=1024
part pv.1 --fstype="lvmpv" --grow --size=1
#分配所有空间给pv1 size设为1 加 --grow
volgroup centos pv.1
logvol / --fstype="xfs" --size=17408 --name=root --vgname=centos
logvol /home --fstype="xfs" --size=10240 --name=home --vgname=centos
logvol swap --fstype="swap" --size=2040 --name=swap --vgname=centos
# 上述分区大小单位为 MB,最好指定的分区大小总空间,比实际磁盘空间小10M左右,否则可能空间不够。
%packages
@^infrastructure-server-environment
@base
@core
%end
%post
cat > /etc/security/limits.conf << EOF
* - nofile 650000
* - memlock unlimited
* - stack 655360
* - nproc unlimited
EOF
#set ssh
sed -i 's/^GSSAPIAuthentication yes$/GSSAPIAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
service sshd restart
#define the backspace button can erase the last character typed
echo 'stty erase ^H' >> /etc/profile
echo "syntax on" >> /root/.vimrc
cat > /etc/sysctl.conf << EOF
kernel.sysrq = 0
kernel.core_uses_pid = 1
fs.file-max=655360
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
kernel.pid_max = 655360
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_max_orphans = 655360
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 16384 16777216
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.route.gc_timeout = 100
# 禁止icmp重定向报文
net.ipv4.conf.all.accept_redirects = 0
# 禁止icmp源路由
net.ipv4.conf.all.accept_source_route = 0
net.core.somaxconn = 65535
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
vm.swappiness = 3
vm.overcommit_memory = 1
vm.max_map_count = 262144
EOF
# 终端美化
echo "PS1='[\[\e[36m\]\#::\[\e[31m\]\u@\[\e[32m\]\h\[\e[36m\]::\w]\\$
>>> \[\e[m\]'" >> /etc/profile
# 关闭发邮件
echo 'unset MAILCHECK' >> /etc/profile
#reboot
reboot
%end
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
# 启动nginx
$ nginx
KVM网络配置
kvm虚拟机的网络配置有两种模式:桥接模式和NAT模式。两种模式区别如下:
- NAT模式:也是用户模式,数据包由NAT方式通过主机的接口进行传送,可以访问公网,但是无法从外部访问虚拟机网络,所以一般不会用到。
- Bridge:也就是桥接模式,这种模式允许虚拟机像一个独立的主机一样拥有网络,外部的机器可以直接访问到虚拟机内部,但需要网卡支持,一般有线网卡都支持。
NAT模式配置
nat模式配置比较简单,只需要在创建虚机时,指定--network network=default
,表示使用默认网络即可,这里就不多写了,(它是借助KVM服务器的防火墙规则及IPtables规则来实现的,关闭KVM服务器的防火墙不会影响虚拟机ping外网,但是其iptables的默认配置必须存在,否则,虚拟机无法ping通外网)。
Bridge模式配置
停止网络服务
$ systemctl stop NetworkManager
启用桥接接口br0
$ virsh iface-bridge ens33 br0 # ens33为我的网卡名称
使用附加设备 br0 生成桥接 ens33 失败 # 如果卡在这里,再敲下回车
已启动桥接接口 br0
$ ls /etc/sysconfig/network-scripts/ | grep br0
ifcfg-br0 # 确认有此文件
创建虚拟机
创建虚拟磁盘
# 创建两个虚机磁盘
$ qemu-img create -f qcow2 /data/kvm/disk/vm01.qcow2 30G
$ qemu-img create -f qcow2 /data/kvm/disk/vm02.qcow2 30G
常用的虚拟磁盘有三种格式:
- RAW:裸格式。占用空间较大,性能比较好,但不支持快照功能。
- qcow:copy on write(写时复制机制)。
- qcow2:占用空间较小(按需进行分配磁盘空间,不管文件系统是否支持),性能相比较RAW稍差,,但它支持快照、压缩、加密功能。
注:磁盘文件最好挂载在LVS卷上,以便可以动态扩展卷空间。
创建一个虚机
# 使用nat网络的虚机
$ virt-install --os-type=linux --os-variant centos7.0 --name web01 --ram 2048 --vcpus 2 \
--disk /data/kvm/disk/vm01.qcow2 --location /data/kvm/iso/CentOS-7.6-x86_64-DVD-1810.iso \
--network network=default --graphics vnc,listen=0.0.0.0 --console pty,target_type=serial \
-x "ks=http://192.168.20.6/ks.cfg" --autostart --noautoconsole
# 使用Bridge网络的虚机
$ virt-install --os-type=linux --os-variant centos7.0 --name web02 --ram 2048 --vcpus 2 \
--disk /data/kvm/disk/vm02.qcow2 --location /data/kvm/iso/CentOS-7.6-x86_64-DVD-1810.iso \
--network bridge=br0 --graphics vnc,listen=0.0.0.0 --console pty,target_type=serial \
-x "ks=http://192.168.20.6/ks.cfg" --autostart --noautoconsole
# --network bridge=br0:也可以写为 --network type=bridge,source=br0
# 如果要使用lvm的存储池创建存储卷并安装虚机,则需要用`--disk vol=test_lvm/lvvol1` 来指定磁盘文件
# 其中`test_lvm`是存储池名称,`lvvol1`是存储卷名称。
# 附加:创建一个win7机器(win7.img文件无需提前创建,size的单位为G)
$ virt-install --name win7 --hvm --ram 3072 --vcpus 2 --disk path=/data/win7.img,size=30 \
--network network:default --accelerate --vnc --vncport=8621 --vnclisten=0.0.0.0 \
--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虚机中,如下:
# 查询宿主机对应的虚机web01的端口
$ virsh vncdisplay web01
:0
# 查看出的结果是“:0”,解释如下:
# “:0”表示监听5900端口;
# “:1”表示监听5901端口;
# 以此类推......
输入ip+端口,登录到虚机:
输入用户名/密码,即可登录到虚机中,如下:
使用console登录到机器
如果你执行virsh console $kvm-name
指令后,卡在那里不动,则需要先使用其他方式登录到虚机中,执行grubby --update-kernel=ALL --args=”console=ttyS0”
指令,然后重启虚机,就可以通过console登录到虚机了,如下:
$ grubby --update-kernel=ALL --args=”console=ttyS0”
$ reboot
当机器重启后,即可输入如下指令,在宿主机上登录到机器上,如下:
$ virsh console web01 # 登录到web01
连接到域 web01
换码符为 ^] # 按下回车键
CentOS Linux 7 (Core)
Kernel 3.10.0-957.el7.x86_64 on an x86_64
# 输入用户名密码
localhost login: root
Password:
Last login: Sat Jan 30 15:52:22 on ttyS0
[1::root@localhost::~]#
>>> ping baidu.com # ping百度测试下是否可以访问外网
PING baidu.com (39.156.69.79) 56(84) bytes of data.
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=127 time=10.2 ms
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=127 time=12.1 ms
# 若要退出kvm虚机终端,请按 Ctrl + ] 组合键。
克隆虚机
通过命令方式克隆(源虚机需要在关机或挂起状态下操作)
$ virsh list --all # 查看现有虚机
Id 名称 状态
----------------------------------------------------
9 web01 running
$ virsh console web01
$ vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 删除UUID
UUID="c32c8fae-52e7-497e-a0d0-f9658316490f"
$ virsh shutdown web01 # 需要先将web01关机
域 web01 被关闭
# 根据web01克隆出来web02(-f 指定的是web02这个虚机的磁盘文件,此文件无需提前创建)
$ virt-clone -o web01 -n web02 -f /data/kvm/disk/vm02.qcow2
正在分配 'vm02.qcow2' | 30 GB 00:00:36
$ virsh list --all # 再次查看虚机列表
Id 名称 状态
----------------------------------------------------
- web01 关闭
- web02 关闭
$ for i in 1 2;do virsh start web0${i};done # 启动两个虚机
注:克隆出来的虚机,需要登录到虚机中,修改mac地址为实际的mac地址(可通过ip a
指令查询),否则克隆出来的虚机无法获取IP。
通过修改文件的方式克隆(无需关闭源虚机)
查看虚机列表
$ virsh list --all
Id 名称 状态
----------------------------------------------------
11 web01 running
12 web02 running
创建新的虚机配置文件
$ virsh dumpxml web01 > /etc/libvirt/qemu/web03.xml
拷贝磁盘文件
$ cd /data/kvm/disk/
$ cp -a vm01.qcow2 vm03.qcow2
修改虚机配置文件
$ vim /etc/libvirt/qemu/web03.xml
....... # 省略部分内容
<domain type='kvm' id='11'>
<name>web03</name> # 修改虚机名称
~~<uuid>1911922e-7273-4f82-bf13-ecb4d901236b</uuid>~~ # 删除此行配置
....... # 省略部分内容
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/data/kvm/disk/vm03.qcow2'/> # 指定刚刚拷贝的新的磁盘文件
....... # 省略部分内容
<mac address='52:54:00:cb:18:f3'/> # 删除mac地址
定义虚机
$ virsh define /etc/libvirt/qemu/web03.xml
定义域 web03(从 /etc/libvirt/qemu/web03.xml)
确认虚机已克隆完成
$ virsh list --all # 可以查看到新增的web03
Id 名称 状态
----------------------------------------------------
11 web01 running
12 web02 running
- web03 关闭
注:克隆出来的虚机,需要登录到虚机中,修改mac地址为实际的mac地址(可通过ip a
指令查询),否则克隆出来的虚机无法获取IP。
kvm维护指令
virsh指令
查看虚机列表
$ virsh list --all # 如果只查看运行状态的虚机,则无需 --all
Id 名称 状态
----------------------------------------------------
1 web01 running
- web02 关闭
- web03 关闭
启动虚拟机
$ virsh start 虚机名称
重启虚机
$ virsh reboot 虚机名称
设置所有虚机为开机自启
$ for i in $(virsh list --all | awk '{if(NR>2) print $2}');do virsh autostart $i;done
启动所有虚机
for i in $(virsh list --all | grep -v running | awk '{if(NR>2) print $2}');do virsh start $i;done
关闭虚机
$ virsh shutdown 虚拟机名称 #正常的关闭虚拟机
$ virsh destroy 虚拟机名称 #强制关闭虚拟机(类似于拔电源)
备份虚机配置文件
$ virsh dumpxml 虚拟机名称 > /root/test01-dum.xml
删除虚机
$ virsh undefine 虚拟机名称 #删除虚拟机(注意:取消定义之后,磁盘文件需要手动删除)
还原虚机
$ virsh define 备份的.xml虚拟机文件
编辑虚机配置文件
$ virsh edit 虚拟机名称
更改虚机名称
$ virsh domrename 原名字 要更改的名字
查看虚机信息
$ virsh dominfo 虚拟机名称
设置开机自启
$ virsh autostart 虚拟机名称
取消开机自启
$ virsh autostart --disable 虚拟机名称
查看虚机对应的VNC连接端口号
默认第一个端口号为:5900(用“:0”表示),以此类推
$ virsh vncdisplay 虚拟机名称
挂起虚机
$ virsh suspend 虚拟机名称
取消挂起虚机
$ virsh resume 虚拟机名称
console登陆虚拟机
$ virsh console 虚拟机名称
查看磁盘信息
$ virsh domblklist web01
目标 源
------------------------------------------------
vda /data/kvm/disk/vm01.qcow2
hda -
将将test.raw磁盘格式raw转换为qcow2
$ qemu-img convert -f raw -O qcow2 test.raw test.qcow2
克隆虚机
$ virt-clone --auto-clone -o 源虚机 -n 新虚机
查看磁盘文件分区信息
$ virt-filesystems --long --parts --blkdevs -h -a /data/kvm/disk/vm01.qcow2
Name Type MBR Size Parent
/dev/sda1 partition 83 1.0G /dev/sda
/dev/sda2 partition 8e 29G /dev/sda
/dev/sda device - 30G -
qemu-img指令
qemu-img是一个功能强大的磁盘镜像管理工具。
查看虚拟机的磁盘信息
$ qemu-img info /data/kvm/disk/vm01.qcow2
image: /data/kvm/disk/vm01.qcow2
file format: qcow2
virtual size: 30G (32212254720 bytes)
disk size: 1.6G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
创建raw格式的虚拟机磁盘
$ qemu-img create /path/to/test.raw 2G
创建qcow2格式的虚拟机磁盘
$ qemu-img create -f qcow2 /path/to/test2.qcow2 2G
调整磁盘大小
# 最好先将虚机关机
$ qemu-img info /data/kvm/disk/vm01.qcow2
image: /data/kvm/disk/vm01.qcow2
file format: qcow2
virtual size: 30G (32212254720 bytes) # 当前大小为 30G
disk size: 1.6G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
$ qemu-img resize /data/kvm/disk/vm01.qcow2 +20G # 增大 20G
Image resized.
$ qemu-img info /data/kvm/disk/vm01.qcow2
image: /data/kvm/disk/vm01.qcow2
file format: qcow2
virtual size: 50G (53687091200 bytes) # 已经增加至50G
disk size: 1.6G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
# 当扩容完成后,启动虚机,还需要登录到虚机,进行磁盘分区,挂载,才可以使用扩展的磁盘空间
# 可能当分区后,无法识别新的分区,需要执行 partprobe /dev/vda 重新检测分区信息
快照管理
快照分类:
按快照信息保存分为:
- 内置快照:快照数据和base磁盘数据放在一个qcow2文件中;
- 外置快照:快照数据单独的qcow2文件存放;
按虚机状态可以分为:
- 关机态快照:数据可以保持一执行;
- 运行态快照:数据无法保证一致性,类似与系统crash后的磁盘数据。使用时可能需要fsck等操作;
按磁盘数量可以分为:
- 单盘:单盘快照不涉及原子性;
- 多盘:涉及原子性,主要分为两个方面:1、所有快照点相同;2、所有盘要么都快照成功,要么都快照失败,主要依赖于qemu的transaction实现。
创建磁盘快照
# -s指定标签
$ qemu-img snapshot -c s1 /data/kvm/disk/vm02.qcow2
列出磁盘快照
$ qemu-img snapshot -l /data/kvm/disk/vm02.qcow2
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 s1 0 2021-02-01 10:30:47 00:00:00.000
# qemu-img info 也可以查看到快照
$ qemu-img info /data/kvm/disk/vm02.qcow2
image: /data/kvm/disk/vm02.qcow2
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 1.7G
cluster_size: 65536
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 s1 0 2021-02-01 10:30:47 00:00:00.000
Format specific information:
compat: 1.1
lazy refcounts: false
回滚到某个磁盘快照
$ qemu-img snapshot -a s1 /data/kvm/disk/vm02.qcow2
注:上述是对于磁盘创建的快照,而接下来是对于整个虚机创建快照
创建快照
$ virsh snapshot-create 虚拟机名称
查看虚机快照列表
$ virsh snapshot-list 虚拟机名称
恢复快照
$ virsh snapshot-revert 虚机名称 快照名称
删除快照
$ virsh snapshot-delete 虚机名称 快照名称