创建磁盘镜像
创建一个80GB的qcow2文件系统镜像
sudo qemu-img create -f qcow2 /mnt/kvm-2/images/vm-2021-performance-01.qcow2 80G
这行命令是用于创建一个新的虚拟机硬盘文件的QEMU命令。下面是详细的解释:
- qemu-img:这是QEMU虚拟化软件的一个工具,用来管理和操作硬盘镜像文件;
- create:这个参数告诉qemu-img工具我们要执行的操作是创建一个新的硬盘镜像文件;
- -f qcow2:这里的-f是指定文件格式的参数,qcow2(QEMU Copy On Write version 2)是支持快照和增量备份的硬盘文件格式;
- /mnt/kvm-2/images/vm-2021-performance-01.qcow2:这是新创建的虚拟硬盘文件的存储路径和文件名。这里的路径通常指向一个专门存储虚拟机硬盘文件的目录;
- 80G:这是新创建的硬盘文件的大小,这里指定为80 GB。
这行命令的作用是使用root权限通过QEMU的qemu-img工具创建一个新的80 GB大小的qcow2格式的虚拟硬盘文件,放在/mnt/kvm-2/images/目录下,文件名为vm-2021-performance-01.qcow2。
硬盘文件通常用于虚拟机的存储需求。另外,虚拟磁盘文件的名称尽量与下面的统一域名称相同。
编写描述文件
描述文件的模版如下:
<domain type='kvm'>
<name>vm-2021-performance-01</name>
<memory unit='GiB'>16</memory>
<currentMemory unit='GiB'>16</currentMemory>
<vcpu placement='static'>16</vcpu>
<iothreads>1</iothreads>
<os>
<type arch='aarch64' machine='virt-4.0'>hvm</type>
<loader readonly='yes' type='pflash'>/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw</loader>
<nvram>/var/lib/libvirt/qemu/nvram/vm-2021-performance-01.fd</nvram>
</os>
<features>
<acpi/>
<gic version='3'/>
</features>
<cpu mode='host-passthrough' check='none'>
<topology sockets='4' cores='4' threads='1'/>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' iothread='1'/>
<source file='/mnt/kvm-2/images/vm-2021-performance-01.qcow2'/>
<target dev='vda' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/mnt/openEuler-20.03-LTS-aarch64-dvd.iso'/>
<target dev='sdb' bus='scsi'/>
<readonly/>
<boot order='2'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='scsi' index='0' model='virtio-scsi'>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<controller type='usb' index='0' model='ehci'>
<address type='pci' domain='0x0000' bus='0x04' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'/>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x8'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0xa'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-to-pci-bridge'>
<model name='pcie-pci-bridge'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0xb'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0xc'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0xd'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/>
</controller>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</interface>
<serial type='pty'>
<target type='system-serial' port='0'>
<model name='pl011'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='keyboard' bus='usb'>
<address type='usb' bus='0' port='2'/>
</input>
<video>
<model type='virtio' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</video>
<graphics type='vnc' listen='0.0.0.0' autoport='no' port='27403' passwd='g27f403s'/>
</devices>
<seclabel type='dynamic' model='dac' relabel='yes'/>
</domain>
注意需要修改的地方主要有以下几个:
统一域名称
<name>vm-2021-performance-01</name>
统一命名规范,设置一个与其它虚拟机都不同的域名称
虚拟机内存
<memory unit='GiB'>16</memory>
<currentMemory unit='GiB'>16</currentMemory>
在KVM(Kernel-based Virtual Machine)配置文件中,<memory>和<currentMemory>两个元素都是用来配置虚拟机的内存大小,但它们有一些区别:
- memory:这个元素指定了虚拟机能够使用的最大内存总量。这是虚拟机在创建时分配的最大内存容量,也是虚拟机在运行时可以达到的内存上限。即使当前不使用这么多内存,虚拟机也有能力在需要时扩展到这个值;
- currentMemory:这个元素指定了虚拟机当前分配的内存量。这通常在虚拟机启动时起作用,表示虚拟机实际启动时所使用的内存大小。currentMemory的值可以在虚拟机运行期间动态调整,以便在不重启虚拟机的情况下增加或减少内存使用。
举个例子:假设memory设置为16 GiB,而currentMemory设置为8 GiB。这意味着虚拟机启动时会使用8 GiB的内存,但如果需要,它可以在运行时扩展到最多16 GiB的内存。如果两者为16 GiB,这意味着虚拟机将始终有16 GiB的内存可用,而无需在运行时进行调整。
简而言之,memory定义了虚拟机的内存上限,而currentMemory定义了虚拟机当前启动时使用的内存量。这两者的设置可以相同,也可以不同,取决于对虚拟机性能和资源使用的需求。
CPU核心数
<vcpu placement='static'>16</vcpu>
...
<topology sockets='4' cores='4' threads='1'/>
在KVM虚拟机的配置文件中,<vcpu>、<topology>以及其子元素<sockets>、<cores>、<threads>用于定义虚拟机的CPU架构。以下是这些元素的详细解释以及它们之间的关系:
- vcpu: 这个元素定义了虚拟机可用的虚拟CPU的总数。`<vcpu placement='static'>16</vcpu>`表示虚拟机配置了16个虚拟CPU;
- topology: 这个元素及其子元素用于定义虚拟CPU的物理布局,即虚拟CPU如何映射到物理核心和逻辑处理线程。这有助于优化虚拟机的性能,使其更贴近物理硬件的运作方式;
- sockets: 虚拟CPU插槽的数量,这个数字代表虚拟机看到的物理CPU数量。`sockets='4'`表示虚拟机配置了4个CPU插槽;
- cores:每个插槽中的核心数。`cores='4'`意味着每个CPU插槽被配置为有4个核心;
- threads:每个核心的线程数。`threads='1'`表示每个核心配置为单线程。
这些参数的关系是:总的虚拟CPU数(`<vcpu>`的值)应该等于插槽数(`sockets`)乘以每个插槽的核心数(`cores`)乘以每个核心的线程数(`threads`)。在您的例子中,`4 sockets x 4 cores x 1 thread = 16 vCPUs`。这正好符合`<vcpu>`元素设置的16个虚拟CPU。
NVRAM路径
<nvram>/var/lib/libvirt/qemu/nvram/vm-2021-performance-01.fd</nvram>
在KVM虚拟机配置文件中的<nvram>标签用来指定虚拟机的非易失性随机存取存储器(NVRAM)文件的位置。NVRAM 在虚拟化环境中通常用于存储EFI(可扩展固件接口)固件配置和状态,这是用于启动虚拟机的固件类型之一。
<nvram> 标签:
- 用途: `<nvram>` 标签定义了虚拟机使用的NVRAM文件的路径;
- 路径: `/var/lib/libvirt/qemu/nvram/vm-2021-performance-01.fd` 是NVRAM文件的具体位置。这个文件通常包含EFI启动信息,例如启动顺序、设备配置等。
NVRAM的作用:
- EFI固件:如果虚拟机使用EFI而不是传统的BIOS来启动,NVRAM文件就尤为重要。它保存了EFI固件的设置,这些设置在虚拟机重启后仍然保持不变;
- 启动信息存储:NVRAM存储关键的启动信息,如操作系统加载器的路径、启动菜单选项等,它们对于虚拟机的启动过程至关重要。
确保<nvram>标签中指定的路径存在且可访问是很重要的,因为如果NVRAM文件丢失或损坏,可能会导致虚拟机无法正常启动或EFI配置丢失。通常,在创建支持EFI启动的虚拟机时,相关的NVRAM文件会被自动创建。如果迁移虚拟机或备份其配置,NVRAM文件也需要被相应地处理。
虚拟磁盘地址
<source file='/mnt/kvm-2/images/vm-2021-performance-01.qcow2'/>
在KVM虚拟机的配置文件中,<source>标签用于指定虚拟机使用的硬盘镜像文件。这个标签通常位于<disk>元素的内部,用以定义虚拟硬盘的来源。
<source>标签:
- 用途:`<source>`标签定义了虚拟机硬盘的源文件路径;
- 属性:`file`属性指定了硬盘镜像文件的具体位置,这里的路径是`/mnt/kvm-2/images/vm-2021-performance-01.qcow2`。
硬盘镜像文件的作用:
- 存储虚拟机数据:该文件作为虚拟机的主要存储介质,包含操作系统、应用程序和用户数据;
- 文件格式:后缀`.qcow2`表明这是一个使用QEMU Copy On Write version 2格式的镜像文件,这种格式支持快照和动态扩展等高级功能。
`<source file='/mnt/kvm-2/images/vm-2021-performance-01.qcow2'/>` 这个配置指明了虚拟机将从指定的.qcow2格式的硬盘镜像启动,该文件位于`/mnt/kvm-2/images`目录下,是虚拟机的主存储设备。这是虚拟机配置中非常关键的一部分,因为所有的操作系统和应用数据都存储在这里。
VNC地址配置
<graphics type='vnc' listen='0.0.0.0' port='27403'
passwd='g27f403s'/>
在KVM虚拟机配置文件中的 `<graphics>` 标签用于定义虚拟机的图形输出设置,特别是如何通过网络访问虚拟机的图形界面。这个例子中使用了VNC(Virtual Network Computing)协议来远程访问虚拟机的桌面。下面是该标签各属性的详细解释:
<graphics>标签:
`type='vnc'`:
- 类型:这指定了使用VNC协议进行远程桌面连接;
- 功能:VNC允许用户通过网络看到和操作虚拟机的图形界面,就如同坐在本地机器前一样。
`listen='0.0.0.0'`:
- 监听地址:设置VNC服务器监听的网络地址。这里的`0.0.0.0`表示接受来自任何IP地址的连接请求,使得任何网络中的机器都能尝试连接到此虚拟机。
`port='27403'`:
- 端口号:这是VNC服务器在主机上监听的端口号。通过该端口号,用户可以从远程位置连接到虚拟机的VNC服务器;
- 配置:确保该端口在网络防火墙上是开放的,并且没有被其他服务占用。
配置使得用户可以通过VNC客户端软件从任意位置远程访问虚拟机的图形界面,非常适合需要远程管理的场景。但同时,它也要求管理员必须注意安全配置,防止未授权访问。注意这里的密码是VNC的连接密码,不是虚拟机操作系统的登录密码。
安装操作系统
定义并开启虚拟机
sudo virsh define vm-2021-performance-01.xml
sudo virsh start vm-2021-performance-01
这两行命令是使用 `virsh` 工具来管理和控制 KVM 虚拟机。下面是每条命令的具体功能解释:
`sudo virsh define vm-2021-performance-01.xml`:
- 作用:这个命令定义一台新的虚拟机。它从指定的XML文件(`vm-2021-performance-01.xml`)读取虚拟机的配置信息;
- 功能:通过这个命令,virsh工具将XML文件中描述的虚拟机配置加载到KVM的虚拟机列表。这并不会启动虚拟机,只是将其配置定义在系统中,以便随时可以启动。
`sudo virsh start vm-2021-performance-01`:
- 作用:这个命令启动一个已定义的虚拟机。这里的虚拟机名称是`vm-2021-performance-01`,即上一条命令中定义的虚拟机。
- 功能:执行此命令后,KVM将根据之前定义的配置启动虚拟机。这包括分配资源、加载操作系统等。
在设置好虚拟机的XML配置文件后,首先使用`define`命令将这些配置注册到虚拟化平台上。注册后,可以通过start命令来启动虚拟机。如果需要停止虚拟机、查看状态或进行其他管理操作,也可以使用virsh的其他命令来实现。
现在虚拟机还没有安装系统,我们需要通过设置的VNC相关参数远程给虚拟机装系统。
查看VNC端口
sudo virsh vncdisplay vm-2021-performance-01
:21503
这里显示的是display id,不是VNC端口,VNC端口还是我们在XML中定义的那个(+5900)
临时放行端口
sudo firewall-cmd --add-port=27403/tcp
sudo firewall-cmd --add-port=27403/udp
OpenEuler和其他使用firewalld服务的Linux发行版的防火墙管理工具,来配置防火墙以允许特定端口的网络流量。这里具体用于添加TCP和UDP协议的27403端口。
- 临时与永久规则:默认情况下,使用firewall-cmd添加的规则仅为临时规则,仅在下次重启前有效。如果希望规则永久生效,需要添加--permanent选项,然后重新加载防火墙规则;
- 检查和应用:在添加端口规则后,可以使用sudo firewall-cmd --list-all命令来检查当前防火墙的配置,确保您的规则已被正确添加。
VNC viewer连接
注意画质必须设置为high quality,否则会报错。连接后在VNC Viewer中安装操作系统。安装步骤与在主机上安装操作系统是基本相同的,此处不展开讲述。
完成最后配置
查看虚拟机IP
sudo virsh domifaddr vm-2021-performance-01
名称 MAC 地址 Protocol Address
-------------------------------------------------------------------------------
vnet25 52:54:00:ac:2a:50 ipv4 192.168.122.153/24
ssh端口转发
sudo iptables -I FORWARD -d 0.0.0.0/0 -j ACCEPT
sudo firewall-cmd --add-forward-port=port=21503:proto=tcp:toaddr=192.168.122.153:toport=22
`sudo iptables -I FORWARD -d 0.0.0.0/0 -j ACCEPT`:
- iptables:Linux上用于配置网络层防火墙规则的工具;
- -I FORWARD:表示在FORWARD链中插入一条规则;
- -d 0.0.0.0/0:指定目的地地址为任意地址;
- -j ACCEPT:指示匹配到此规则的数据包应被接受。
此命令配置iptables允许所有经过此主机的转发流量,基本上是将主机设置为一个透明网关。
`sudo firewall-cmd --add-forward-port=port=21503:proto=tcp:toaddr=192.168.122.153:toport=22`:
- firewall-cmd:是 firewalld 的管理工具,firewalld 是用于管理网络访问控制的守护程序:
- --add-forward-port:添加一个端口转发规则;
- port=21503:指定外部接入端口;
- proto=tcp:定义使用 TCP 协议;
- toaddr=192.168.122.153:定义内部目标地址;
- toport=22:定义内部目标端口,即 SSH 服务的标准端口。
这条命令设置端口转发,将所有到达21503端口的TCP流量转发到内网IP地址192.168.122.153上的22端口(通常是SSH端口)。这可以用于在不更改网络设置或防火墙的更内部配置的情况下,从外部直接访问一个内部网络中的SSH服务。
对于firewall-cmd的命令,如果想要使规则永久生效,需要添加`--permanent`参数。
始终确保网络设置的更改不会意外暴露敏感服务到不安全的环境中,尤其是在配置如SSH端口转发等重要服务时。
这些配置可以帮助进行高级网络设置,如设置 DMZ(隔离区),或在有限的公网IP地址下暴露内部服务等。因此最终的外部ssh端口为21503,root密码设置为g27f4@3s。