一、虚拟机镜像格式
目前,虚拟机的主流镜像格式有raw
、cow
、qcow
、qcow2
以及vmdk
,下面,我就详细介绍一下这些主流的虚拟机镜像格式。
1、raw格式
raw
格式是一种很早的镜像格式,格式比较原始、简单,性能上也还不错。并且raw
格式镜像的一个突出好处是它支持转换成其他格式的镜像,或者作为其他格式镜像转换的中间格式。但是,raw
格式的一个突出缺点就是不支持快照。 CentOS6
的虚拟机KVM
和XEN
默认使用raw
格式。
2、cow、qcow和qcow2格式
cow
、qcow
和qcow2
是另外的镜像格式,cow
格式、qcow
格式目前已经逐步被qcow2
格式所取代,qcow2
格式是目前的一种主流镜像格式,性能上与raw
格式相差无几,但是支持虚拟机快照。CentOS7
的KVM
虚拟机镜像默认使用qcow2
格式。
3、vmdk格式
vmdk
是Vmware
虚拟的镜像格式,其整体性能非常出色,稳定性和其他方面的能力很好,也支持快照。
二、KVM虚拟机
1、KVM简介
KVM
是由Quramnet
开发,08
年被RedHat
收购,目前KVM
由RedHat
工程师开发维护,准确来说,KVM(Kernel-based Virtual Machine)
只是一个linux
内核模块,包括核心虚拟化模块kvm.ko
,以及针对特定CPU
的模块kvm-intel.ko
或者kvm-amd.ko
,其实现需要宿主机CPU
支持硬件虚拟化,在x86
平台下,CPU
硬件虚拟化技术有Intel
的VT-x
,AMD
的 AMD-V
。
目前,由于kvm
良好发展,其能够运行在x86
, ARM
(Cortex A15, AArch64
),MIPS32
等平台下,因为vcpu
是由Host
硬件模拟,x86
平台下Host
上安装的kvm
能够虚拟出一颗x86
架构的vcpu
,却无法虚拟出arm
,Powerpc
等其它架构的vcpu
,同样arm
平台下安装的kvm
只能够虚拟出arm
架构的vcpu
。
2、QEMU/KVM
许多朋友可能都有过在自己 Windows
电脑上装 VMWare
或者 VirtualBox
跑虚拟机的经历,创建虚拟机前,需要准备一个 ISO
镜像,随后让你选择给虚拟机分配多大内存,多大磁盘等,一切准备好后,点击创建虚拟机,就可以看到熟悉的装机界面了,接下来就和在物理机上装系统一样。
在 Linux 环境下,我们也有相应的虚拟化解决方案——QEMU/KVM
,同样,我们创建虚拟机前,也要准备好镜像,以及定义好虚拟机的各种规格等。这里的镜像就是我们平时装操作系统用的镜像,里面只包括了引导程序和操作系统,而且装好后,这个镜像就不用了;从创建 KVM
虚拟机的过程来看,显然它对虚拟机的各种资源有更详细的描述,基本等同于创建了一个“物理机”了,毕竟物理机有的它都有。
Linux 下的虚拟化,最常见的虚拟化组合就是QEMU/KVM
了。QEMU
是一款开源的模拟器和虚拟机监视器(Virtual Machine Monitor, VMM
),是一套完整的开源的全虚拟化解决方案,它有两种使用方式:
-
第一种是单独使用,对宿主机硬件没什么要求,也并不要求宿主机 CPU
支持虚拟化,qemu
为虚拟机操作系统模拟整套硬件环境,虚拟机操作系统感觉不到自己运行在模拟的硬件环境中,这种纯软件模拟效率很低,但可以模拟出各种硬件设备,包括像软盘驱动器这样的老旧设备。 -
第二种是作为一个用户空间工具,和运行在内核中的 KVM
配合完成硬件环境的模拟,qemu1.3
版本之前,其有一个专门的分支版本qemu-kvm
作为KVM
的用户空间程序(centos6.x yum
源中就是这个),qemu-kvm
通过ioctl
调用/dev/kvm
这个接口与KVM
交互,这样KVM
在内核空间模拟虚拟机CPU
,qemu-kvm
负责模拟虚拟机I/O
设备。qemu1.3
及其以后版本中,qemu-kvm
分支代码已经合并到qemu
的master
分支中,因此在qemu 1.3
以上版本中,只需在编译qemu
时开启--enable-kvm
选项就能够是qemu
支持kvm
,具体说明可以查看qemu
官网。
从上面描述我们可以看到,QEMU
其实是一个纯软件实现的虚拟机模拟器,但虚拟化效率很低,因此配合 KVM
等一类 VMM
,利用 KVM
提供的硬件加速,使得在 QEMU
中运行的 CPU
指令,直接在宿主机的物理 CPU
上执行,使虚拟机的性能更高。KVM
已经是 Linux 平台下的一个内核模块了,它本身不实现任何模拟,运行于内核空间,仅仅是暴露了一个 /dev/kvm
接口,由运行于用户空间的 QEMU
与之交互。当虚拟机有 CPU
操作时,QEMU
将指令转交给 KVM
模块,而 IO
仍然由 QEMU
来完成。因此,由 QEMU/KVM
组合创建的虚拟机,被称为 KVM
虚拟机。
KVM
的基本架构可以用下图来表示:
三、创建虚拟机
1、准备工作
本文所用服务器宿主机为CentOS 8.5 Minimal 64
位,检查宿主机CPU
是否支持虚拟化:
[root@localhost ~]# cat /proc/cpuinfo | egrep '(vmx|svm)' | wc -l;
24
结果大于0
表示支持虚拟化,可以放心做KVM
虚拟化安装了。
注意:检索结果有
vmx
或者svm
就说明支持VT
;如果没有任何的输出,说明你的cpu
不支持,将无法成功安装KVM
虚拟机。
2、 安装 EPEL(可选)
EPEL
的全称叫 Extra Packages for Enterprise Linux
。EPEL
是由 Fedora
社区打造,用以创建、维护以及管理针对企业版 Linux 的一个高质量附加软件包集。EPEL
适用于 RHEL
及衍生发行版如 CentOS
等。装上了 EPEL
之后,就相当于添加了一个第三方源。
[root@localhost ~]# yum -y install epel-release
或
[root@localhost ~]# yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
[root@localhost ~]# rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
查看/etc/yum.repos.d/
目录,发现多了很多 epel*
的文件。
[root@localhost lxy]# ls -l /etc/yum.repos.d/
total 20
-rw-r--r-- 1 root root 2495 Aug 21 07:52 CentOS-Base.repo
-rw-r--r-- 1 root root 1680 Apr 17 15:22 epel-modular.repo
-rw-r--r-- 1 root root 1332 Apr 17 15:22 epel.repo
-rw-r--r-- 1 root root 1779 Apr 17 15:22 epel-testing-modular.repo
-rw-r--r-- 1 root root 1431 Apr 17 15:22 epel-testing.repo
3、安装kvm及相关软件包
查看kvm
模块是否安装,如果通过lsmod
能够检索到kvm
则说明已安装。否则需要通过命令行加载kvm
模块。
[root@localhost ~]# lsmod | grep kvm
kvm_intel 323584 0
kvm 880640 1 kvm_intel
irqbypass 16384 1 kvm
从Linux内核版本2.6.20
开始,kvm
模块就包含在Linux内核中,因此当通过lsmod
检索不到kvm
模块时,只需通过如下命令加载此模块即可。
#加载kvm模块(Intel VT)
modprobe kvm
modprobe kvm-intel
#注意:如果加载失败,说明服务器硬件不支持或BIOS中未开启虚拟化扩展
注意:Linux内核加载
kvm
模块之后
从宿主机中来看,Linux内核成为一个
hypervisor(VMM)
,虚拟机则实现为标准的Linux进程,启动一台虚拟机就是在宿主机上运行了一个进程(可以使用命令查看某个虚拟机对应的进程:ps -ef | grep "虚拟机名字"
),因此虚拟机可以接受linux调度程序的管理,vcpu
实现为Linux线程[root@localhost ~]# virsh list --all
Id Name State
----------------------------------------------------
2 Anolis7.9-QU1 running
[root@localhost ~]# ps -ef | grep Anolis7.9-QU1
root 30198 1 34 09:54 ? 00:00:18 /usr/libexec/qemu-kvm -name Anolis7.9-QU1 -S -machine pc-i440fx-rhel7.0.0,accel=kvm,usb=off,dump-guest-core=off -cpu Skylake-Server-IBRS,+spec-ctrl,+ssbd -m 2048 -realtime mlock=off -smp 2,sockets=2,cores=1,threads=1 -uuid 113f9a50-a69b-440e-8b66-93494da01a8d -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-2-Anolis7.9-QU1/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 -drive file=/var/lib/libvirt/images/Anolis7.9-QU1.qcow2,format=qcow2,if=none,id=drive-ide0-0-0 -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -drive if=none,id=drive-ide0-0-1,readonly=on -device ide-cd,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 -netdev tap,fd=26,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:95:f3:c9,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -vnc 0.0.0.0:0 -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -msg timestamp=on
root 30273 22131 0 09:55 pts/4 00:00:00 grep --color=auto Anolis7.9-QU1
KVM
需要借助Linux内核,因此KVM
运行在操作系统之上,幸运的是,kvm
模块已包含在Linux 内核2.6.20
版本及其以上版本中与
KVM
不同,Xen
的hypervisor
代码完全由自己开发,本身就是一套完整的虚拟机管理程序,因此Xen
可以直接安装在裸机上,不需要先安装操作系统,就像esxi
内核加载
kvm
模块后,其会暴露一个/dev/kvm
接口来与用户空间程序(qemu
)交互,提供模拟vcpu
,vmemory
的功能单靠内核中的
kvm
模块并不能启动一台虚拟机,其只能模拟vcpu
,vmemory
, 像io
设备的模拟还需要借助用户空间程序qemu
KVM
相关安装包及其作用:
qemu-kvm 主要的KVM程序包
virt-manager GUI虚拟机管理工具
virt-top 虚拟机统计命令
virt-viewer GUI连接程序,连接到已配置好的虚拟机
libvirt C语言工具包,提供libvirt的基础工具,包含了API和守护进程(libvirtd)以及命令行工具(virsh)
libvirt-client 为虚拟客户机提供的C语言工具包
virt-install 提供命令行工具来创建Domains(也就是虚拟机)
bridge-utils 创建和管理桥接设备的工具
安装KVM
核心软件包:
yum install -y bridge-utils virt-viewer virt-install qemu-kvm libvirt virt-manager libguestfs-tools xorg-x11-xauth
开启 KVM
服务 libvirt
并设置开机自启
#启动kvm管理工具
[root@localhost ~]# systemctl start libvirtd
#设为开机自动启动
[root@localhost ~]# systemctl enable libvirtd
查看 libvirt
当前的状态
[root@localhost ~]# systemctl status libvirtd
这样就是正在运行时(绿色的 running
)。
4、安装GNOME3(可选)
因本文所用服务器宿主机为CentOS 8.5 Minimal
版本,故需在Linux操作系统中安装GNOME3
桌面环境和GDM(GNOME Display Manager)
现实环境管理器才能使用图形用户界面安装或者管理虚拟机。非Minimal
版本的操作系统无需做这一节的操作。
首先列出网络源中可以使用的Groups
,命令如下:
[root@localhost ~]# yum grouplist
Last metadata expiration check: 0:31:49 ago on Wed 23 Aug 2023 04:44:41 AM SAST.
Available Environment Groups:
Server with GUI
Server
Minimal Install
Workstation
KDE Plasma Workspaces
Custom Operating System
Virtualization Host
Installed Groups:
Development Tools
Available Groups:
Legacy UNIX Compatibility
Container Management
.NET Core Development
Graphical Administration Tools
Headless Management
Network Servers
RPM Development Tools
Scientific Support
Security Tools
Smart Card Support
System Tools
Fedora Packager
Xfce
下一步我们需要“Available Environment Groups”
下面的“Server with GUI”
,而这个“Server with GUI”
环境包使用的桌面环境就是GNOME3
。下一步进行安装,下载大约1GB
的安装包:
[root@localhost ~]# yum groupinstall "Server with GUI"
Last metadata expiration check: 0:32:31 ago on Wed 23 Aug 2023 04:44:41 AM SAST.
No match for group package "insights-client"
No match for group package "rhc"
No match for group package "hpijs"
No match for group package "centos-linux-release-eula"
Dependencies resolved.
=========================================================================================================================================================================================================
Package Architecture Version Repository Size
=========================================================================================================================================================================================================
Upgrading:
kernel-tools x86_64 4.18.0-348.7.1.el8_5 base 7.2 M
kernel-tools-libs x86_64 4.18.0-348.7.1.el8_5 base 7.0 M
......
sssd-kcm x86_64 2.5.2-2.el8_5.3 base 254 k
systemd x86_64 239-51.el8_5.2 base 3.6 M
systemd-container x86_64 239-51.el8_5.2 base 751 k
......
Installing group/module packages:
ModemManager x86_64 1.10.8-4.el8 base 923 k
NetworkManager-adsl x86_64 1:1.32.10-4.el8 base 144 k
NetworkManager-bluetooth x86_64 1:1.32.10-4.el8 base 170 k
NetworkManager-config-server noarch 1:1.32.10-4.el8 base 131 k
NetworkManager-wifi x86_64 1:1.32.10-4.el8 base 190 k
NetworkManager-wwan x86_64 1:1.32.10-4.el8 base 176 k
......
file-roller x86_64 3.28.1-4.el8 AppStream 1.3 M
firefox x86_64 91.4.0-1.el8_5 AppStream 106 M
fprintd-pam x86_64 1.90.9-2.el8 AppStream 28 k
gdm x86_64 1:40.0-15.el8 AppStream 881 k
gedit x86_64 2:3.28.1-3.el8 AppStream 2.5 M
glx-utils x86_64 8.4.0-5.20181118git1830dcb.el8 AppStream 44 k
gnome-bluetooth x86_64 1:3.34.3-1.el8 AppStream 60 k
......
gnome-shell x86_64 3.32.2-40.el8 AppStream 1.5 M
gnome-terminal-nautilus x86_64 3.28.3-3.el8 AppStream 47 k
gnome-themes-standard x86_64 3.22.3-4.el8 AppStream 2.7 M
...
Complete!
1)设置GDM开机启动
安装完成后则需要设置GDM
开机启动,查看gdm.service
是否启动,发现gdm
服务没有启动。
[root@localhost ~]# systemctl status gdm
● gdm.service - GNOME Display Manager
Loaded: loaded (/usr/lib/systemd/system/gdm.service; enabled; vendor preset: enabled)
Active: inactive (dead)
下面设置gdm
开机启动,并立即启动该服务:
[root@localhost ~]# systemctl enable gdm --now
[root@localhost ~]# systemctl status gdm
● gdm.service - GNOME Display Manager
Loaded: loaded (/usr/lib/systemd/system/gdm.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2023-08-23 05:59:32 SAST; 1s ago
Main PID: 89393 (gdm)
Tasks: 4 (limit: 819691)
Memory: 4.0M
CGroup: /system.slice/gdm.service
└─89393 /usr/sbin/gdm
Aug 23 05:59:32 localhost.localdomain systemd[1]: Starting GNOME Display Manager...
Aug 23 05:59:32 localhost.localdomain systemd[1]: Started GNOME Display Manager.
设置系统启动级别为graphical
,默认情况下,CentOS8
默认启动级别为multi-user.target
,即永久命令行界面。
[root@localhost ~]# systemctl get-default
multi-user.target
下面设置CentOS8
的启动级别为graphical.target
,永久转变为图形化。
[root@localhost ~]# systemctl set-default graphical.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/graphical.target.
[root@localhost ~]#
[root@localhost ~]# systemctl get-default
graphical.target
设置完上面的配置之后,重启操作系统。
2)设置X11转发
欲在无桌面环境的 Linux 上运行 GUI
程序,则X11
转发需要首先了解一下。要想使用 X11
转发,首先要了解 X Window
。X Window System
(简写为 X11
) 是一种用于位图显示的窗口系统,在类 UNIX
操作系统非常常见。
X11
为GUI
环境提供了基本的框架,包括在屏幕上绘制和移动图像、监听鼠标键盘的操作等功能。同时X11
自由度比较高,同样是采用X11
方案的软件可能外观上有很大差异。
X11
是经典的C/S
架构,分为Server
和Client
,并定义了一系列协议用于C-S
间通信。X Server
负责图形界面的显示和用户的输入,而 X Client
需要连接到X Server
,请求X Server
绘制图形界面,同时从X Server
接受用户的输入并做出响应。
在带有桌面环境的系统上,X Server
和 X Client
安装在同一台机器上,但是 X Server
和 X Client
显然可以分别运行在不同的机器上,从而实现在一台机器上运行程序,而在另外一台机器上显示图形界面。
事实上,X Server
就像一个画布,Linux
上的 X Client
就像一个画家。Server
同显示器等硬件打交道,为画家(Client
)提供绘图的必要服务。画家处理数据并对用户的做出响应,在画布上展示出来。
举个实际的例子:假设此时你正在用一台 Windows
主机通过 SSH
连接到另一台 Linux
主机,要在Linux
上运行Wireshark
并把图像显示在Windows
上,那么X Server
在 Windows
上,X Client
在Linux
上。
看上去这有点违反直觉。不过只要记住:在哪里看到画面,哪里就有X Server
。
而X11
转发就是使用 SSH
转发X11
的流量。正如上文提到的,X Server
可以接受X Client
的连接并显示出画面,那么如果X Server
能够被随意连接就出大乱子了。所以很多时候X Server
是具有认证的,将X11
的流量暴露在公网上传输也是具有很大风险的。
这时SSH
的作用就很明显了,SSH
相当于一个隧道,X11
流量在其中是加密的,安全性大大提升。同时SSH
会在远程的Linux
主机上设置端口转发,这一点后面在操作部分会提到。
X Window System
有多种实现,在Windows
平台上,常用的X Server
软件是vcxsrv
。也有一些终端软件,内部集成了X Server
(例如 MobaXterm
)。本文则主要讲解内部集成了X Server
的MobaXterm
软件。
安装MobaXterm
后,确保主页面右上角的 X
图标为彩色(意为已经启动 X Server
)。
连接到服务器后, 检查X11
转发标志是否为对勾。
如果不是对勾,首先检查 /etc/ssh/sshd_config
中 X11Forwarding
选项是否为yes
,然后检查是否已经安装 xorg-x11-xauth
包,方法是运行 xauth list
命令,看是否有结果。其次检查 $DISPLAY
是否已经被设置,如果没有被设置可以尝试自行设置。需要注意的是,默认情况下 DISPLAY=localhost:10.0
就表明通过X11
转发到远程主机显示。
注意:如果
/etc/ssh/sshd_config
中X11Forwarding
选项被注释掉或者值设置为no
,则DISPLAY
环境变量的值为空。换一句话讲,当X11Forwarding
的值被设置为yes
,则DISPLAY
环境变量的值非空,且virt-manager
指令可以成功调用虚拟化控制台图形界面。
如果/etc/ssh/sshd_config
中 X11Forwarding
选项被注释或为no
,则需进行如下修改,设置X11Forwarding
的值为yes
。
[root@localhost ~]# vim /etc/ssh/sshd_config
......
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
......
接着,重新启动sshd
服务,如下所示:
[root@localhost ~]# service sshd restart
Redirecting to /bin/systemctl restart sshd.service
在此之后,重新进行ssh
连接,发现X11
转发标志已为对勾,且DISPLAY
环境变量的值为localhost:11.0
,而非空值。使用virt-manager
命令可以成功调用虚拟机控制台图形界面工具。
至此,成功实现虚拟机控制台图形界面工具安装。
【拓展】
DISPLAY
环境变量格式如下:host:NumA.NumB
;host
指X Server
所在的主机主机名或者ip
地址,NumA
表示端口偏移,NumB
表示屏幕编号,如果host
为空,则表示X Server
运行于本机, 并且图形程序(X Client
)使用unix socket
方式连接到X Server
,而不是TCP
方式。使用TCP
方式连接时,NumA
为连接的端口减去6000
的值, 如果NumA
为0
,则表示连接到6000
端口; 使用unix socket
方式连接时则表示连接的unix socket
的路径,如果为0
, 则表示连接到/tmp/.X11-unix/X0
。NumB
则几乎总是0
。可以通过
netstat -tnlp
命令查看tcp
连接方式时使用的端口号,一般6010
及以上表示图形程序(X Client
)连接到X Server
,此时如果X11Forwarding
的值未被设置为yes
,则可以通过手动方式设置export DISPLAY=localhost:$(60xx-6000).0
,这样也可成功调用虚拟化控制台图形界面工具。[root@localhost ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 2344/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1386/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1413/cupsd
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 2406/sshd: root@pts
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 2505/sshd: root@pts
tcp 0 0 127.0.0.1:6012 0.0.0.0:* LISTEN 2812/sshd: root@pts
tcp 0 0 127.0.0.1:6013 0.0.0.0:* LISTEN 3123/sshd: root@pts
tcp 0 0 127.0.0.1:6014 0.0.0.0:* LISTEN 3949/sshd: root@pts
tcp 0 0 127.0.0.1:6015 0.0.0.0:* LISTEN 6306/sshd: root@pts
tcp 0 0 127.0.0.1:5900 0.0.0.0:* LISTEN 3054/qemu-kvm
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 :::22 :::* LISTEN 1386/sshd
tcp6 0 0 ::1:631 :::* LISTEN 1413/cupsd
tcp6 0 0 ::1:6010 :::* LISTEN 2406/sshd: root@pts
tcp6 0 0 ::1:6011 :::* LISTEN 2505/sshd: root@pts
tcp6 0 0 ::1:6012 :::* LISTEN 2812/sshd: root@pts
tcp6 0 0 ::1:6013 :::* LISTEN 3123/sshd: root@pts
tcp6 0 0 ::1:6014 :::* LISTEN 3949/sshd: root@pts
tcp6 0 0 ::1:6015 :::* LISTEN 6306/sshd: root@pts屏幕编号:一台机器可能连接了多个屏幕,因此将所有屏幕从
0
开始编号加以区别。端口偏移:则是用来表示X Server
监听的端口号,监听端口的起始值是6000
,但是有可能被占用,所以需要加上偏移,直到找到一个没有被占用的可用端口。综上所述,对于上面图中变量内容,其含义是通知所有当前用户要启动的
X Client
程序,有一个能够进行图形显示的X Server
程序正在监听着localhost
的6011
端口,并且它的屏幕编号为0
,你们只需要往这个地址发送绘图指令就可以正常绘图了。
5、虚拟机创建
经过检索和查阅资料,总结了常见的虚拟机创建方法:virt-manager
虚拟机管理工具创建、virt-install
命令行创建、qemu-kvm
命令行创建。接下来让我们分别讲解一下相应的方法。
1、virt-manager创建虚拟机
A. 打开虚拟机管理工具(virt-manager),新建一个虚拟机
B. 设置虚拟机的安装方法
C. 创建虚拟机的存储卷
D. 选择虚拟机的安装镜像并设置安装系统类型
需提前下载好待安装的操作系统镜像iso文件,这里将该镜像文件保存在/home/image/
路径下。
E. 设置虚拟机的内存与CPU
F. 设置虚拟机的磁盘
G. 设置虚拟机的名称及网络
默认情况下,KVM
虚拟机是基于 NAT
的网络配置,只有同一宿主机的虚拟键之间可以互相访问,跨宿主机是不能访问的。虚拟机使用宿主机的网络访问公网,宿主机和虚拟机能互相访问,但不支持外部访问虚拟机。
I. 创建成功,登录虚拟机
2、virt-install创建虚拟机
virt-install
是一个虚拟机命令行安装工具,它能够为KVM
、Xen
或其它支持libvirt API
的hypervisor
创建虚拟机并完成GuestOS
安装;此外,它能够基于串行控制台、VNC
或SDL(Simple DirectMedia Layer)
支持文本或图形安装界面。安装过程可以使用本地的安装介质如CDROM
,也可以通过网络方式如NFS
、HTTP
或FTP
服务实现。对于通过网络安装的方式,virt-install
可以自动加载必要的文件以启动安装过程而无须额外提供引导工具。当然,virt-install
也支持PXE
方式的安装过程,也能够直接使用现有的磁盘映像直接启动安装过程。
虚拟机创建命令如下:
1)创建虚拟机磁盘
#使用qemu-img创建Anolis 7.9虚拟机的镜像,格式为qcow2,大小为20G
[root@localhost home]# qemu-img create -f qcow2 /var/lib/libvirt/images/Anolis7.9-QU1.qcow2 20G
Formatting '/var/lib/libvirt/images/Anolis7.9-QU1.qcow2', fmt=qcow2 size=21474836480 cluster_size=65536 lazy_refcounts=off refcount_bits=16
创建虚拟机磁盘文件之后,在/var/lib/libvirt/images
目录下会生成qcow2
格式的文件Anolis7.9-QU1.qcow2
,如下:
[root@localhost ~]# ls /var/lib/libvirt/images/
Anolis7.9-QU1.qcow2
2)创建虚拟机
使用virt-install
指令在宿主机命令行执行,附带如下参数或者其他参数创建虚拟机如下:
virt-install
--virt-type kvm
--name Anolis7.9-QU1
--ram 2048
--vcpus 2
--cdrom=/home/images/AnolisOS-7.9-QU1-x86_64-dvd.iso
--disk path=/var/lib/libvirt/images/Anolis7.9-QU1.qcow2
--network network=default
--graphics vnc,listen=0.0.0.0
--os-type linux
【常用参数解析】
–virt-type:虚拟机类型kvm;
–name:虚拟机名字;
–ram:虚拟机内存大小,以
MB
为单位;–vcpus:分配
CPU
核心数,最大与实体机CPU
核心数相同;–cdrom:输入系统
iso
镜像路径,用于系统安装;–disk:指定虚拟机的磁盘存储位置;
–network:指定虚拟机连接的网络配置,常用的两种:
bridge=BRIDGE
指定连接到host
上名为BRIDGE
的虚拟网桥上;network=NAME
指定连接到virsh
管控的名为NAME
的network
上;–graphics TYPE,opt1=val1,opt2=val2:可选项,指定
guest
图像显示配置,如果不需要图像显示,可以使用--graphics none
;
TYPE:指定显示类型,可以为 vnc、sdl、spice
或none
等,默认为vnc;port: TYPE
为vnc
或spice
时其监听的端口,若想指定端口加这条--vncport=5900
,默认端口为5900
,根据虚拟机数量依次增加5901、5902...
;listen: TYPE
为vnc
或spice
时所监听的IP地址,默认为127.0.0.1
,可以通过修改/etc/libvirt/qemu.conf
定义新的默认值;password: TYPE
为vnc
或spice
时,为远程访问监听的服务进指定认证密码;–noautoconsole:禁止自动连接至虚拟机的控制台;
–os-type:操作系统类型,如
linux
、unix
或windows
等。–os-variant:某类型操作系统的变体,如
rhel5
、fedora8
、debian10
等;该选项为可选的,不明确指定亦可。
拓展:使用
virt-install
构建虚拟机可能需要指定操作系统类型, 在配置之前, 我们需要了解到底有哪些可选值,查阅了下,可以使用osinfo-query
来完成。安装
osinfo-query
REHL/CentOS
yum -y install libosinfo
Debian/Ubuntu
apt -y install libosinfo-bin
下面就可以使用
osinfo-query
列出所有操作系统类型:[root@localhost ~]# osinfo-query os
Short ID | Name | Version | ID
----------------------+----------------------------------------------------+----------+-----------------------------------------
altlinux1.0 | Mandrake RE Spring 2001 | 1.0 | http://altlinux.org/altlinux/1.0
altlinux2.0 | ALT Linux 2.0 | 2.0 | http://altlinux.org/altlinux/2.0
altlinux2.2 | ALT Linux 2.2 | 2.2 | http://altlinux.org/altlinux/2.2
altlinux2.4 | ALT Linux 2.4 | 2.4 | http://altlinux.org/altlinux/2.4
altlinux3.0 | ALT Linux 3.0 | 3.0 | http://altlinux.org/altlinux/3.0
altlinux4.0 | ALT Linux 4.0 | 4.0 | http://altlinux.org/altlinux/4.0
altlinux4.1 | ALT Linux 4.1 | 4.1 | http://altlinux.org/altlinux/4.1
altlinux5 | ALT Linux 5.0.0 Ark | 5.0 | http://altlinux.org/altlinux/5
altlinux6 | ALT Linux 6.0.0 Centaurus | 6.0 | http://altlinux.org/altlinux/6
altlinux7 | ALT Linux 7.0.0 Centaurus | 7.0 | http://altlinux.org/altlinux/7
centos6.0 | CentOS 6.0 | 6.0 | http://centos.org/centos/6.0
centos6.1 | CentOS 6.1 | 6.1 | http://centos.org/centos/6.1
centos6.2 | CentOS 6.2 | 6.2 | http://centos.org/centos/6.2
centos6.3 | CentOS 6.3 | 6.3 | http://centos.org/centos/6.3
centos6.4 | CentOS 6.4 | 6.4 | http://centos.org/centos/6.4
centos6.5 | CentOS 6.5 | 6.5 | http://centos.org/centos/6.5
centos7.0 | CentOS 7.0 | 7.0 | http://centos.org/centos/7.0
debian1.0 | Debian Buzz | 1.1 | http://debian.org/debian/1.0
debian1.2 | Debian Rex | 1.2 | http://debian.org/debian/1.2
debian1.3 | Debian Bo | 1.3 | http://debian.org/debian/1.3
debian2.0 | Debian Hamm | 2.0 | http://debian.org/debian/2.0
debian2.1 | Debian Slink | 2.1 | http://debian.org/debian/2.1
debian2.2 | Debian Potato | 2.2 | http://debian.org/debian/2.2
debian3 | Debian Woody | 3 | http://debian.org/debian/3
debian3.1 | Debian Sarge | 3.1 | http://debian.org/debian/3.1
debian4 | Debian Etch | 4 | http://debian.org/debian/4
debian5 | Debian Lenny | 5 | http://debian.org/debian/5
debian6 | Debian Squeeze | 6 | http://debian.org/debian/6
debian7 | Debian Wheezy | 7 | http://debian.org/debian/7
debian8 | Debian Jessie | 8 | http://debian.org/debian/8
fedora-unknown | Fedora | unknown | http://fedoraproject.org/fedora/unknown
fedora1 | Fedora Core 1 | 1 | http://fedoraproject.org/fedora/1
fedora10 | Fedora 10 | 10 | http://fedoraproject.org/fedora/10
fedora11 | Fedora 11 | 11 | http://fedoraproject.org/fedora/11
fedora12 | Fedora 12 | 12 | http://fedoraproject.org/fedora/12
fedora13 | Fedora 13 | 13 | http://fedoraproject.org/fedora/13
fedora14 | Fedora 14 | 14 | http://fedoraproject.org/fedora/14
fedora15 | Fedora 15 | 15 | http://fedoraproject.org/fedora/15
fedora16 | Fedora 16 | 16 | http://fedoraproject.org/fedora/16
fedora17 | Fedora 17 | 17 | http://fedoraproject.org/fedora/17
fedora18 | Fedora 18 | 18 | http://fedoraproject.org/fedora/18
fedora19 | Fedora 19 | 19 | http://fedoraproject.org/fedora/19
fedora2 | Fedora Core 2 | 2 | http://fedoraproject.org/fedora/2
fedora20 | Fedora 20 | 20 | http://fedoraproject.org/fedora/20
fedora21 | Fedora 21 | 21 | http://fedoraproject.org/fedora/21
fedora22 | Fedora 22 | 22 | http://fedoraproject.org/fedora/22
fedora3 | Fedora Core 3 | 3 | http://fedoraproject.org/fedora/3
fedora4 | Fedora Core 4 | 4 | http://fedoraproject.org/fedora/4
fedora5 | Fedora Core 5 | 5 | http://fedoraproject.org/fedora/5
fedora6 | Fedora Core 6 | 6 | http://fedoraproject.org/fedora/6
fedora7 | Fedora 7 | 7 | http://fedoraproject.org/fedora/7
fedora8 | Fedora 8 | 8 | http://fedoraproject.org/fedora/8
fedora9 | Fedora 9 | 9 | http://fedoraproject.org/fedora/9
......
virt-install
命令执行后,会自动调出控制台图形用户界面,随后即可通过控制台界面逐步安装虚拟机操作系统,最终成功创建虚拟机,具体步骤如下:
A. 命令行调用virt-install
,调出控制台图形界面新建虚拟机
B. 控制台图形界面内选择将要安装的操作系统Anolis OS 7
C. 控制台图形界面选择安装过程中使用的语言
D. 控制台图形界面设置待安装的软件和系统
E. 控制台图形界面设置root账户和密码
F. 控制台图形界面重新启动虚拟机
G. 进入虚拟机登录控制台界面
H. 关掉控制台图形界面,virt-install命令行退出
每个虚拟机创建后,其配置信息保存在/etc/libvirt/qemu
目录中,文件名与虚拟机相同,格式为XML
。
[root@localhost ~]# ls -l /etc/libvirt/qemu
total 4
-rw------- 1 root root 3569 Aug 25 14:00 Anolis7.9-QU1.xml
drwx------ 3 root root 42 Aug 23 03:55 networks
3、qemu-kvm创建虚拟机
qemu-kvm
命令行创建虚拟机分为两种方式:直接启动虚拟磁盘文件为虚拟机和通过iso
镜像文件安装虚拟机。下面我们主要讲解通过iso
镜像文件创建虚拟机。
首先,由于qemu-kvm
在安装kvm
及相关软件包阶段已安装,因此,这里只需进行软链接设置,使可以直接通过命令行执行qemu-kvm
命令,否则会提示找不到命令。
[root@localhost ~]# qemu-kvm -h
bash: qemu-kvm: command not found...
#设置软链接
[root@localhost ~]# ln -vs /usr/libexec/qemu-kvm /usr/bin/
'/usr/bin/qemu-kvm' -> '/usr/libexec/qemu-kvm
随后,自行下载并准备好iso
镜像文件。
[root@localhost ~]# ls /home/images/
AnolisOS-7.9-QU1-x86_64-dvd.iso
安装vnc
客户端和x11
需要的插件。
[root@localhost ~]# yum install tigervnc xorg-x11-xauth -y
创建qcow2
磁盘文件,如下:
[root@localhost ~]# qemu-img create -f qcow2 /var/lib/libvirt/images/Anolis7.9.qcow2 10G
Formatting '/var/lib/libvirt/images/Anolis7.9.qcow2', fmt=qcow2 size=10737418240 cluster_size=65536 lazy_refcounts=off refcount_bits=16
通过qemu-kvm
命令创建虚拟机,如下:
[root@localhost ~]# qemu-kvm -name 'anolis7.9' -cpu host -smp 2 -m 2048m -drive file=/var/lib/libvirt/images/Anolis7.9.qcow2 -cdrom /home/images/AnolisOS-7.9-QU1-x86_64-dvd.iso -daemonize
VNC server running on ::1:5900
【常用参数解析】
-name:指定客户机名称可用于宿主机上唯一标识该客户机;
-cpu :指定
cpu
模型,默认的cpu
模型为qemu64,"-cpu ?"
可以查询当前qemu-kvm
支持哪些cpu
模型;[root@localhost ~]# qemu-kvm -cpu ?
Available CPUs:
x86 486 (alias configured by machine type)
x86 486-v1
x86 Broadwell (alias configured by machine type)
x86 Broadwell-IBRS (alias of Broadwell-v3)
x86 Broadwell-noTSX (alias of Broadwell-v2)
x86 Broadwell-noTSX-IBRS (alias of Broadwell-v4)
x86 Broadwell-v1 Intel Core Processor (Broadwell)
x86 Broadwell-v2 Intel Core Processor (Broadwell, no TSX)
x86 Broadwell-v3 Intel Core Processor (Broadwell, IBRS)
x86 Broadwell-v4 Intel Core Processor (Broadwell, no TSX, IBRS)
x86 Cascadelake-Server (alias configured by machine type)
x86 Cascadelake-Server-noTSX (alias of Cascadelake-Server-v3)
x86 Cascadelake-Server-v1 Intel Xeon Processor (Cascadelake)
x86 Cascadelake-Server-v2 Intel Xeon Processor (Cascadelake)
x86 Cascadelake-Server-v3 Intel Xeon Processor (Cascadelake)
x86 Conroe (alias configured by machine type)
x86 Conroe-v1 Intel Celeron_4x0 (Conroe/Merom Class Core 2)
x86 Cooperlake (alias configured by machine type)
x86 Cooperlake-v1 Intel Xeon Processor (Cooperlake)
x86 Denverton (alias configured by machine type)
x86 Denverton-v1 Intel Atom Processor (Denverton)
x86 Dhyana (alias configured by machine type)
x86 Dhyana-v1 Hygon Dhyana Processor
x86 EPYC (alias configured by machine type)
x86 EPYC-IBPB (alias of EPYC-v2)
x86 EPYC-Milan (alias configured by machine type)
x86 EPYC-Milan-v1 AMD EPYC-Milan Processor
x86 EPYC-Rome (alias configured by machine type)
x86 EPYC-Rome-v1 AMD EPYC-Rome Processor
x86 EPYC-v1 AMD EPYC Processor
x86 EPYC-v2 AMD EPYC Processor (with IBPB)
x86 Haswell (alias configured by machine type)
x86 Haswell-IBRS (alias of Haswell-v3)
x86 Haswell-noTSX (alias of Haswell-v2)
x86 Haswell-noTSX-IBRS (alias of Haswell-v4)
x86 Haswell-v1 Intel Core Processor (Haswell)
x86 Haswell-v2 Intel Core Processor (Haswell, no TSX)
x86 Haswell-v3 Intel Core Processor (Haswell, IBRS)
x86 Haswell-v4 Intel Core Processor (Haswell, no TSX, IBRS)
x86 Icelake-Client (alias configured by machine type)
x86 Icelake-Client-noTSX (alias of Icelake-Client-v2)
x86 Icelake-Client-v1 Intel Core Processor (Icelake)
x86 Icelake-Client-v2 Intel Core Processor (Icelake)
x86 Icelake-Server (alias configured by machine type)
x86 Icelake-Server-noTSX (alias of Icelake-Server-v2)
x86 Icelake-Server-v1 Intel Xeon Processor (Icelake)
x86 Icelake-Server-v2 Intel Xeon Processor (Icelake)
x86 Icelake-Server-v3 Intel Xeon Processor (Icelake)
x86 IvyBridge (alias configured by machine type)
x86 IvyBridge-IBRS (alias of IvyBridge-v2)
x86 IvyBridge-v1 Intel Xeon E3-12xx v2 (Ivy Bridge)
x86 IvyBridge-v2 Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)
x86 KnightsMill (alias configured by machine type)
x86 KnightsMill-v1 Intel Xeon Phi Processor (Knights Mill)
x86 Nehalem (alias configured by machine type)
x86 Nehalem-IBRS (alias of Nehalem-v2)
x86 Nehalem-v1 Intel Core i7 9xx (Nehalem Class Core i7)
x86 Nehalem-v2 Intel Core i7 9xx (Nehalem Core i7, IBRS update)
x86 Opteron_G1 (alias configured by machine type)
x86 Opteron_G1-v1 AMD Opteron 240 (Gen 1 Class Opteron)
x86 Opteron_G2 (alias configured by machine type)
x86 Opteron_G2-v1 AMD Opteron 22xx (Gen 2 Class Opteron)
x86 Opteron_G3 (alias configured by machine type)
x86 Opteron_G3-v1 AMD Opteron 23xx (Gen 3 Class Opteron)
x86 Opteron_G4 (alias configured by machine type)
x86 Opteron_G4-v1 AMD Opteron 62xx class CPU
x86 Opteron_G5 (alias configured by machine type)
x86 Opteron_G5-v1 AMD Opteron 63xx class CPU
x86 Penryn (alias configured by machine type)
x86 Penryn-v1 Intel Core 2 Duo P9xxx (Penryn Class Core 2)
x86 SandyBridge (alias configured by machine type)
x86 SandyBridge-IBRS (alias of SandyBridge-v2)
x86 SandyBridge-v1 Intel Xeon E312xx (Sandy Bridge)
x86 SandyBridge-v2 Intel Xeon E312xx (Sandy Bridge, IBRS update)
x86 Skylake-Client (alias configured by machine type)
x86 Skylake-Client-IBRS (alias of Skylake-Client-v2)
x86 Skylake-Client-noTSX-IBRS (alias of Skylake-Client-v3)
x86 Skylake-Client-v1 Intel Core Processor (Skylake)
x86 Skylake-Client-v2 Intel Core Processor (Skylake, IBRS)
x86 Skylake-Client-v3 Intel Core Processor (Skylake, IBRS)
x86 Skylake-Server (alias configured by machine type)
x86 Skylake-Server-IBRS (alias of Skylake-Server-v2)
x86 Skylake-Server-noTSX-IBRS (alias of Skylake-Server-v3)
x86 Skylake-Server-v1 Intel Xeon Processor (Skylake)
x86 Skylake-Server-v2 Intel Xeon Processor (Skylake, IBRS)
x86 Skylake-Server-v3 Intel Xeon Processor (Skylake, IBRS)
x86 Snowridge (alias configured by machine type)
x86 Snowridge-v1 Intel Atom Processor (SnowRidge)
x86 Snowridge-v2 Intel Atom Processor (Snowridge, no MPX)
x86 Westmere (alias configured by machine type)
x86 Westmere-IBRS (alias of Westmere-v2)
x86 Westmere-v1 Westmere E56xx/L56xx/X56xx (Nehalem-C)
x86 Westmere-v2 Westmere E56xx/L56xx/X56xx (IBRS update)
x86 athlon (alias configured by machine type)
x86 athlon-v1 QEMU Virtual CPU version 2.5+
x86 core2duo (alias configured by machine type)
x86 core2duo-v1 Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz
x86 coreduo (alias configured by machine type)
x86 coreduo-v1 Genuine Intel(R) CPU T2600 @ 2.16GHz
x86 kvm32 (alias configured by machine type)
x86 kvm32-v1 Common 32-bit KVM processor
x86 kvm64 (alias configured by machine type)
x86 kvm64-v1 Common KVM processor
x86 n270 (alias configured by machine type)
x86 n270-v1 Intel(R) Atom(TM) CPU N270 @ 1.60GHz
x86 pentium (alias configured by machine type)
x86 pentium-v1
x86 pentium2 (alias configured by machine type)
x86 pentium2-v1
x86 pentium3 (alias configured by machine type)
x86 pentium3-v1
x86 phenom (alias configured by machine type)
x86 phenom-v1 AMD Phenom(tm) 9550 Quad-Core Processor
x86 qemu32 (alias configured by machine type)
x86 qemu32-v1 QEMU Virtual CPU version 2.5+
x86 qemu64 (alias configured by machine type)
x86 qemu64-v1 QEMU Virtual CPU version 2.5+
x86 base base CPU model type with no features enabled
x86 host KVM processor with all supported host features
x86 max Enables all features supported by the accelerator in the current host注意:如果想尽可能多的将宿主机的
CPU
特性暴露给客户机使用,则可以使用"-cpu host"
参数。使用"-cpu host"
参数会带来动态迁移的限制,不让客户机在不同的cpu硬件上迁移;-smp:
-smp n[,scores=scores][,threads=threads][,sockets=sockets]
,设置客户机总共有n
个逻辑CPU
,并设置了其中CPU socket
的数量、每个socket
上核心(core
)的数量、每个核心上的线程(thread
)数量。其中:n = sockets x cores x threads
;-m megs:设置客户机内存大小为
megs MB
。默认单位:MB
,可设置GB
;-drive:详细的配置一个驱动。例如:
-drive file=/images/centos7.img,if=virtio,cache=writeback
使用virtio_blk
驱动 和 磁盘回写机制来支持该磁盘文件;-cdrom:输入系统
iso
镜像路径,用于系统安装;-daemonize:在启动时让
qemu-kvm
作为守护进程在后台运行。如果没有该参数,默认qemu-kvm
在启动客户机后就会占用标准输入输出,直到客户机退出;-nographic:让客户机以命令行的方式在当前终端启动显示。
如果这里召唤不出界面,建议重新开启一个终端执行。
[root@localhost ~]# vncviewer :5900
全流程如下所示:
至此,通过qemu-kvm
命令行安装虚拟机成功完成。
四、登录KVM虚拟机
成功安装KVM
虚拟机以后,该如何登录到KVM
虚拟机呢?经过查询资料得知,可以通过三种方式登录,分别是virt-manager
、virt-viewer
和virsh console ID
。
1、virt-manager
virt-manager
是一套虚拟机的桌面管理器,像VMware
的vCenter
和xenCenter
差不多,工具提供了虚拟机管理的基本功能,如开机,挂起,重启,关机,强制关机/重启,迁移等,并且可以进入虚拟机图形界面进行操作。该工具还可以管理各种存储以及网络方面。
2、vncviewer
vncviewer
命令来自英文词组“VNC viewer”的拼写,中文译为“VNC查看器”,其功能是用于连接VNC
服务器。VNC
全称为“Virtual Network Console”,是一种虚拟网络控制台协议,也是著名的AT&T公司研发的一款远程控制软件的名字。其中vncviewer
命令则是连接VNC
协议的客户端,输入正确的目标主机地址及端口号后即可进行图形化的远程控制,弥补了SSH
协议只能命令行文字控制的遗憾。
首先查询虚拟机vnc
端口:
[root@localhost ~]# virsh vncdisplay Anolis7.9-QU1
:0
【解析】:0 即 为 5900 端口,以此类推 :1为5901 。
随后,直接通过vncviewer :5900
命令行登录虚拟机,如下:
3、virt-viewer
RHEL
还提供了一个mini
化的命令行工具 virt-viewer
来显示虚拟机的图形控制台。这个图形控制台可以使用 vnc
或 spice
协议,虚拟机访问可以引用为虚拟机名字,ID
或UUID
。
如果虚拟机还没有启动,virt-viewer
可以设置成在尝试连接到控制台前处于等待。virt-viewer
虽然没有提供 virt-manager
完整的功能,但是需要的资源少,并且大多数情况下, virt-viewer
不需要 libvirt
的读写权限,所以可以提供给不需要配置功能的普通用户。
virt-viewer
使用方法:
virt-viewer [OPTIONS] {guest-name|id|uuid}
下面让我们通过例子来演示virt-viewer
使用方法:
点击connect
以后,弹出如下虚拟机控制台登录界面,输入用户名和密码即可成功登录。
除此以外,virt-viewer
后也可以直接跟虚拟机ID
号,虚拟机ID
号可以通过virsh list --all
命令显示。然后直接进入虚拟机图形化控制台登录界面,如果非初次登录可能无需再输入用户名和密码即可成功登录。演示如下:
KVM
中宿主机通过console
无法连接客户机,卡在这里不动。
在使用 virt-install
创建虚拟机的时候,首先把一些要使用的程序包安装:
yum install virt-viewer dejavu-sans-fonts.noarch xorg-x11-xauth -y
说明:
virt-viewer 用于通过vnc直接查看虚拟机控制台
dejavu-sans-fonts.noarch xorg-x11-xauth 用于通过 xmanager直接界面访问
4、virsh console
安装完KVM
虚拟机后,直接通过宿主机执行virsh console
无法连接虚拟客户机,会卡在如下这里动弹不得:
执行Ctrl + C
也无济于事,依然卡在这里动弹不得,只得杀死虚拟机,重新再起新的虚拟机才能退出卡住的页面。
为什么会导致这样的情况呢?因为我们还未开启console
功能。为什么要开启console
功能呢?因为只有开启console
功能,我们才能通过类似ssh
的方式登录虚拟机,才可以复制粘贴一些命令行,否则则只能通过图形登录界面手动敲击命令执行,无法复制粘贴命令。接下来让我们一起学习如何开启console
功能。
1)添加ttyS0
的许可,允许root登陆
[root@localhost ~]# echo "ttyS0" >> /etc/securetty
2)编辑/etc/grub2.conf
,加入console=ttyS0
在/etc/grub2.conf
文件中为内核添加参数:
console=ttyS0
这步要注意:console=ttyS0
一定要放在kernel
这行中(大约在第100行),不能单独一行,即console=ttyS0
是kernel
的一个参数,不是单独的,如下:
3)编辑/etc/inittab
在最后一行加入内容 S0:12345:respawn:/sbin/agetty ttyS0 115200
[root@localhost ~]# cat -n /etc/inittab
1 # inittab is no longer used when using systemd.
2 #
3 # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
4 #
5 # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
6 #
7 # systemd uses 'targets' instead of runlevels. By default, there are two main targets:
8 #
9 # multi-user.target: analogous to runlevel 3
10 # graphical.target: analogous to runlevel 5
11 #
12 # To view current default target, run:
13 # systemctl get-default
14 #
15 # To set a default target, run:
16 # systemctl set-default TARGET.target
17 #
18 S0:12345:respawn:/sbin/agetty ttyS0 115200
4)重启服务器
[root@localhost ~]# reboot
5)在宿主机上测试连接
[root@localhost home]# virsh list --all
Id Name State
----------------------------------------------------
1 centos-build running
6 Anolis7.9-QU1 running
......
[root@localhost home]# virsh console 6
Connected to domain Anolis7.9-QU1
Escape character is ^]
Anolis OS 7.9
Kernel 4.19.91-26.4.an7.x86_64 on an x86_64
localhost login:
Anolis OS 7.9
Kernel 4.19.91-26.4.an7.x86_64 on an x86_64
localhost login: root
密码:
Last login: Mon Aug 21 19:56:14 on tty1
注意:按 ctrl+] 组合键退出virsh console
6)更新虚拟机内核参数
在KVM
虚拟机里执行更新内核参数的命令,然后reboot
重启虚拟机后即可生效。具体如下:
#执行grubby命令更新虚拟机内核参数后,kernel行均会包含console=ttyS0参数
[root@localhost ~]# grubby --update-kernel=ALL --args="console=ttyS0"
# kernel行均包含console=ttyS0参数
[root@localhost ~]# grubby --info=ALL
index=0
kernel=/boot/vmlinuz-4.19.91-26.4.an7.x86_64
args="ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=ao/root rd.lvm.lv=ao/swap rhgb quiet LANG=zh_CN.UTF-8 console=ttyS0"
root=/dev/mapper/ao-root
initrd=/boot/initramfs-4.19.91-26.4.an7.x86_64.img
title=Anolis OS (4.19.91-26.4.an7.x86_64) 7.9
index=1
kernel=/boot/vmlinuz-0-rescue-113f9a50a69b440e8b6693494da01a8d
args="ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=ao/root rd.lvm.lv=ao/swap rhgb quiet console=ttyS0"
root=/dev/mapper/ao-root
initrd=/boot/initramfs-0-rescue-113f9a50a69b440e8b6693494da01a8d.img
title=Anolis OS (0-rescue-113f9a50a69b440e8b6693494da01a8d) 7.9
index=2
non linux entry
[root@localhost ~]# reboot
Rebooting.
[47867.919293] reboot: Restarting system
[ 0.555052] integrity: Unable to open file: /etc/keys/x509_ima.der (-2)
[ 0.555053] integrity: Unable to open file: /etc/keys/x509_evm.der (-2)
Anolis OS 7.9
Kernel 4.19.91-26.4.an7.x86_64 on an x86_64
localhost login: root
密码:
Last login: Mon Aug 21 19:56:33 on ttyS0
[root@localhost ~]#
通过grubby
命令更新虚拟机内核参数后,我们查看/etc/grub2.cfg
文件会发现内核启动行的参数最后均会跟着console=ttyS0
参数。
[root@localhost ~]# cat /etc/grub2.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -s $prefix/grubenv ]; then
load_env
fi
......
### BEGIN /etc/grub.d/01_users ###
if [ -f ${prefix}/user.cfg ]; then
source ${prefix}/user.cfg
if [ -n "${GRUB2_PASSWORD}" ]; then
set superusers="root"
export superusers
password_pbkdf2 root ${GRUB2_PASSWORD}
fi
fi
### END /etc/grub.d/01_users ###
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Anolis OS (4.19.91-26.4.an7.x86_64) 7.9' --class anolis --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-4.19.91-26.4.an7.x86_64-advanced-36733d05-198d-4c6f-91fe-a3b86bd4d21e' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' b544030d-0a8c-49c4-9c43-9cc5a10c9074
else
search --no-floppy --fs-uuid --set=root b544030d-0a8c-49c4-9c43-9cc5a10c9074
fi
linux16 /vmlinuz-4.19.91-26.4.an7.x86_64 root=/dev/mapper/ao-root ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=ao/root rd.lvm.lv=ao/swap rhgb quiet LANG=zh_CN.UTF-8 console=ttyS0
initrd16 /initramfs-4.19.91-26.4.an7.x86_64.img
}
menuentry 'Anolis OS (0-rescue-113f9a50a69b440e8b6693494da01a8d) 7.9' --class anolis --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-113f9a50a69b440e8b6693494da01a8d-advanced-36733d05-198d-4c6f-91fe-a3b86bd4d21e' {
load_video
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' b544030d-0a8c-49c4-9c43-9cc5a10c9074
else
search --no-floppy --fs-uuid --set=root b544030d-0a8c-49c4-9c43-9cc5a10c9074
fi
linux16 /vmlinuz-0-rescue-113f9a50a69b440e8b6693494da01a8d root=/dev/mapper/ao-root ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=ao/root rd.lvm.lv=ao/swap rhgb quiet console=ttyS0
initrd16 /initramfs-0-rescue-113f9a50a69b440e8b6693494da01a8d.img
}
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
......
五、配置KVM虚拟机网络
虽然使用virsh console
方式可以登录连接虚拟机,但是此操作只允许打开一个会话,如下示例为在打开了一个虚拟机会话后,另外开启一个会话再次通过virsh console
登录虚拟机,结果发现会报错。
[root@localhost home]# virsh console 6
Connected to domain Anolis7.9-QU1
Escape character is ^]
error: operation failed: Active console session exists for this domain #错误:操作失败: 这个域有活跃控制台会话
因此还需要配置KVM
虚拟机网络,使我们可以直接ssh
进去,这样就可以打开多个会话了。
KVM
虚拟机网络配置主要有两种方式:NAT
方式和Bridge
方式。KVM
虚拟机默认能使用NAT
方式转发通信,但NAT
方式容易受防火墙等网络环境的限制,并且性能有时也会成为瓶颈,KVM
生产中使用Bridge
桥接方式。
KVM虚拟机网络配置的两种方式:
用户网络( User Networking
):让虚拟机访问主机、互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整。【NAT
方式】虚拟网桥( Virtual Bridge
):这种方式要比用户网络复杂一些,但是设置好后客户机与互联网,客户机与主机之间的通信都很容易。【Bridge
方式】
让我们一起先来看看KVM
的NAT
网络模型是什么样的。
1、NAT网络
在安装KVM
后,会自动创建一个默认的NAT
网络,虚拟机可以使用这个NAT
网络访问外部网络,这个NAT
网络由一个虚拟交换机和若干iptables
规则组成,这样说可能不太容易理解,我们来看一张示意图。
通过示意图可以看出,在KVM
的NAT
网络中,虚拟机连接到虚拟交换机,经过iptables
规则的nat
处理,利用宿主机的物理网卡eth0
与物理交换机所在的网络通讯,但是需要注意,这里的iptables
规则只是对虚拟机的ip
地址进行了snat
(源地址转换)处理,并没有进行dnat
(目标地址转换)处理,所以,虚拟机可以直接访问物理交换机所在的网络,但是物理交换机所在网络的其他主机,无法直接访问虚拟机,如果想要在物理交换机所在的网络直接访问虚拟机中的服务,则需要手动的进行dnat
,为了方便描述,下文将物理交换机所在的网络称之为”外部网络”,这里说的外部网络不是公网,而是办公环境的网络,也就上图中物理交换机所在的网络,”外部网络”的”外部”是针对KVM
虚拟机而言的。
为了更加具象化的理解上面的示意图,我们可以通过命令,查看一下这些设置。
在宿主机中,执行ip a
命令,可以看到如下信息:
[root@localhost ~]# 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: eno8303: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether ec:2a:72:10:14:32 brd ff:ff:ff:ff:ff:ff
inet 10.8.8.15/24 brd 10.8.8.255 scope global dynamic noprefixroute eno8303
valid_lft 4222sec preferred_lft 4222sec
inet6 fe80::ee2a:72ff:fe10:1432/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: eno8403: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether ec:2a:72:10:14:33 brd ff:ff:ff:ff:ff:ff
4: idrac: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether ec:2a:72:1a:70:6b brd ff:ff:ff:ff:ff:ff
6: ens5f1np1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 8c:1f:64:30:6f:54 brd ff:ff:ff:ff:ff:ff
7: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:d8:52:96 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
8: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:d8:52:96 brd ff:ff:ff:ff:ff:ff
12: ens5f0np0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 8c:1f:64:30:6f:53 brd ff:ff:ff:ff:ff:ff
上述信息中,eno8303
是宿主机的物理网卡,virbr0
是KVM
为默认NAT
网络创建的虚拟交换机,当使用默认NAT
网络时,虚拟机会连接到virbr0
交换机,由于我没有启动任何虚拟机,所以不太容易观察到对应网卡的变化,如果我们启动一个虚拟机,KVM
会自动创建出一个新的虚拟网卡,我们来做个实验,启动一个提前配置好的虚拟机Anolis7.9-QU1
,如下所示:
[root@localhost ~]# virsh list --all
Id Name State
-------------------------------
1 Anolis7.9-QU1 running
启动Anolis7.9-QU1
虚拟机后,再次使用ip a
命令查看网卡信息,可以看到比没有启动虚拟机之前,多出了一个网卡,如下:
[root@localhost ~]# 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: eno8303: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether ec:2a:72:10:14:32 brd ff:ff:ff:ff:ff:ff
inet 10.8.8.15/24 brd 10.8.8.255 scope global dynamic noprefixroute eno8303
valid_lft 4198sec preferred_lft 4198sec
inet6 fe80::ee2a:72ff:fe10:1432/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: eno8403: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether ec:2a:72:10:14:33 brd ff:ff:ff:ff:ff:ff
4: idrac: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether ec:2a:72:1a:70:6b brd ff:ff:ff:ff:ff:ff
6: ens5f1np1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 8c:1f:64:30:6f:54 brd ff:ff:ff:ff:ff:ff
7: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:d8:52:96 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
8: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:d8:52:96 brd ff:ff:ff:ff:ff:ff
13: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:d9:40:6c brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fed9:406c/64 scope link
valid_lft forever preferred_lft forever
如上所示,启动Anolis7.9-QU1
后,多出了一个vnet0
网卡,vnet0
网卡的作用就是为了让Anolis7.9-QU1
虚拟机能够连接到virbr0
交换机,我们可以这样想象,有一根网线,网线的一头插在Anolis7.9-QU1
虚拟机上,另一头插在virbr0
上,如果网线想要插在主机或者交换机上,总要有网线口吧,Anolis7.9-QU1
虚拟机的网线口在虚机内部的虚拟网卡上,交换机的网线口就是vnet0
这个虚拟网卡,只不过vnet0
这个网卡(网线口)是单独为了Anolis7.9-QU1
准备的,执行brctl show
命令,可以更加清楚的看到virbr0
和vnet0
的关系,如下:
#执行brctl命令前,需要安装bridge-utils包
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400d85296 yes virbr0-nic
vnet0
可以看到,当前有一个桥设备,名字叫virbr0
,也就是virbr0
虚拟交换机,他有两个接口(网线口),virbr0-nic
和vnet0
,其中,virbr0-nic
接口负责和宿主机的eno
网卡连,vnet0
接口负责和Anolis7.9-QU1
虚拟机的ens
网卡连,这样想象就应该有画面了吧。
我们还可以模拟一下拔网线和插网线,验证一下我们的想法,用ifconfig vnet0 down
命令和ifconfig vnet0 up
命令,模拟拔下和插上虚拟交换机这头的网线,然后观察Anolis7.9-QU1
虚拟机中的网络是否通畅。如下:
#宿主机中down掉vnet0接口
[root@localhost ~]# ifconfig vnet0 down
#查看虚拟机中网络接口情况
[root@localhost ~]# 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: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:d9:40:6c brd ff:ff:ff:ff:ff:ff
inet 192.168.122.158/24 brd 192.168.122.255 scope global noprefixroute dynamic ens3
valid_lft 3289sec preferred_lft 3289sec
inet6 fe80::3a0f:b6d3:e2ea:96e9/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:57:06:1f brd ff:ff:ff:ff:ff:ff
inet 192.168.124.1/24 brd 192.168.124.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:57:06:1f brd ff:ff:ff:ff:ff:ff
#在虚拟机中ping与宿主机同局域网下的其他物理主机,发现已无法ping通
[root@localhost ~]# ping 10.8.13.17
PING 10.8.13.17 (10.8.13.17) 56(84) bytes of data.
--- 10.8.13.17 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1020ms
#宿主机中开启vnet0接口
[root@localhost ~]# ifconfig vnet0 up
#查看虚拟机中网络情况
[root@localhost ~]# 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: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:d9:40:6c brd ff:ff:ff:ff:ff:ff
inet 192.168.122.158/24 brd 192.168.122.255 scope global noprefixroute dynamic ens3
valid_lft 3345sec preferred_lft 3345sec
inet6 fe80::3a0f:b6d3:e2ea:96e9/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:57:06:1f brd ff:ff:ff:ff:ff:ff
inet 192.168.124.1/24 brd 192.168.124.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:57:06:1f brd ff:ff:ff:ff:ff:ff
#在虚拟机中ping与宿主机同局域网下的其他物理主机,已可以ping通
[root@localhost ~]# ping 10.8.13.17
PING 10.8.13.17 (10.8.13.17) 56(84) bytes of data.
64 bytes from 10.8.13.17: icmp_seq=1 ttl=63 time=0.407 ms
64 bytes from 10.8.13.17: icmp_seq=2 ttl=63 time=0.252 ms
--- 10.8.13.17 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1034ms
rtt min/avg/max/mdev = 0.252/0.329/0.407/0.079 ms
细心如你可能已经发现了,似乎有一个规律,就是虚拟机的网卡的mac
地址,和其所连接的虚拟交换机的网口的mac
地址,都长得特别像,只有前两位不一样,可以动手查看一下。
宿主机上的virbr0
虚拟交换机和默认NAT
网络下的虚拟机所在的网段是192.168.122.0/24
,宿主机上virbr0
的IP
地址是192.168.122.1
,虚拟机的网关指向的也是192.168.122.1
,查看iptables
规则,会发现转发的也都是这个网段的ip
地址,最终实现了虚拟机访问外部网络的功能。
#宿主机路由表
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.8.8.1 0.0.0.0 UG 100 0 0 eno8303
10.8.8.0 0.0.0.0 255.255.255.0 U 100 0 0 eno8303
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
#虚拟机路由表
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.122.1 0.0.0.0 UG 100 0 0 ens3
192.168.122.0 0.0.0.0 255.255.255.0 U 100 0 0 ens3
192.168.124.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
#虚拟机中iptables规则
[root@localhost ~]# iptables -t nat -L -nv
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 POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
643 53538 LIBVIRT_PRT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain LIBVIRT_PRT (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24
0 0 RETURN all -- * * 192.168.122.0/24 255.255.255.255
0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
25 1900 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
2 168 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
了解了上面的知识,我们可以把NAT
网络的模型图细化一下,理解成下面的样子:
2、桥接网络
默认情况下,KVM
虚拟机是基于 NAT
的网络配置,只有同一宿主机的虚拟机之间可以互相访问,跨宿主机是不能访问的。所以需要和宿主机配置成桥接模式,以便虚拟机可以在局域网内可见。
桥接网络模型的示意图如下:
如上图所示,我们需要先在宿主机中创建一个虚拟交换机(桥设备),然后把宿主机的物理网卡连接到虚拟交换机上,此时,我们可以把宿主机的物理网卡想象成虚拟交换机的一个网口,虚拟交换机通过这个网口,插上网线,桥接到物理交换机上,如果虚拟机使用了桥接网络,当启动某个虚拟机时,KVM
会自动创建一个虚拟网卡(相当于在虚拟交换机上创建了一个网口),以便虚拟机可以连接到虚拟交换机,从而通过虚拟交换机桥接到物理交换机上,这时,我们可以通过虚拟交换机的IP
地址连接到宿主机,通过虚拟机的IP
地址连接到虚拟机,此时宿主机和虚拟机是平级的,它们的网关都是指向了物理交换机所在网络的网关。了解完了相关概念以后,我们来动手操作一下。
1)宿主机网络配置
创建桥接网卡br1
,如下:
[root@localhost lxy]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# ls
ifcfg-br0 ifcfg-eno8303 ifcfg-eno8403 ifcfg-enp0s20f0u14u3
#eno8303为宿主机物理网卡(管理网络)
[root@localhost network-scripts]# cp ifcfg-eno8303 ifcfg-br1
修改 ifcfg-br1
文件,最终内容如下:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-br1
BOOTPROTO=static
NAME=br1 #将eno8303改为br1
DEVICE=br1 #同上
ONBOOT=yes
TYPE=bridge # 将制定为桥接类型
IPADDR=10.8.8.15 # 设置IP地址
PREFIX=24 # 设置子网掩码
GATEWAY=10.8.8.1 # 设置网关
修改 ifcfg-eno8303
, ifcfg-eno8303
为宿主机的物理网卡配置文件,最终内容如下:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eno8303
TYPE=Ethernet
BOOTPROTO=static
NAME=eno8303
DEVICE=eno8303
ONBOOT=yes
BRIDGE="br1" #指定桥接网卡的名称
配置好之后重启网络服务或者重启主机:
[root@localhost ~]# systemctl restart NetworkManager
[root@localhost ~]# systemctl enable NetworkManager.service
Created symlink /etc/systemd/system/multi-user.target.wants/NetworkManager.service → /usr/lib/systemd/system/NetworkManager.service.
Created symlink /etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service → /usr/lib/systemd/system/NetworkManager-dispatcher.service.
Created symlink /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service → /usr/lib/systemd/system/NetworkManager-wait-online.service.
[root@localhost ~]# ifconfig br1 up
注意:上述操作可能会导致服务器
ssh
断开连接。最好在BMC
中操作,建议提前查看BMC
地址,防止服务器ssh
断开后无法查询。查看BMC
地址的指令:ipmitool lan print
,输出结果中IP Address
列的地址即为服务器的BMC
地址。
在服务器BMC
控制台中执行上述命令,生成如下:
2)虚拟机网络配置
在宿主机上配置完网桥以后,接着需要将虚拟机的网络连接方式由NAT
修改为Bridge
方式(如果创建虚拟机时即指定网络连接方式为bridge
,则此处无需修改);可通过virt-manager
调用控制台图形界面进行修改,如下:
修改后,重新启动虚拟机,查看虚拟机IP
地址如下:
[root@localhost ~]# 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: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:0b:ea:2b brd ff:ff:ff:ff:ff:ff
inet 10.8.8.63/24 brd 10.8.8.255 scope global noprefixroute dynamic ens3
valid_lft 7034sec preferred_lft 7034sec
inet6 fe80::c2f8:1761:fcca:9f9c/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:b2:2a:fe brd ff:ff:ff:ff:ff:ff
inet 192.168.124.1/24 brd 192.168.124.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:b2:2a:fe brd ff:ff:ff:ff:ff:ff
此时,虚拟机的IP
地址变成和宿主机同一网段了,说明修改生效了。
改成桥接网络以后,无论是在虚拟机内ping
外网,还是在外面ping
虚拟机,均可以ping
通。
#虚拟机内ping百度可以ping通
[root@localhost ~]# ping www.baidu.com
PING www.a.shifen.com (180.101.50.188) 56(84) bytes of data.
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=1 ttl=52 time=3.68 ms
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=2 ttl=52 time=2.51 ms
--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 2.511/3.100/3.689/0.589 ms
# 其他宿主机ping虚拟机,可通
[root@xxx ~]# ping 10.8.8.63
PING 10.8.8.63 (10.8.8.63) 56(84) bytes of data.
64 bytes from 10.8.8.63: icmp_seq=1 ttl=64 time=0.599 ms
64 bytes from 10.8.8.63: icmp_seq=2 ttl=64 time=0.423 ms
^C
--- 10.8.8.63 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1036ms
rtt min/avg/max/mdev = 0.423/0.511/0.599/0.088 ms
#本地直接cmd内ping虚拟机,可通
C:Usersxxxx>ping 10.8.8.63
正在 Ping 10.8.8.63 具有 32 字节的数据:
来自 10.8.8.63 的回复: 字节=32 时间=6ms TTL=62
来自 10.8.8.63 的回复: 字节=32 时间=6ms TTL=62
10.8.8.63 的 Ping 统计信息:
数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 6ms,最长 = 6ms,平均 = 6ms
Control-C
^C
六、virsh管理虚拟机
virsh
是用C
语言编写的一个使用libvirt API
的虚拟化管理工具,在使用virsh
命令行进行管理虚拟化时,可以使用交互模式和非交互模式。virsh
实现了大部分对 qemu
命令行的大部分参数 和qemu monitor
中的多数命令,并非全部。在使用 virsh
命令之前要先安装 KVM
,并且需要 root
权限。
1、虚拟机管理常用参数
[root@localhost ~]# virsh help
分组的命令:
Domain Management (help keyword 'domain'):
attach-device 从一个XML文件附加装置
attach-disk 附加磁盘设备
attach-interface 获得网络界面
autostart 自动开始一个域
blkdeviotune 设定或者查询块设备 I/O 调节参数。
blkiotune 获取或者数值 blkio 参数
blockcommit 启动块提交操作。
blockcopy 启动块复制操作。
blockjob 管理活跃块操作
blockpull 使用其后端映像填充磁盘。
blockresize 创新定义域块设备大小
change-media 更改 CD 介质或者软盘驱动器
console 连接到客户会话
cpu-stats 显示域 cpu 统计数据
create 从一个 XML 文件创建一个域
define 从一个 XML 文件定义(但不开始)一个域
desc 显示或者设定域描述或者标题
destroy 销毁(停止)域
detach-device 从一个 XML 文件分离设备
detach-device-alias detach device from an alias
detach-disk 分离磁盘设备
detach-interface 分离网络界面
domdisplay 域显示连接 URI
domfsfreeze Freeze domain's mounted filesystems.
domfsthaw Thaw domain's mounted filesystems.
domfsinfo Get information of domain's mounted filesystems.
domfstrim 在域挂载的文件系统中调用 fstrim。
domhostname 输出域主机名
domid 把一个域名或 UUID 转换为域 id
domif-setlink 设定虚拟接口的链接状态
domiftune 获取/设定虚拟接口参数
domjobabort 忽略活跃域任务
domjobinfo 域任务信息
domname 将域 id 或 UUID 转换为域名
domrename rename a domain
dompmsuspend 使用电源管理功能挂起域
dompmwakeup 从 pmsuspended 状态唤醒域
domuuid 把一个域名或 id 转换为域 UUID
domxml-from-native 将原始配置转换为域 XML
domxml-to-native 将域 XML 转换为原始配置
dump 把一个域的内核 dump 到一个文件中以方便分析
dumpxml XML 中的域信息
edit 编辑某个域的 XML 配置
event Domain Events
inject-nmi 在虚拟机中输入 NMI
iothreadinfo view domain IOThreads
iothreadpin control domain IOThread affinity
iothreadadd add an IOThread to the guest domain
iothreaddel delete an IOThread from the guest domain
send-key 向虚拟机发送序列号
send-process-signal 向进程发送信号
lxc-enter-namespace LXC 虚拟机进入名称空间
managedsave 管理域状态的保存
managedsave-remove 删除域的管理保存
managedsave-edit edit XML for a domain's managed save state file
managedsave-dumpxml Domain information of managed save state file in XML
managedsave-define redefine the XML for a domain's managed save state file
memtune 获取或者数值内存参数
perf Get or set perf event
metadata show or set domain's custom XML metadata
migrate 将域迁移到另一个主机中
migrate-setmaxdowntime 设定最大可耐受故障时间
migrate-getmaxdowntime get maximum tolerable downtime
migrate-compcache 获取/设定压缩缓存大小
migrate-setspeed 设定迁移带宽的最大值
migrate-getspeed 获取最长迁移带宽
migrate-postcopy Switch running migration from pre-copy to post-copy
numatune 获取或者数值 numa 参数
qemu-attach QEMU 附加
qemu-monitor-command QEMU 监控程序命令
qemu-monitor-event QEMU Monitor Events
qemu-agent-command QEMU 虚拟机代理命令
reboot 重新启动一个域
reset 重新设定域
restore 从一个存在一个文件中的状态恢复一个域
resume 重新恢复一个域
save 把一个域的状态保存到一个文件
save-image-define 为域的保存状态文件重新定义 XML
save-image-dumpxml 在 XML 中保存状态域信息
save-image-edit 为域保存状态文件编辑 XML
schedinfo 显示/设置日程安排变量
screenshot 提取当前域控制台快照并保存到文件中
set-lifecycle-action change lifecycle actions
set-user-password set the user password inside the domain
setmaxmem 改变最大内存限制值
setmem 改变内存的分配
setvcpus 改变虚拟 CPU 的号
shutdown 关闭一个域
start 开始一个(以前定义的)非活跃的域
suspend 挂起一个域
ttyconsole tty 控制台
undefine 取消定义一个域
update-device 从 XML 文件中关系设备
vcpucount 域 vcpu 计数
vcpuinfo 详细的域 vcpu 信息
vcpupin 控制或者查询域 vcpu 亲和性
emulatorpin 控制火车查询域模拟器亲和性
vncdisplay vnc 显示
guestvcpus query or modify state of vcpu in the guest (via agent)
setvcpu attach/detach vcpu or groups of threads
domblkthreshold set the threshold for block-threshold event for a given block device or it's backing chain element
Domain Monitoring (help keyword 'monitor'):
domblkerror 在块设备中显示错误
domblkinfo 域块设备大小信息
domblklist 列出所有域块
domblkstat 获得域设备块状态
domcontrol 域控制接口状态
domif-getlink 获取虚拟接口链接状态
domifaddr Get network interfaces' addresses for a running domain
domiflist 列出所有域虚拟接口
domifstat 获得域网络接口状态
dominfo 域信息
dommemstat 获取域的内存统计
domstate 域状态
domstats get statistics about one or multiple domains
domtime domain time
list 列出域
Host and Hypervisor (help keyword 'host'):
allocpages Manipulate pages pool size
capabilities 性能
cpu-baseline 计算基线 CPU
cpu-compare 使用 XML 文件中描述的 CPU 与主机 CPU 进行对比
cpu-models CPU models
domcapabilities domain capabilities
freecell NUMA可用内存
freepages NUMA free pages
hostname 打印管理程序主机名
hypervisor-cpu-baseline compute baseline CPU usable by a specific hypervisor
hypervisor-cpu-compare compare a CPU with the CPU created by a hypervisor on the host
maxvcpus 连接 vcpu 最大值
node-memory-tune 获取或者设定节点内存参数
nodecpumap 节点 cpu 映射
nodecpustats 输出节点的 cpu 状统计数据。
nodeinfo 节点信息
nodememstats 输出节点的内存状统计数据。
nodesuspend 在给定时间段挂起主机节点
sysinfo 输出 hypervisor sysinfo
uri 打印管理程序典型的URI
version 显示版本
Interface (help keyword 'interface'):
iface-begin 生成当前接口设置快照,可在今后用于提交 (iface-commit) 或者恢复 (iface-rollback)
iface-bridge 生成桥接设备并为其附加一个现有网络设备
iface-commit 提交 iface-begin 后的更改并释放恢复点
iface-define define an inactive persistent physical host interface or modify an existing persistent one from an XML file
iface-destroy 删除物理主机接口(启用它请执行 "if-down")
iface-dumpxml XML 中的接口信息
iface-edit 为物理主机界面编辑 XML 配置
iface-list 物理主机接口列表
iface-mac 将接口名称转换为接口 MAC 地址
iface-name 将接口 MAC 地址转换为接口名称
iface-rollback 恢复到之前保存的使用 iface-begin 生成的更改
iface-start 启动物理主机接口(启用它请执行 "if-up")
iface-unbridge 分离其辅助设备后取消定义桥接设备
iface-undefine 取消定义物理主机接口(从配置中删除)
Network Filter (help keyword 'filter'):
nwfilter-define 使用 XML 文件定义或者更新网络过滤器
nwfilter-dumpxml XML 中的网络过滤器信息
nwfilter-edit 为网络过滤器编辑 XML 配置
nwfilter-list 列出网络过滤器
nwfilter-undefine 取消定义网络过滤器
nwfilter-binding-create create a network filter binding from an XML file
nwfilter-binding-delete delete a network filter binding
nwfilter-binding-dumpxml XML 中的网络过滤器信息
nwfilter-binding-list list network filter bindings
Networking (help keyword 'network'):
net-autostart 自动开始网络
net-create 从一个 XML 文件创建一个网络
net-define define an inactive persistent virtual network or modify an existing persistent one from an XML file
net-destroy 销毁(停止)网络
net-dhcp-leases print lease info for a given network
net-dumpxml XML 中的网络信息
net-edit 为网络编辑 XML 配置
net-event Network Events
net-info 网络信息
net-list 列出网络
net-name 把一个网络UUID 转换为网络名
net-start 开始一个(以前定义的)不活跃的网络
net-undefine undefine a persistent network
net-update 更新现有网络配置的部分
net-uuid 把一个网络名转换为网络UUID
Node Device (help keyword 'nodedev'):
nodedev-create 根据节点中的 XML 文件定义生成设备
nodedev-destroy 销毁(停止)节点中的设备
nodedev-detach 将节点设备与其设备驱动程序分离
nodedev-dumpxml XML 中的节点设备详情
nodedev-list 这台主机中中的枚举设备
nodedev-reattach 重新将节点设备附加到他的设备驱动程序中
nodedev-reset 重置节点设备
nodedev-event Node Device Events
Secret (help keyword 'secret'):
secret-define 定义或者修改 XML 中的 secret
secret-dumpxml XML 中的 secret 属性
secret-event Secret Events
secret-get-value secret 值输出
secret-list 列出 secret
secret-set-value 设定 secret 值
secret-undefine 取消定义 secret
Snapshot (help keyword 'snapshot'):
snapshot-create 使用 XML 生成快照
snapshot-create-as 使用一组参数生成快照
snapshot-current 获取或者设定当前快照
snapshot-delete 删除域快照
snapshot-dumpxml 为域快照转储 XML
snapshot-edit 编辑快照 XML
snapshot-info 快照信息
snapshot-list 为域列出快照
snapshot-parent 获取快照的上级快照名称
snapshot-revert 将域转换为快照
Storage Pool (help keyword 'pool'):
find-storage-pool-sources-as 找到潜在存储池源
find-storage-pool-sources 发现潜在存储池源
pool-autostart 自动启动某个池
pool-build 建立池
pool-create-as 从一组变量中创建一个池
pool-create 从一个 XML 文件中创建一个池
pool-define-as 在一组变量中定义池
pool-define define an inactive persistent storage pool or modify an existing persistent one from an XML file
pool-delete 删除池
pool-destroy 销毁(删除)池
pool-dumpxml XML 中的池信息
pool-edit 为存储池编辑 XML 配置
pool-info 存储池信息
pool-list 列出池
pool-name 将池 UUID 转换为池名称
pool-refresh 刷新池
pool-start 启动一个(以前定义的)非活跃的池
pool-undefine 取消定义一个不活跃的池
pool-uuid 把一个池名称转换为池 UUID
pool-event Storage Pool Events
Storage Volume (help keyword 'volume'):
vol-clone 克隆卷。
vol-create-as 从一组变量中创建卷
vol-create 从一个 XML 文件创建一个卷
vol-create-from 生成卷,使用另一个卷作为输入。
vol-delete 删除卷
vol-download 将卷内容下载到文件中
vol-dumpxml XML 中的卷信息
vol-info 存储卷信息
vol-key 为给定密钥或者路径返回卷密钥
vol-list 列出卷
vol-name 为给定密钥或者路径返回卷名
vol-path 为给定密钥或者路径返回卷路径
vol-pool 为给定密钥或者路径返回存储池
vol-resize 创新定义卷大小
vol-upload 将文件内容上传到卷中
vol-wipe 擦除卷
Virsh itself (help keyword 'virsh'):
cd 更改当前目录
echo echo 参数
exit 退出这个非交互式终端
help 打印帮助
pwd 输出当前目录
quit 退出这个非交互式终端
connect 连接(重新连接)到 hypervisor
提示:从上面的信息可以看到,virsh
命令大概分了,Domain Management
(域管理),Domain Monitoring
(域监控)、 Host and Hypervisor
(主机及虚拟化)、Interface
(网卡接口)、Network Filter
(网络防火墙)、Networking
(网络)、Node Device
(节点设备驱动)、Secret
、Snapshot
(快照)、Storage Pool
(存储池或存储策略)、Storage Volume
(存储卷)、Virsh itself
(virsh shell
自身相关)这些组,如果查看某一组帮助信息,我们可以使用virsh help
+组名;比如查看 list
组相关命令有哪些,可以使用virsh help list
;
[root@localhost ~]# virsh help list
NAME
list - 列出域
SYNOPSIS
list [--inactive] --all] [--transient] [--persistent] [--with-snapshot] [--without-snapshot] [--state-running] [--state-paused] [--state-shutoff] [--state-other] [--autostart] [--no-autostart] [--with-managed-save] [--without-managed-save] [--uuid] [--name] [--table] [--managed-save] [--title]
DESCRIPTION
返回域列表
OPTIONS
--inactive 列出不活跃的域
--all 不活跃和活跃的域列表
--transient 列出临时域
--persistent 列出持久域
--with-snapshot 列出现有快照的域
--without-snapshot 列出没有快照的域
--state-running 运行状态的域列表
--state-paused 列出暂停状态的域
--state-shutoff 列出关闭状态的域
--state-other 列出其他状态的域
--autostart 列出启用 autostart 的域
--no-autostart 列出禁用 autostart 的域
--with-managed-save 列出有管理的保存状态的域
--without-managed-save 列出没有管理的保存状态的域
--uuid 只列出 uuid
--name 只列出域名
--table 列出表格(默认)
--managed-save 标记有管理的保存状态的域
--title show domain title
[root@localhost ~]# virsh list
Id Name State
----------------------------------------------------
2 Anolis7.9-QU1 running
[root@localhost ~]# virsh list --all
Id Name State
-------------------------------
2 Anolis7.9-QU1 running
2、宿主机网络和hypervisor管理参数
virsh version # 获取libvirt 和hypervisor版本信息
virsh sysinfo # 获取宿主机系统信息
virsh nodeinfo # 获取宿主机CPU,内存,核数等信息
virsh uri # 显示当前连接对象
virsh connect # 连接到指定对象
virsh hostname # 获取宿主机主机名
virsh capabilities # 获取宿主机和虚拟机的架构及特性
virsh freecell # 显示当前MUMA单元空闲内存
virsh nodememstats # 获取宿主机内存使用情况
virsh nodecpustats # 获取宿主机CPU使用情况
virsh qemu-attach # 根据PID添加一个QEMU进程到libvirt中
virsh qemu-monitor-command domain [--hmp] command # 向QEMU monitor发送一个命令
virsh iface-list # 获取宿主机网络接口列表
virsh iface-mac <iface name> # 获取网络接口mac地址
virsh iface-name <mac> # 获取网络接口名称
virsh iface-edit <iface name of uuid> # 编辑网络接口XML配置文件
virsh iface-dumpxml <iface name of uuid> # 输出网络接口XML配置
virsh iface-destory <iface name of uuid> # 关闭网络接口
参考文章
-
[ kvm ] 学习笔记 7:KVM 虚拟机创建的几种方式 https://www.cnblogs.com/hukey/p/11307129.html -
KVM详解
https://www.cszhi.com/2019/10/12/KVM%E8%AF%A6%E8%A7%A3/ -
kvm总结(6) : nat网络和桥接网络
https://www.zsythink.net/archives/4272 -
KVM实战系列之virsh
https://www.jianshu.com/p/fe96cdb0bb67 -
虚拟化技术之kvm管理工具virsh常用基础命令(一)
https://www.cnblogs.com/qiuhom-1874/p/13508231.html
原文始发于微信公众号(Linux二进制):Linux服务器起KVM虚拟机总结
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/302186.html