介绍
KVM(Kernel-based Virtual Machine)是一个开源的虚拟化解决方案,它基于 Linux 内核,提供了一种在 Linux 系统上运行虚拟机的方法。KVM 利用现代处理器中的虚拟化扩展(如 Intel VT-x 和 AMD-V)来提供高性能的虚拟化环境。
架构
KVM 中,虚拟机被实现为常规的 Linux 进程,由标准 Linux 调度程序进行调度;虚拟机的每个虚拟CPU 被实现为一个常规的 Linux 进程,这使得 KVM 能够使用 Linux 内核的已有功能。
但是,KVM 本身不执行任何硬件模拟,需要客户空间程序通过 /dev/kvm 接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O,并将它的视频显示映射回宿主的显示屏。目前这个应用程序使用QEMU
KVM(Kernel-based Virtual Machine)是一种在 Linux 内核中实现的虚拟化技术,它负责初始化 CPU 硬件、启用虚拟化模式,并管理虚拟机的 CPU、内存、中断控制器和时钟。KVM 的核心功能由内核模块 kvm_xxx.ko
提供,这些模块在 hypervisor 层面工作,并通过 /dev/kvm
设备接口与用户空间交互。用户空间的应用程序可以通过 ioctl()
系统调用来执行虚拟机的创建、启动、内存分配、VCPU 寄存器的读写操作,以及向 VCPU 注入中断和时钟信号等管理任务。
QEMU(Quick Emulator)是一个用户空间的进程,它模拟了各种硬件设备,如显卡、网卡和硬盘等,为虚拟机提供硬件支持。QEMU 与 KVM 结合使用时,qemu-kvm
进程负责运行虚拟机实例,它利用 KVM 的硬件虚拟化能力来提高性能。
Libvirt 是一个提供统一 API 的虚拟化管理库,它包括一个守护进程 libvirtd
和一系列相关工具,如 virsh
(虚拟机 shell)和 virt-manager
(虚拟机图形界面管理器)。Libvirt 提供了一个简化的接口来管理虚拟化资源,使得用户可以通过命令行或图形界面轻松地创建、监控和管理虚拟机。通过 Libvirt,用户可以跨多种虚拟化技术(包括 KVM)进行操作,提供了灵活性和一致性。
KVM模块载入后的系统运行模式
内核模式:HostOS执行I/O类操作,或其它的特殊指令的操作;称作内核模式
用户模式:GuestOS的I/O类操作
来宾模式:GuestOS非I/O类操作,称作虚拟机的用户模式
管理工具
KVM是运行在单机的系统,需要其它软件实现跨主机的统一的管理。
基于 KVM 技术的常见虚拟化平台:
oVirt:功能强大,是Redhat虚拟化管理平台RHEV的开源版本
WebVirtMgr:virt-manager的Web模式的替代品
OpenStack:最主流的开源虚拟化管理平台
Proxmox virtualization environment:简称PVE,是一个开源免费的基于Linux的企业级虚拟化方案。
宿主机准备
使用VMWare WorkStation模拟物理机,需要开启CPU虚拟化。
验证开启虚拟化
grep -Em 1 “vmx|svm” /proc/cpuinfo
如果输出中包含了 vmx 或 svm,则CPU 支持虚拟化技术。若没有,则CPU不支持或BIOS/UEFI未开启虚拟化。
-m 1表示只输出匹配的第一行。
vmx是Intel 处理器的虚拟化技术(Intel VT-x)的指示符
svm是 AMD 处理器的虚拟化技术(AMD-V)的指示符
安装KVM工具
-
qemu-kvm: 为kvm提供底层仿真支持
-
libvirt-daemon: libvirtd守护进程,管理虚拟机
-
libvirt-client: 用户端软件,提供客户端管理命令
-
libvirt-daemon-driver-qemu: libvirtd连接qemu的驱动
-
libvirt: 使用最多的KVM虚拟化管理工具和应用程序接口,即通过libvirt调用KVM创建虚拟机,
-
libvirt是KVM通用的访问API,其不但能管理KVM,还能管理VMware、Xen、Hyper-V、virtualBox等虚拟化方案。
-
virt-manager: 图形界面管理工具,其底层也是调用libvirt API来完成对虚拟机的操作,包括虚拟机的创建、删除、启动、停止以及一些简单的监控功能等。
-
virt-install: 虚拟机命令行安装工具
-
virsh: 命令行工具是基于 libvirt API 创建的命令行工具,它可以作为图形化的 virt-manager 应用的备选工具。virsh 命令可以被用来创建虚拟化任务管理脚本,如安装、启动和停止虚拟机
-
virt-viewer: 通过 VNC 和 SPICE 协议显示虚拟机器图形控制台的最小工具。该工具在其同名软件包中:virtviewercockpit: CentOS8 专门提供的基于Web的虚拟机管理界面
libvirt
libvirt 程序包是一个与虚拟机监控程序相独立的虚拟化应用程序接口,它可以与操作系统的一系列虚拟化性能进行交互。
libvirt 程序包提供:
一个稳定的通用层来安全地管理主机上的虚拟机。
一个管理本地系统和连网主机的通用接口。
libvirt 主要的功能是管理单节点主机,并提供 API 来列举、监测和使用管理节点上的可用资源。
如果libvirtd.socket服务意外关闭,将导致相关工具,virt-manager等无法和虚拟机相连,但虚拟机仍可正常运行。
结构图
安装KVM
Ubuntu
安装检测工具,CPU是否支持
[root@wenzi ~]#apt -y install cpu-checker
若支持
[root@wenzi ~]#kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
若不支持
[root@wenzi ~]#kvm-ok
INFO: Your CPU does not support KVM extensions
KVM acceleration can NOT be used
安装KVM工具
[root@wenzi ~]#apt update && apt -y install qemu-kvm virt-manager libvirt-daemon-system
CentOS
安装KVM工具
[root@wenzi ~]#yum -y install qemu-kvm libvirt virt-manager virt-install
[root@wenzi ~]#systemctl start libvirtd
实现基于web的虚拟机管理方式
CentOS、Ubuntu通用
[root@wenzi ~]#dnf -y install cockpit cockpit-machines
[root@wenzi ~]#systemctl enable --now cockpit.socket
访问地址:https://192.168.28.30:9090
图形化管理
此处指定:1.0
[root@wenzi ~]#export DISPLAY=192.168.28.1:1.0
[root@wenzi ~]#virt-manager
调出图形界面
若有乱码,设置语言
localectl set-locale LANG=en_US.UTF-8;exit
默认网络配置
安装完KVM新产生的virbr0是由 libvirt 创建的虚拟网络接口,可实现虚拟机之间、虚拟机与宿主机之间通讯;可实现网络隔离、网络桥接。
默认NAT地址转换模式,类似VMWare WorkStation的VMNet8网卡
---------------------------------------Ubuntu
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:39:53 brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 192.168.28.60/24 brd 192.168.28.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:3953/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:97:c9:e2 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
[root@wenzi ~]#apt -y install bridge-utils
[root@wenzi ~]#brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.52540097c9e2 yes
---------------------------------------CentOS
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:9f:92:9b brd ff:ff:ff:ff:ff:ff
inet 192.168.28.30/24 brd 192.168.28.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe9f:929b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:ae:53:64 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:ae:53:64 brd ff:ff:ff:ff:ff:ff
[root@wenzi ~]#dnf -y install bridge-utils
[root@wenzi ~]#brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400ae5364 yes virbr0-nic
#在CentOS、Ubuntu查看
[root@wenzi ~]#cat /etc/libvirt/qemu/networks/default.xml
<network>
<name>default</name> #网络名称default
<uuid>6ec5e852-928e-45fd-9442-9fc1c6cecad0</uuid> #UUID唯一标识符
<forward mode='nat'/> #网络模式NAT
<bridge name='virbr0' stp='on' delay='0'/> #定义了一个虚拟网桥virbr0,开启stp,延迟0
<mac address='52:54:00:ae:53:64'/> #虚拟网桥的MAC地址
<ip address='192.168.122.1' netmask='255.255.255.0'> #虚拟网桥IP、子网掩码
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/> #DHCP分配的地址范围
</dhcp>
</ip>
</network>
准备系统ISO
[root@wenzi ~]#mkdir -pv /data/isos/
[root@wenzi ~]#ls /data/isos/
CentOS-7.9-x86_64-DVD-2009.iso
创建虚拟机(图形化)
[root@wenzi ~]#export DISPLAY=192.168.28.1:1.0
[root@wenzi ~]#virt-manager
新增虚拟机
添加本地镜像文件
分配内存、CPU
分配磁盘空间
此处指定的磁盘会生成一个qcow2的稀疏格式文件,此处可以指定文件最大容量,但实际只占用实际的空间
大小,使用du -sh 文件可以观察到实际大小,使用ls -l 命令看到是此处指定的大小。
自定义配置
完毕点 Begin Installation。后续若发现键盘无法输入控制,在此面板Display Spice—Type—选择VNC
后面的步骤和正常装系统一样。
创建虚拟机(命令行)
virt-install更适用于批量创建管理虚拟机。
virt-install
常见选项
查看支持的OS版本
[root@wenzi ~]#virt-install --osinfo list
almalinux9
almalinux8
alpinelinux3.18
alpinelinux3.17
...
创建虚拟机使用光盘启动并手动安装
1、无需事先创建磁盘文件,直接创建虚拟机
[root@wenzi ~]#virt-install --virt-type kvm --os-variant=rocky8.5 --name rocky8 --memory 1024 --vcpus 2 --cdrom=/data/isos/Rocky-8.5-x86_64-minimal.iso --disk path=/var/lib/libvirt/images/rocky8.qcow2,size=10,format=qcow2,bus=virtio --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
virt-install: 这是用来创建虚拟机的命令。
--virt-type kvm: 指定虚拟化类型为KVM,这是Linux内核的一部分,用于提供高效的硬件虚拟化。
--os-variant=rocky8.5: 指定操作系统的变体,这里是Rocky Linux 8.5版本。
--name rocky8: 给虚拟机命名为rocky8。
--memory 1024: 分配1024MB的内存给虚拟机。
--vcpus 2: 分配2个虚拟CPU核心给虚拟机。
--cdrom=/data/isos/Rocky-8.5-x86_64-minimal.iso: 使用指定的ISO镜像文件作为虚拟机的光驱启动设备。
--disk path=/var/lib/libvirt/images/rocky8.qcow2,size=10,format=qcow2,bus=virtio: 创建一个10GB大小的QCOW2格式的磁盘文件,使用virtio总线。
--network network=default: 将虚拟机连接到默认的网络配置。
--graphics vnc,listen=0.0.0.0: 使用VNC图形界面,允许从任何IP地址访问。
--noautoconsole: 不自动打开控制台。
2、事先创建磁盘文件,再创建虚拟机
使用qemu-img创建新磁盘文件一定要实现检查,避免磁盘文件重名,否则原先的磁盘文件会被覆盖
[root@wenzi ~]#qemu-img create -f qcow2 /var/lib/libvirt/images/centos7.qcow2 10G
[root@wenzi ~]#ls /var/lib/libvirt/images/
centos7.qcow2 rocky8.qcow2
使用 centos7.qcow2 作为磁盘文件,接着创建虚拟机
[root@wenzi ~]#virt-install --virt-type kvm --os-variant=centos7 --name centos7 --memory 1024 --vcpus 2 --cdrom=/data/isos/CentOS-7.9-x86_64-DVD-2009.iso --disk path=/var/lib/libvirt/images/centos7.qcow2 --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
基于现有虚拟机磁盘为模版创建新的虚拟机
virt-manager
复制已有的磁盘文件,生成新的磁盘文件
[root@wenzi ~]#cp -a /var/lib/libvirt/images/rocky8.qcow2 /var/lib/libvirt/images/rocky888.qcow2
方式一
方式二
virt-install
[root@wenzi ~]#cp -a /var/lib/libvirt/images/rocky8.qcow2 /var/lib/libvirt/images/rocky888888.qcow2
下面命令和之前有区别
[root@wenzi ~]#virt-install --virt-type kvm --os-variant=rocky8.5 --name rocky888888 --memory 1024 --vcpus 1 --disk bus=virtio,path=/var/lib/libvirt/images/rocky888888.qcow2 --network network=default,model=virtio --graphics vnc,listen=0.0.0.0 --noautoconsole --autostart --boot hd
virt-clone
[root@wenzi ~]#virt-clone -o rocky8 -n rocky8-new -f /var/lib/libvirt/images/rocky8-new.qcow2
-o:指定已有的虚拟机名称
-n:new,后跟新创建虚拟机的名称
-f:指定新虚拟机磁盘文件位置,无需事先创建
管理虚拟机
半虚拟化驱动virtio
可以提高硬件(磁盘、内存、网络)性能
原理
实现IO虚拟化主要有三种方式:
- 全虚拟化:Guest OS不会感知到自己是虚拟机,也无需修改Guest OS,但是它的效率比较低。
- 半虚拟化:Guest OS知道自己是虚拟机,通过Frontend/Backend驱动模拟实现IO虚拟化。
- 透传就是直接分配物理设备给VM用,但是需要解决单个硬件在多个虚拟机共享使用的问题。
virtio 是一种 I/O 半虚拟化解决方案,是一套通用 I/O 设备虚拟化的程序,是对半虚拟化 Hypervisor 中的一组通用 I/O 设备的抽象。提供了一套上层应用与各 Hypervisor 虚拟化设备(KVM,Xen,VMware等)之间的通信框架和编程接口,减少跨平台所带来的兼容性问题,大大提高驱动程序开发效率。
通过统一的接口virtio以支持多种硬件设备
- 不同的虚拟设备和不同的虚拟机可以有不同的前端驱动
- 不同的硬件设备可以有不同的后端驱动
- 两者之间的交互遵循virtio的标准
架构
virtio 可以分为四层,包括前端 guest 中各种驱动程序模块,后端 Hypervisor (实现在Qemu上)上的处理程序模块,中间用于前后端通信的 virtio 层和 virtio-ring 层,virtio 这一层实现的是虚拟队列接口,算是前后端通信的桥梁,而 virtio-ring 则是该桥梁的具体实现,它实现了两个环形缓冲区,分别用于保存前端驱动程序和后端处理程序执行的信息。
获取驱动
Linux
RHEL4.8以后的系统会自动加载安装virtio驱动。
在虚拟机内部使用 lsmod | grep virtio 可查看。宿主机上没有使用virtio看不到结果。
windows
windows系统需要单独安装virtio驱动,
http://www.linux-kvm.org/page/Downloads
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/
virt-manager 管理虚拟机
virt-manager是一个图形化工具,主要功能:
定义和创建虚拟机
硬件管理
性能监视
控制台
在线和离线迁移
虚拟机的保存和恢复、暂停和继续、关闭和启动
启动菜单
开机后按ESC,会出现启动菜单
远程管理KVM主机
连接至远程的宿主机进行虚拟机的管理
虚拟机性能监控
管理快照
virsh命令行工具
virsh是使用libvirt managementAPI构建的管理工具,相比virt-manager可以提高效率
virsh命令格式
virsh [options]... [<command_string>]
virsh [options]... <command> [args...]
选项:
-c | --connect=URI: 指定连接到虚拟化宿主机的URI。这允许你连接到远程或本地的虚拟化宿主机。
-d | --debug=NUM: 设置调试级别,范围是0到4,数字越大,输出的调试信息越详细。
-e | --escape <char>: 设置控制台的转义字符,用于从虚拟机控制台退出。
-h | --help: 显示帮助信息,包括可用的子命令和全局选项。
-k | --keepalive-interval=NUM: 设置保活间隔时间(以秒为单位),用于保持与虚拟化宿主机的连接。设置为0可以禁用保活。
-K | --keepalive-count=NUM: 设置允许丢失的保活消息的数量。
-l | --log=FILE: 将日志信息输出到指定的文件。
-q | --quiet: 静默模式,不显示任何输出信息。
-r | --readonly: 以只读模式连接到虚拟化宿主机。
-t | --timing: 打印操作的计时信息。
-v: 显示短版本信息。
-V: 显示长版本信息。
--version[=TYPE]: 显示版本信息,TYPE可以是short(短版本)或long(长版本,默认为短版本)。
子命令: virsh help 子命令
help #打印基本帮助信息
attach-device #使用XML文件中的设备定义在虚拟机中添加设备
attach-disk #在虚拟机中附加新磁盘设备
attach-interface #在虚拟机中附加新网络接口
create #从 XML 配置文件生成虚拟机并启动新虚拟机
define #为虚拟机输出XML配置文件
destroy #强制虚拟机停止
detach-device #从虚拟机中分离设备,使用同样的XML 描述作为命令
detach-disk #从虚拟机中分离磁盘设备
detach-interface #从虚拟机中分离网络接口
domblkstat #显示正在运行的虚拟机的块设备统计
domid #显示虚拟机ID
domifstat #显示正在运行的虚拟机的网络接口统计
dominfo #显示虚拟机信息
domname #显示虚拟机名称
domstate #显示虚以机状态
domuuid #显示虚拟机UUID
dumpxml #输出虚拟机 XML配置文件
list #列出所有虚拟机
migrate #将虚拟机迁移到另一台主机中
nodeinfo #有关管理程序的输出信息
quit #退出这个互动终端
reboot #重新启动虚拟机
restore #恢复以前保存在文件中的虚拟机
resume #恢复暂停的虚拟机
save #将虚拟机当前状态保存到某个文件中
setmaxmem #为管理程序设定内存上限
setmem #为虚拟机设定分配的内存
setvcpus #修改为虚拟机分配的虚拟CPU数目
shutdown #关闭某个虚拟机
start #启动未激活的虚拟机
suspend #暂停虚拟机
undefine #删除与虚拟机关联的所有文件
vepuinfo #显示虚以机的虚拟CPU信息
vcpupin #控制虚拟机的虚拟CPU亲和性
version #显示virsh版本
查看虚拟机列表
查看当前活动的虚拟机
[root@wenzi ~]#virsh list
Id Name State
-------------------------
2 centos7 running
列出所有已知的虚拟机,无论虚拟机是否连接、运行
[root@wenzi ~]#virsh list --all
Id Name State
--------------------------
2 centos7 running
- rocky8 shut off
列出所有处于运行状态的虚拟机的UUID、名称
[root@wenzi ~]#virsh list --uuid --name
a89f78fb-cc7e-45fd-b208-d3b80e795300 centos7
列出所有已知的虚拟机的UUID、名称
[root@wenzi ~]#virsh list --all --uuid --name
a89f78fb-cc7e-45fd-b208-d3b80e795300 centos7
ee4b378b-2004-4ec4-b886-200de3573ab0 rocky8
查看个别虚拟机的UUID
[root@wenzi ~]#virsh domuuid centos7
a89f78fb-cc7e-45fd-b208-d3b80e795300
启动/关闭
可以使用虚拟机名字 或 virsh list中列出的ID 或 UUID 控制虚拟机
[root@wenzi ~]#virsh start rocky8
Domain 'rocky8' started
正常关机
[root@wenzi ~]#virsh shutdown rocky8
Domain 'rocky8' is being shutdown
强制关机。慎用
[root@wenzi ~]#virsh destroy rocky8
Domain 'rocky8' destroyed
在virt-manager中可看到虚拟机关机方式
暂停/恢复
暂停虚拟机,宿主机中的实现虚拟机的进程不会消失。通过ps aux 过滤qemu关键字可看到
暂停
[root@wenzi ~]#virsh suspend centos7
Domain 'centos7' suspended
恢复
[root@wenzi ~]#virsh resume centos7
Domain 'centos7' resumed
配置虚拟机开启自启
[root@wenzi ~]#virsh autostart centos7
Domain 'centos7' marked as autostarted
开机自启实质上是在 /etc/libvirt/qemu/autostart/ 目录下生成软链接
[root@wenzi ~]#ll /etc/libvirt/qemu/autostart/centos7.xml
lrwxrwxrwx 1 root root 29 Mar 11 14:45 /etc/libvirt/qemu/autostart/centos7.xml -> /etc/libvirt/qemu/centos7.xml
取消开机自启
[root@wenzi ~]#virsh autostart centos7 --disable
Domain 'centos7' unmarked as autostarted
查看虚拟机配置
每个虚拟机配置文件都存放在 /etc/libvirt/qemu/ 目录下
[root@wenzi ~]#virsh list
Id Name State
------------------------
10 rocky8 running
[root@wenzi ~]#ls /etc/libvirt/qemu/
autostart centos7.xml networks rocky8.xml
查看指定虚拟机配置,相当于cat /etc/libvirt/qemu/rocky8.xml
[root@wenzi ~]#virsh dumpxml rocky8
<domain type='kvm' id='10'>
<name>rocky8</name>
<uuid>ee4b378b-2004-4ec4-b886-200de3573ab0</uuid>
...
删除虚拟机配置
方法一:删除虚拟机配置,但不删除虚拟机磁盘文件
[root@wenzi ~]#virsh list --all
Id Name State
--------------------------
10 rocky8 running
- centos7 shut off
[root@wenzi ~]#virsh undefine centos7
Domain 'centos7' has been undefined
[root@wenzi ~]#virsh list --all
Id Name State
------------------------
10 rocky8 running
[root@wenzi ~]#ll /var/lib/libvirt/images/
total 2292768
drwx--x--x 2 root root 4096 Mar 11 13:35 ./
drwxr-xr-x 7 root root 4096 Mar 11 12:10 ../
-rw-r--r-- 1 root root 196768 Mar 11 12:38 centos7.qcow2 #centos7磁盘文件还存在
-rw------- 1 libvirt-qemu kvm 10739318784 Mar 11 15:07 rocky8.qcow2
#CentOS7的xml配置文件已经消失
[root@wenzi ~]#ll /etc/libvirt/qemu/
total 24
drwxr-xr-x 4 root root 4096 Mar 11 15:06 ./
drwxr-xr-x 7 root root 4096 Mar 11 12:26 ../
drwxr-xr-x 2 root root 4096 Mar 11 15:06 autostart/
drwxr-xr-x 3 root root 4096 Mar 11 12:10 networks/
-rw------- 1 root root 7094 Mar 11 12:26 rocky8.xml
方法二:删除虚拟机配置,同时删除虚拟机磁盘文件
[root@wenzi ~]#virsh undefine rocky8-clone --remove-all-storage
Domain 'rocky8-clone' has been undefined
Volume 'vda'(/var/lib/libvirt/images/rocky8-clone.qcow2) removed.
冷迁移虚拟机
将一个宿主机的处于关机状态的虚拟机迁移到另一台宿主机。
不支持Ubuntu和Rocky之间迁移。
新宿主机安装基本环境
[root@wenzi ~]#apt -y install qemu-kvm virt-manager libvirt-daemon-system
找到待迁移主机的两个文件
1、虚拟机的xml配置文件 /etc/libvirt/qemu/rocky8.xml
2、虚拟机的磁盘文件 /var/lib/libvirt/images/rocky8.qcow2
将其传输到新宿主机,新宿主机需要重启libvirtd服务才能看到新的虚拟机。
systemctl restart libvirtd
热迁移
热迁移需要让数据文件都在共享存储里面
virt-what
此命令可以判断当前是虚拟机还是物理机,如果是物理机,将不会返回任何结果。如果是虚拟机,将会输出含有kvm、vmware关键字的信息
#VMWare虚拟机
[root@ubuntu2004 ~]#virt-what
vmware
#阿里云ECS
[root@centos7-liyun-pc ~]# virt-what
kvm
#物理机执行结果
root@user:~# virt-what
存储管理
虚拟磁盘类型
固定Fixed
在配置时,指定磁盘大小。不管在虚拟磁盘上实际存储多少数据,都将占用相同大小宿主机的磁盘空间。
动态Dynamic
初始空间占用小。随着空间的使用逐渐增长到最大容量,但是只根据需求使用更多的空间。
差异Differencing
创建的是差异磁盘,只保存变更的数据。例如,将操作系统安装在父盘,然后创建差异化磁盘来执行进一步配置。
虚拟镜像文件格式
raw
默认磁盘格式。性能好,但空间占用大,功能少,生产不建议使用。
如果主机文件系统允许,raw 文件可以是预分配(pre-allocated)或 稀疏(sparse)。稀
疏文件根据需求分配主机磁盘空间,因此它是一种精简配置形式(thin provisioning)。
预分配文件的所有空间需要被预先分配,但它比稀疏文件性能好。当对磁盘 I/O 性能要求非常高,而且通常不需要通过网络传输镜像文件时,可以使用 raw文件
qcow2
推荐使用,按需分配磁盘空间,不管文件系统是否支持,支持快照,支持zlib的磁盘压缩,支持AES加密,节约空间,功能丰富,但性能较差。
vmdk
VMWare环境中默认使用的磁盘文件格式
vhd
微软默认使用的磁盘文件格式
vdi
Virtual Box 使用的磁盘文件格式
查看KVM支持的磁盘格式
[root@wenzi ~]#qemu-img --help | grep Support
Supported formats: blkdebug blklogwrites blkverify bochs cloop compress copy-before-write copy-on-read dmg file ftp ftps gluster host_cdrom host_device http https iscsi iser luks nbd null-aio null-co nvme parallels preallocate qcow qcow2 qed quorum raw rbd replication ssh throttle vdi vhdx vmdk vpc vvfat
qemu-img工具
qemu-img 是一个功能强大的磁盘镜像管理工具。
帮助文档:qemu-img --help
子命令:
check #检查完整性
create #创建镜像
commit #提交更改
compare #比较
convert #转换
info #获得信息
map #映射
snapshot #快照管理
rebase #在已有的镜像的基础上创建新的镜像
resize #调整大小
amend #修订镜像格式选项
创建默认raw稀疏格式磁盘
默认生成在当前目录下
[root@wenzi ~]#qemu-img create vm1.img 500M
Formatting 'vm1.img', fmt=raw size=524288000
显示文件大小
[root@wenzi ~]#ll -h vm1.img
-rw-r--r-- 1 root root 500M Mar 11 15:55 vm1.img
实际只占4k
[root@wenzi ~]#du -sh vm1.img
4.0K vm1.img
显示文件信息
[root@wenzi ~]#qemu-img info vm1.img
image: vm1.img
file format: raw
virtual size: 500 MiB (524288000 bytes)
disk size: 4 KiB
创建raw非稀疏格式磁盘
[root@wenzi ~]#dd if=/dev/zero of=vm2.img bs=500M count=1
1+0 records in
1+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 0.652132 s, 804 MB/s
[root@wenzi ~]#qemu-img info vm2.img
image: vm2.img
file format: raw
virtual size: 500 MiB (524288000 bytes)
disk size: 500 MiB
[root@wenzi ~]#ll -h vm2.img
-rw-r--r-- 1 root root 500M Mar 11 16:10 vm2.img
[root@wenzi ~]#du -sh vm2.img
500M vm2.img
查看不同磁盘文件格式支持选项
[root@wenzi ~]#qemu-img create -f raw -o ?
Supported raw options:
size=<size> - Virtual disk size
The protocol level may support further options.
Specify the target filename to include those options.
[root@wenzi ~]#qemu-img create -f qcow2 -o ?
Supported qcow2 options:
backing_file=<str> 指定基础镜像文件的名称
backing_fmt=<str> 指定基础镜像的格式
cluster_size=<size> 仅适用于QCOW2格式,设置镜像中的簇大小,取值在512到2M之间,默认值为64K
...
preallocation=<str> 指定虚拟磁盘的预分配模式(off, metadata, falloc, full)
size=<size> 指定虚拟磁盘的大小
检查虚拟磁盘
对于关机状态的虚拟机磁盘,可以检查错误。
[root@wenzi ~]#qemu-img check /var/lib/libvirt/images/rocky8.qcow2
No errors were found on the image.
52179/163840 = 31.85% allocated, 3.51% fragmented, 0.00% compressed clusters
Image end offset: 10739318784
磁盘预分配策略
raw 文件的预分配策略和文件系统是否支持有关;而qcow2则无关。
- off: 不预分配任何空间,磁盘文件将根据需要动态增长。
- metadata: 预分配元数据空间,但不预分配数据空间。
- falloc: 使用fallocate系统调用预分配空间,这可以提高性能,但不是所有文件系统都支持。
- full: 完全预分配磁盘空间,这会立即占用全部指定的磁盘空间。
创建不同预分配策略的磁盘文件
qemu-img create -f qcow2 test2.qcow2 1g -o preallocation=off|metadata|falloc|full
虚拟磁盘格式转换
默认转化为raw格式
qemu-img convert CentOS8.2.vmdk CentOS8.2.img
指定转化后的格式为qcow2
qemu-img convert -f vmdk -O qcow2 CentOS8.2.vmdk
调整虚拟磁盘大小
qemu-img resize [–shrink] filename [+l -]size
- 操作之前,一定要做好数据备份
- 增加文件大小后,需要在客户机中使用fdisk、parted等分区工具进行相应的操作才能真正让客户机使用到增加后的镜像空间。
- 缩小镜像之前,要在客户机中保证里面的文件系统有空余空间,否则会数据丢失。另外xfs文件系统不支持缩减。
- qcow2不支持缩小镜像的操作
查看当前虚拟机磁盘空间
扩容vda至12G
--------------------------------------宿主机操作
[root@wenzi ~]#qemu-img info /var/lib/libvirt/images/rocky8.qcow2
image: /var/lib/libvirt/images/rocky8.qcow2
file format: qcow2
virtual size: 10 GiB (10737418240 bytes) #当前10G
disk size: 2.17 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
extended l2: false
[root@wenzi ~]#qemu-img resize /var/lib/libvirt/images/rocky8.qcow2 +2G
Image resized.
[root@wenzi ~]#qemu-img info /var/lib/libvirt/images/rocky8.qcow2
image: /var/lib/libvirt/images/rocky8.qcow2
file format: qcow2
virtual size: 12 GiB (12884901888 bytes) #当前12G,但文件系统大小未变化,还需fdisk、lvm等操作
disk size: 2.17 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
extended l2: false
kvm虚拟机内查看,可见vda是12G,但并未使用。且使用了LVM逻辑卷。
--------------------------------------kvm虚拟机内操作
可以用宿主机ssh连接至kvm虚拟机
[root@rocky85 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 12G 0 disk
├─vda1 252:1 0 1G 0 part /boot
└─vda2 252:2 0 9G 0 part
├─rl-root 253:0 0 8G 0 lvm /
└─rl-swap 253:1 0 1G 0 lvm [SWAP]
[root@rocky85 ~]# fdisk /dev/vda
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): n
Partition type
p primary (2 primary, 0 extended, 2 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (3,4, default 3):
First sector (20971520-25165823, default 20971520):
Last sector, +sectors or +size{K,M,G,T,P} (20971520-25165823, default 25165823):
Created a new partition 3 of type 'Linux' and of size 2 GiB.
Command (m for help): t
Partition number (1-3, default 3): 3
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'.
Command (m for help): w
The partition table has been altered.
Syncing disks.
[root@rocky85 ~]# partprobe
[root@rocky85 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 12G 0 disk
├─vda1 252:1 0 1G 0 part /boot
├─vda2 252:2 0 9G 0 part
│ ├─rl-root 253:0 0 8G 0 lvm /
│ └─rl-swap 253:1 0 1G 0 lvm [SWAP]
└─vda3 252:3 0 2G 0 part
[root@rocky85 ~]# pvcreate /dev/vda3
Physical volume "/dev/vda3" successfully created.
[root@rocky85 ~]# vgextend rl /dev/vda3
Volume group "rl" successfully extended
[root@rocky85 ~]# vgs
VG #PV #LV #SN Attr VSize VFree
rl 2 2 0 wz--n- 10.99g <2.00g
#此步骤可以和xfs_growfs整合,使用 lvextend -r -l +100%free /dev/mapper/rl-root
[root@rocky85 ~]# lvextend -l +100%free /dev/mapper/rl-root
Size of logical volume rl/root changed from <8.00 GiB (2047 extents) to 9.99 GiB (2558 extents).
Logical volume rl/root successfully resized.
[root@rocky85 ~]# xfs_growfs /dev/rl/root
[root@rocky85 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 12G 0 disk
├─vda1 252:1 0 1G 0 part /boot
├─vda2 252:2 0 9G 0 part
│ ├─rl-root 253:0 0 10G 0 lvm /
│ └─rl-swap 253:1 0 1G 0 lvm [SWAP]
└─vda3 252:3 0 2G 0 part
└─rl-root 253:0 0 10G 0 lvm /
[root@rocky85 ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 467M 0 467M 0% /dev
tmpfs tmpfs 485M 0 485M 0% /dev/shm
tmpfs tmpfs 485M 6.6M 478M 2% /run
tmpfs tmpfs 485M 0 485M 0% /sys/fs/cgroup
/dev/mapper/rl-root xfs 10G 1.7G 8.3G 17% / #从原先8G,变为现在10G,扩容成功
/dev/vda1 xfs 1014M 162M 853M 16% /boot
tmpfs tmpfs 97M 0 97M 0% /run/user/0
缩容风险大,不建议使用
磁盘快照
对磁盘数据进行快照,主要用于虚拟机备份等场合
磁盘快照分类
按快照信息保存分为:
- 内置快照∶快照数据和base磁盘数据放在同一个qcow2文件中
- 外置快照︰快照数据单独的另一个qcow2文件存放
按虚拟机状态可以分为:
- 关机态快照︰数据可以保证一致性
- 运行态快照∶数据无法保证一致性,类似与系统crash后的磁盘数据。使用是可能需要fsck等操作。
按磁盘数量可以分为:
- 单盘:单盘快照不涉及原子性
- 多盘:涉及原子性。主要分两个方面:1.是所有盘快照点相同2.所有盘要么都快照成功,要么都快照失败。主要依赖于qemu的transaction实现
qemu-img 管理磁盘快照
qemu-img snapshot [--object objectdef] [--image-opts] [-U] [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename
-a:应用快照
-c:创建快照
-d:删除快照
-l:列出快照
关机才能创建快照
[root@wenzi ~]#qemu-img snapshot -c rocky8-snap1 /var/lib/libvirt/images/rocky8.qcow2
查看快照信息
[root@wenzi ~]#qemu-img info /var/lib/libvirt/images/rocky8.qcow2
image: /var/lib/libvirt/images/rocky8.qcow2
file format: qcow2
virtual size: 10 GiB (10737418240 bytes)
disk size: 2.7 GiB
cluster_size: 65536
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK ICOUNT
1 snapshot1 502 MiB 2024-03-11 17:55:35 00:32:28.369
2 rocky8-snap1 0 B 2024-03-11 18:02:02 00:00:00.000 0
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
extended l2: false
查看某个虚拟机的快照
[root@wenzi ~]#qemu-img snapshot -l /var/lib/libvirt/images/rocky8.qcow2
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK ICOUNT
1 snapshot1 502 MiB 2024-03-11 17:55:35 00:32:28.369
2 rocky8-snap1 0 B 2024-03-11 18:02:02 00:00:00.000 0
关机才能恢复快照
[root@wenzi ~]#qemu-img snapshot -a rocky8-snap1 /var/lib/libvirt/images/rocky8.qcow2
关机才能删除快照
[root@wenzi ~]#qemu-img snapshot -d rocky8-snap1 /var/lib/libvirt/images/rocky8.qcow2
virsh管理磁盘快照
virsh管理创建删除应用磁盘快照时,kvm虚拟机可以是开机运行状态
[root@wenzi ~]#virsh list --all
Id Name State
---------------------------
2 rocky8-02 running
[root@wenzi ~]#virsh snapshot-list rocky8-02
Name Creation Time State
-------------------------------
[root@wenzi ~]#virsh snapshot-create rocky8-02
Domain snapshot 1710230402 created
[root@wenzi ~]#virsh snapshot-list rocky8-02
Name Creation Time State
---------------------------------------------------
1710230402 2024-03-12 16:00:02 +0800 running
[root@wenzi ~]#virsh snapshot-revert rocky8-02 --snapshotname 1710230402 --running
[root@wenzi ~]#virsh snapshot-list rocky8-02
Name Creation Time State
---------------------------------------------------
1710230402 2024-03-12 16:00:02 +0800 running
[root@wenzi ~]#virsh snapshot-delete rocky8-02 --snapshotname 1710230402
Domain snapshot 1710230402 deleted
[root@wenzi ~]#virsh snapshot-list rocky8-02
Name Creation Time State
-------------------------------
网络管理
官方文档:https://wiki.libvirt.org/VirtualNetworking.html
NAT模式(默认)
类似VMWare WorkStation的 NAT 模式。
允许多个设备共享单个公共 IP 地址,同时保持内部网络的私密性。
当启动kvm虚拟机后,每个虚拟机内部都有自己的网卡,有自己的IP
虚拟机1
[root@rocky85 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:a0:d9:49 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.154/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0
valid_lft 2758sec preferred_lft 2758sec
inet6 fe80::5054:ff:fea0:d949/64 scope link noprefixroute
valid_lft forever preferred_lft forever
虚拟机2
[root@rocky85 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.218/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0
valid_lft 2759sec preferred_lft 2759sec
inet6 fe80::5054:ff:fedd:cf49/64 scope link noprefixroute
valid_lft forever preferred_lft forever
在宿主机内也会生成对应的网络接口,在宿主机内查看ip信息
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#宿主机自身网卡
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:39:53 brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 192.168.28.60/24 brd 192.168.28.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:3953/64 scope link
valid_lft forever preferred_lft forever
#安装完KVM新产生的virbr0是由 libvirt 创建的虚拟网络接口,可实现虚拟机之间、虚拟机与宿主机之间通讯
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:cf:74:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
#kvm虚拟机启动后生成的网卡
7: vnet3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fedd:cf49/64 scope link
valid_lft forever preferred_lft forever
#kvm虚拟机启动后生成的网卡
8: vnet4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:a0:d9:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fea0:d949/64 scope link
valid_lft forever preferred_lft forever
且宿主机内生成的有Iptables规则,主要是SNAT地址转换,不要删除,误删除后可以通过systemctl restart libvirtd.socket 恢复规则。
在此网络模式下,kvm虚拟机内部可以访问外部网络(SNAT),但外部网络无法访问kvm虚拟机,因为有Iptables规则拒绝了。
[root@wenzi ~]#iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
#自定义链LIBVIRT_PRT作用在POSTROUTING链上,即为SNAT
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
228 17842 LIBVIRT_PRT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain LIBVIRT_PRT (1 references)
pkts bytes target prot opt in out source destination
1 40 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24
1 328 RETURN all -- * * 192.168.122.0/24 255.255.255.255
14 840 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
宿主机默认会安装dnsmasq-base包。在配置文件中可修改DHCP分配地址的范围,重启服务生效。
[root@wenzi ~]#dpkg -l dnsmasq-base
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-=====================-============-============================================
ii dnsmasq-base 2.90-0ubuntu0.22.04.1 amd64 Small caching DNS proxy and DHCP/TFTP server
配置文件
[root@wenzi ~]#grep -v "^#" /var/lib/libvirt/dnsmasq/default.conf
strict-order #指示 dnsmasq 按照配置文件中出现的顺序处理配置指令
user=libvirt-dnsmasq #指定运行 dnsmasq 服务的用户
pid-file=/run/libvirt/network/default.pid #指定 dnsmasq 进程 ID 文件的位置
except-interface=lo #排除 lo 接口,即不将 dnsmasq 服务应用于本地回环接口。
bind-dynamic #允许 dnsmasq 动态绑定到 DHCP 客户端请求的端口
interface=virbr0 #指定 dnsmasq 服务绑定到的网络接口
dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0 #定义 DHCP 服务分配的 IP 地址范围,
dhcp-no-override #指示 dnsmasq 不应覆盖从 DHCP 服务器接收到的设置
dhcp-authoritative #使 dnsmasq 成为权威 DHCP 服务器,它将为指定的 IP 地址范围提供 DHCP 服务,不会与其他 DHCP 服务器冲突
dhcp-lease-max=253 #DHCP 租约的最大有效时间为 253 秒
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile #指定一个包含静态 DHCP 映射的主机文件
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts #定一个附加的主机文件,用于定义本地 DNS 名称和 IP 地址映射。
Macvtap模式
一种虚拟网络设备类型,它提供了虚拟机(VM)和宿主机之间的虚拟网络接口。
Macvtap 设备模拟了一个以太网接口,允许虚拟机像物理设备一样参与到宿主机的网络中。
类似VMWare WorkStation的 桥接 模式。
实验
使用VMWare WorkStation做实验时,宿主机所处的NAT模式下的DHCP功能要打开,不然kvm虚拟机不会被分配宿主机同网段的地址。
kvm虚拟机新增一块网卡,Network source选择Macvtap device类型,Device name 填写eth0。(因为宿主机的网卡名字是eth0)
查看宿主机网卡变化
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:39:53 brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 192.168.28.60/24 brd 192.168.28.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:3953/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:cf:74:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
7: vnet3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fedd:cf49/64 scope link
valid_lft forever preferred_lft forever
8: vnet4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:a0:d9:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fea0:d949/64 scope link
valid_lft forever preferred_lft forever
#宿主机多出一块网卡,关键字 macvtap
13: macvtap5@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 500
link/ether 52:54:00:5f:56:9e brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fe5f:569e/64 scope link
valid_lft forever preferred_lft forever
查看kvm虚拟机网卡变化
[root@rocky85 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#原先默认nat的网卡
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.218/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0
valid_lft 2448sec preferred_lft 2448sec
inet6 fe80::5054:ff:fedd:cf49/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#新增的网卡,可见地址端不是192.168.122.0/24 网段的。是和宿主机在同一个网段
7: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:5f:56:9e brd ff:ff:ff:ff:ff:ff
inet 192.168.28.128/24 brd 192.168.28.255 scope global dynamic noprefixroute enp7s0
valid_lft 1782sec preferred_lft 1782sec
inet6 fe80::b150:8efb:f6c6:3277/64 scope link noprefixroute
valid_lft forever preferred_lft forever
此时kvm虚拟机可以和外部网络彼此通讯了。借此特性可实现如下架构:
vm1部署的对外web网站wordpress可以允许外部网络使用Macvtap生成的网卡进行通讯访问;
vm2部署的MySQL数据库连接至网桥和其它kvm虚拟机(vm1)进行通讯,外部网络无法访问数据库,安全性得到保证。
Bridge模式
类似VMWare WorkStation的 仅主机 模式。
实现kvm虚拟机彼此之间通讯,和宿主机通讯。
实验
--------------------------------------宿主机新建网桥
[root@wenzi ~]#apt -y install bridge-utils
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:39:53 brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 192.168.28.60/24 brd 192.168.28.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:3953/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:cf:74:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
7: vnet3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fedd:cf49/64 scope link
valid_lft forever preferred_lft forever
8: vnet4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:a0:d9:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fea0:d949/64 scope link
valid_lft forever preferred_lft forever
#当前结果是nat模式的结果
[root@wenzi ~]#brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400cf740b yes vnet3
vnet4
#新增网桥virbr1
[root@wenzi ~]#brctl addbr virbr1
修改kvm虚拟机网卡模式为Bridge。Device name 填写新增加的网桥名字virbr1
修改完毕后宿主机内查看,vnet3、vnet4已加入到virbr1网桥中。
[root@wenzi ~]#ip link set virbr1 up
[root@wenzi ~]#brctl stp virbr1 on
[root@wenzi ~]#brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400cf740b yes
virbr1 8000.4242c7ed1209 yes vnet3
vnet4
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:f2:39:53 brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 192.168.28.60/24 brd 192.168.28.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fef2:3953/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:cf:74:0b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
7: vnet3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr1 state UNKNOWN group default qlen 1000
link/ether fe:54:00:dd:cf:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fedd:cf49/64 scope link
valid_lft forever preferred_lft forever
8: vnet4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr1 state UNKNOWN group default qlen 1000
link/ether fe:54:00:a0:d9:49 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fea0:d949/64 scope link
valid_lft forever preferred_lft forever
14: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 42:42:c7:ed:12:09 brd ff:ff:ff:ff:ff:ff
inet6 fe80::4042:c7ff:feed:1209/64 scope link
valid_lft forever preferred_lft forever
查看kvm虚拟机ip。在此实验中因为修改的是NAT模式的网卡,所以ip未变化,依旧是192.168.122.0/24网段,但此时已经无法访问外部网络,也无法访问宿主机。kvm虚拟机在同一网段下彼此之间可以通讯。
修改kvm虚拟机IP为10.0.0.0/24 网段,直接改配置文件 /etc/sysconfig/network-scripts/ifcfg-enp1s0
#第一个虚拟机
[root@rocky85 ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp1s0
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=enp1s0
UUID=bdb250d2-3f46-4a9d-a944-21ee115cc5a3
DEVICE=enp1s0
ONBOOT=yes
IPADDR=10.0.0.11
PREFIX=24
#第二个虚拟机
[root@rocky85 ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp1s0
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
NAME=enp1s0
UUID=bdb250d2-3f46-4a9d-a944-21ee115cc5a3
DEVICE=enp1s0
ONBOOT=yes
IPADDR=10.0.0.21
PREFIX=24
#给宿主机内网桥virbr1设置IP
[root@wenzi ~]#ip a a 10.0.0.2 dev virbr1
#在宿主机内配置路由
[root@wenzi ~]#ip route add 10.0.0.0/24 via 10.0.0.2 dev virbr1
kvm虚拟机即可和宿主机通讯。