VMware Workstation Pro позволяет пользователям настраивать виртуальные машины на одной физической машине и использовать их одновременно с реальной машиной. Каждая виртуальная машина может запускать свою собственную операционную систему, включая версии Microsoft Windows, Linux, BSD и MS-DOS.
https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html
cd /home/user/download
sudo chmod +x ./VMware-Workstation-Full-x.y.z-nn.x86_64.bundle
sudo ./VMware-Workstation-Full-x.y.z-nn.x86_64.bundle
CPATH=/usr/src/kernels/$(uname -r | sed 's/+debug//')/include/linux vmware-modconfig --console --install-all
Если не сработало переходим к следующим пунктам
sudo dnf install kernel-devel kernel-headers gcc gcc-c ++ make git
wget https:/wget/github.com/mkubecek/vmware-host-modules/archive/workstation-x.y.z.tar.gz
tar -xzf workstation-x.y.z.tar.gz
cd vmware-host-modules-workstation-x.y.z
make
sudo make install
wget https:/wget/github.com/mkubecek/vmware-host-modules/archive/workstation-x.y.z.tar.gz
tar -xzf workstation-x.y.z.tar.gz
cd vmware-host-modules-workstation-x.y.z
tar -cf vmmon.tar vmmon-only
tar -cf vmnet.tar vmnet-only
cp -v vmmon.tar vmnet.tar /usr/lib/vmware/modules/source/
vmware-modconfig --console --install-all
Вы можете создать скрипт для использования этого после обновления ядра. Сохраните его как /etc/kernel/install.d/99-vmmodules.install:
#!/bin/bash
VMWARE_VERSION="17.5.1"
show_usage() {
echo "Usage: script.sh COMMAND"
echo "Available commands:"
echo " start - Start the VMware service"
echo " stop - Stop the VMware service"
exit 1
}
[ -z "$VMWARE_VERSION" ] && exit 0
if [ "$1" == "start" ]; then
echo "Starting VMware service..."
# Add your start command here
elif [ "$1" == "stop" ]; then
echo "Stopping VMware service..."
# Add your stop command here
else
show_usage
fi
exit 0
license-key:
MC60H-DWHD5-H80U9-6V85M-8280D
4A4RR-813DK-M81A9-4U35H-06KND
NZ4RR-FTK5H-H81C1-Q30QH-1V2LA
JU090-6039P-08409-8J0QH-2YR7F
4Y09U-AJK97-089Z0-A3054-83KLA
4C21U-2KK9Q-M8130-4V2QH-CF810
VMDK - это виртуальная файловая система, используемая в vmware. Ее можно примонтировать к ОС Linux используя утилиты qemu.
Установка qemu utils:
sudo apt install qemu-utils
sudo dnf install qemu-utils
Подгрузка модуля ядра для network block device:
sudo modprobe nbd
Создать network block devices из vmdk образа:
sudo qemu-nbd -r -c /dev/nbd1 ./vmware-disk.vmdk
Проверить,что образы создались:
ls -al /dev/nbd1p*
brw-rw---- 1 root disk 43, 33 Jan 9 14:28 /dev/nbd1p1
brw-rw---- 1 root disk 43, 34 Jan 9 14:28 /dev/nbd1p2
brw-rw---- 1 root disk 43, 35 Jan 9 14:28 /dev/nbd1p3
brw-rw---- 1 root disk 43, 36 Jan 9 14:28 /dev/nbd1p4
brw-rw---- 1 root disk 43, 37 Jan 9 14:28 /dev/nbd1p5
brw-rw---- 1 root disk 43, 38 Jan 9 14:28 /dev/nbd1p6
brw-rw---- 1 root disk 43, 39 Jan 9 14:28 /dev/nbd1p7
Создать точки монтирования для разделов:
mkdir /mnt/p1
mkdir /mnt/p2
mkdir /mnt/p3
mkdir /mnt/p4
mkdir /mnt/p5
mkdir /mnt/p6
mkdir /mnt/p7
Монтирование каждого раздела в свою директорию:
sudo mount /dev/nbd1p1 /mnt/p1
mount: /mnt//p1: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p2 /mnt/p2
mount: /mnt/p2: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p3 /mnt/p3
mount: /mnt/p3: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p4 /mnt/p4
mount: /mnt/p4: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p5 /mnt/p5
mount: /mnt/p5: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p6 /mnt/p6
mount: /mnt/p6: WARNING: device write-protected, mounted read-only.
sudo mount /dev/nbd1p7 /mnt/p7
mount: /mnt/p7: WARNING: device write-protected, mounted read-only.
Примерное содержание:
ls ./p -la
total 104
drwxr-xr-x 23 root root 4096 Oct 8 12:42 .
drwxrwxr-x 9 user user 4096 Jan 9 14:31 ..
drwxr-xr-x 2 root root 4096 Oct 8 12:41 bin
drwxr-xr-x 4 root root 4096 Oct 8 12:42 boot
drwxr-xr-x 4 root root 4096 Oct 8 12:41 dev
drwxr-xr-x 29 root root 4096 Oct 8 12:42 etc
drwxr-xr-x 2 root root 4096 Oct 8 12:41 home
drwxr-xr-x 7 root root 4096 Oct 8 12:42 lib
drwx------ 2 root root 16384 Oct 8 12:58 lost+found
drwxr-xr-x 5 root root 4096 Oct 8 12:41 media
drwxr-xr-x 2 root root 4096 Oct 8 12:41 mnt
Запуск VM в фоновом режиме (не забудьте про доступ к ней, включите VNC)
vmrun -T ws start /path/to/vmx/file.vmx nogui
-T - тип запуска:
Ремарка: Здесь CD-ROM - это любой оптический привод в виртуальном исполнении, подгружаемый как ISO-файл
Сначала необходимо проверить, поддерживает ли процессор аппаратную виртуализацию. Проверка осуществляется командой:
$ egrep '(vmx|svm)' /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb retpoline kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
Если вывод команды не пуст, значит процессор поддерживает аппаратную виртуализацию.
В случае если у команды пустой вывод, возможно, процессор не поддерживает виртуализацию либо функция отключена в BIOS материнской платы.
После проверки можно приступать к развертыванию средства виртуализации.
Установка пакетов сервера виртуализации libvirt:
$ dnf install libvirt qemu-kvm virt-install virt-manager openssh-askpass OVMF boost-random boost-program-options boost-regex
Затем запустите и добавьте в автозагрузку службу сервера libvirtd:
$ systemctl enable libvirtd --now
Проверьте статус службы сервера libvirtd:
$ systemctl status libvirtd
В статусе должно быть указано active (running).
Перезагрузите компьютер для загрузки модулей ядра kvm (если используется процессор Intel, также должен загрузиться модуль intel-kvm).
После перезагрузки проверьте загрузку модулей.
$ lsmod | grep kvm
kvm_intel 196608 3
kvm 598016 1 kvm_intel
Дополнительно рекомендуется проверить сетевые подключения:
$ ifconfig
Должно появиться дополнительное подключение virbr0.
Добавьте пользователя (в примере user), используемого для управления виртуальными машинами, в группу libvirt.
$ usermod -a -G libvirt user
На этом установка и начальная настройка завершены.
Подробнее про настройку OpenVSwitch + QEMU
По умолчанию при первом запуске KVM создается сеть default, которая является NAT-сетью для виртуальных машин с подсетью и DHCP на уровне dnsmasq (управляется через libvirt) 192.168.122.0/24.
Данная подсеть создает виртуальный мост virbr0.
Однако существует несколько вариантов сетей.
Главное что нужно определить, есть 2 типа пробрасывания сети внутрь ВМ:
В каждом, из ниже представленных типов сети приведу пример содержания XML-определения виртуальной сети и виртуального интерфейса ВМ.
Итак, в общем преставлении виртуальный коммутатор - это сущность внутри libvirt, но имеющая виртуальные интерфейсы на хостовой машине для обеспечения связности с внешним миром.
Рис.1 Виртуальный интерфейс
Рис.2 Простое представление виртуального свитча.
Рис.3 Конфигурация сети из коробки
Этот тип сети позволяет маршрутизировать трафик между виртуальной сетью и ЛВС без использования NAT. Для этого требуется предварительная конфигурация таблиц маршрутизации как на хосте, так и в сети.
Рис.4. Виртуальная сеть типа Маршрутизируемая
XML-описание сети:
<network>
<name>ROUTED</name>
<bridge name="virbr1"/>
<forward mode="route" dev="eth1"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/>
</network>
В этом типе сети виртуальные машины могут взаимодействовать между собой, а также с хостом, но без «внешнего» мира.
Рис.5 Виртуальная сеть типа Изолированная
XML-описание сети:
<network>
<name>PRIVATE</name>
<bridge name="virbr2"/>
<ip address="192.168.152.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.152.2" end="192.168.152.254"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64"/>
</network>
Этот тип требует преднастроенный мост на хосте типа «br0». ВМки будут пробошены в физическую сеть. Задачи маршрутизации, выдачи IP и д.р. будут отданы физической сети, а не хосту
XML-описание сети:
<network>
<name>HOST-BRIDGE</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
Здесь будет использоваться macvtap-подключение.
XML-описание сети:
<network>
<name>DIRECT-macvtap</name>
<forward mode="bridge">
<interface dev="eth20"/>
<interface dev="eth21"/>
<interface dev="eth22"/>
<interface dev="eth23"/>
<interface dev="eth24"/>
</forward>
</network>
Этот тип подразумевает, что хостовая машина будет выдавать IP-адреса ВМ, где будет являться сразу DHCP-сервером, маршрутизатором и будет NATить за пределы хоста на соответствующем IP-адресе соответствующего интерфейса хоста за его пределы. Как уже выше говорил, этот тип создается автоматически как default при установке qemu.
Рис.6. Виртуальная сеть типа NAT
Рис.7. DHCP & DNS на хостовой машине
Вот пример такой сети:
<network>
<name>NATED</name>
<bridge name="virbr4"/>
<forward mode="nat"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254"/>
<host mac="52:fa:9b:20:b2:e0" name="VM1" ip="192.168.122.2"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/>
</network>
В хосте это видится так:
$ ifconfig virbr4
virbr4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether b0:0c:19:4f:65:af txqueuelen 1000 (Ethernet)
RX packets 3660339 bytes 428180231 (408.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3594689 bytes 3448743392 (3.2 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
$ brctl show
bridge name bridge id STP enabled interfaces
virbr4 8000.000c297f65a4 yes vnet1
В XML-описании виртуальной машины содержание будет таким:
<interface type='network'>
<mac address='52:fa:9b:20:b2:e0'/>
<source network='NATED' portid='460eb37d-b912-4406-8a11-40088ee278a1' bridge='virbr4'/>
<target dev='vnet1'/>
<model type='virtio'/>
<alias name='net1'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
DHCP при этом будет такой:
$ virsh net-dhcp-leases NATED
Срок действия MAC-адрес Протокол IP-адрес Имя узла Идентификатор или DUID клиента
----------------------------------------------------------------------------------------------------------------------
2024-08-21 15:22:38 52:fa:9b:20:b2:e0 ipv4 192.168.122.2/24 VM1 -
В официальной инструкции предлагается делать вот так (XML-описание сети):
<network>
<name>ovs-net</name>
<forward mode='bridge'/>
<bridge name='ovsbr0'/>
<virtualport type='openvswitch'>
<parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
<vlan trunk='yes'>
<tag id='42' nativeMode='untagged'/>
<tag id='47'/>
</vlan>
<portgroup name='dontpanic'>
<vlan>
<tag id='42'/>
</vlan>
</portgroup>
</network>
Здесь мы можем подключить интерфейс виртуальной машины к «VLAN ID» либо к trunk. Описывается Open vSwitch целиком, однако работает это не во всех QEMU-версиях.
Альтернативно можно сделать вот так:
Вся маршрутизация виртуальной сети ложится на хостовую (Linux) машину, поэтому она может выступать как trunk и как FW. (К слову, у VMWare ESXi это решается созданием VLAN-PortGroup внутри vSwitch с ID 4095. Такой VLAN ID в этом vSwitch и будет trunk всех VLAN этого свитча)
XML-описание ВМ-интерфейса:
<interface type='direct'>
<mac address='28:50:2f:6a:4e:a8'/>
<source dev='vlan03' mode='bridge'/>
<target dev='macvtap1'/>
<model type='e1000e'/>
<alias name='net1'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
При этом на хосте создан интерфейс vlan03. Вот его описание:
[connection]
id=EVL03
uuid=6ce62c48-dd15-46a6-ab1c-6ae5cd191622
type=vlan
interface-name=vlan03
[ethernet]
cloned-mac-address=preserve
mtu=1500
[vlan]
flags=1
id=3
parent=eth0
[ipv4]
method=disabled
[ipv6]
addr-gen-mode=stable-privacy
method=disabled
[proxy]
Обратите внимание на method=disabled. Это сделано для того, чтобы хостовая машина не была участником этой сети (L3, на L2 так или иначе в хостовую машину воткнут trunk)
Подробнее про настройку OpenVSwitch + QEMU
Для создания ВМ есть 3 варианта
virt-install
Пример команды:
$ virt-install \
--virt-type kvm \
--name VM
--ram 2048
--vcpus 4
--os-variant centos7
--network network=default,model=rtl8139
--graphics vnc,port=5900,listen=0.0.0.0,password=passwd
--cdrom /var/lib/libvirt/iso/centos7.iso
--disk path=/var/lib/libvirt/vms/vm.qcow2,size=40,bus=virtio,format=qcow2
Теперь по описанию параметров:
Запросить возможные варианты ОС вот так:
$ osinfo-query os
Используется для определения уже имеющейся ВМ в данном гипервизоре. Т.е. уже есть XML-описание этой ВМ и qcow2-образ диска с системой (например при миграции между гипервизорами, в т.ч. других вендоров, подробнее ниже в главе «Конвертация образов OpenStack»)
Для выгрузки XML-описания существующей ВМ используем команду:
$ virsh dumpxml VMName
Пример вывода будет такой:
<domain type='kvm' id='4'>
<name>VMName</name>
<uuid>716308a2-9120-4fec-a8a6-ad23dd3f26bc</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://redhat.com/rhel/8.0"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<vcpu placement='static'>4</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<vmport state='off'/>
</features>
<cpu mode='host-passthrough' check='none' migratable='on'/>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/vms/vmdisk.qcow2' index='2'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu'/>
<target dev='sda' bus='sata'/>
<readonly/>
<alias name='sata0-0-0'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<alias name='usb'/>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pcie-root'>
<alias name='pcie.0'/>
</controller>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x10'/>
<alias name='pci.1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x11'/>
<alias name='pci.2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x12'/>
<alias name='pci.3'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0x13'/>
<alias name='pci.4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0x14'/>
<alias name='pci.5'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0x15'/>
<alias name='pci.6'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0x16'/>
<alias name='pci.7'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0x17'/>
<alias name='pci.8'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x18'/>
<alias name='pci.9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0x19'/>
<alias name='pci.10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0x1a'/>
<alias name='pci.11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0x1b'/>
<alias name='pci.12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0x1c'/>
<alias name='pci.13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0x1d'/>
<alias name='pci.14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
</controller>
<controller type='sata' index='0'>
<alias name='ide'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<alias name='virtio-serial0'/>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</controller>
<interface type='direct'>
<mac address='52:54:00:1c:2b:df'/>
<source dev='vlan03' mode='bridge'/>
<target dev='macvtap1'/>
<model type='e1000e'/>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/9'/>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/9'>
<source path='/dev/pts/9'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<channel type='unix'>
<source mode='bind' path='/run/libvirt/qemu/channel/4-VMName/org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
<alias name='channel1'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
<input type='tablet' bus='usb'>
<alias name='input0'/>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'>
<alias name='input1'/>
</input>
<input type='keyboard' bus='ps2'>
<alias name='input2'/>
</input>
<graphics type='spice' port='5902' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
<image compression='off'/>
</graphics>
<sound model='ich9'>
<alias name='sound0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
</sound>
<audio id='1' type='spice'/>
<video>
<model type='virtio' heads='1' primary='yes'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<alias name='redir0'/>
<address type='usb' bus='0' port='2'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<alias name='redir1'/>
<address type='usb' bus='0' port='3'/>
</redirdev>
<watchdog model='itco' action='reset'>
<alias name='watchdog0'/>
</watchdog>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</memballoon>
<rng model='virtio'>
<backend model='random'>/dev/urandom</backend>
<alias name='rng0'/>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</rng>
</devices>
<seclabel type='dynamic' model='selinux' relabel='yes'>
<label>system_u:system_r:svirt_t:s0:c220,c736</label>
<imagelabel>system_u:object_r:svirt_image_t:s0:c220,c736</imagelabel>
</seclabel>
<seclabel type='dynamic' model='dac' relabel='yes'>
<label>+107:+107</label>
<imagelabel>+107:+107</imagelabel>
</seclabel>
</domain>
Для начала необходимо доустановить нужный пакет, а именно:
$ dnf install virt-v2v -y
Собственно именно этой тулзой происходит конвертация ovf/ova файлов в qcow2 (RedHat рекомендует также доустановить пакет virtio-win).
Использование просто, как часы:
$ virt-v2v -i ova guestvm1.ova -of qcow2
[ 0.0] Opening the source -i ova guestvm1.ova
[ 0.0] Creating an overlay to protect the source from being modified
[ 1.0] Opening the overlay
[ 4.0] Initializing the target -o libvirt
[ 4.0] Inspecting the overlay
[ 10.0] Checking for sufficient free disk space in the guest
[ 10.0] Estimating space required on target for each disk
[ 10.0] Converting Red Hat Enterprise Linux release 8 to run on KVM
virt-v2v: This guest has virtio drivers installed.
[ 14.0] Mapping filesystem data to avoid copying unused and blank areas
[ 14.0] Closing the overlay
[ 14.0] Copying disk 1/1 to /guests/guestvm1-sda (qcow2)
(100.00/100%)
[ 28.0] Creating output metadata
Pool default refreshed
Domain guestvm1 defined from /tmp/v2vlibvirt4fe796.xml
[ 28.0] Finishing off
Либо, если OVF не один, можно указать путь к файлам OVF:
$ virt-v2v -i ova “/путь/к/файлам/OVF” -of qcow2
Убедимся, что ВМка развернулась:
$ virsh list --all
Тут кратко:
Список всех развернутых ВМ:
$ virsh list --all
Список все автозапускаемых (вместе с хостом) ВМ
$ virsh list --autostart
Запустить ВМ:
$ virsh start VMName
Выключить ВМ:
$ virsh shutdown VMName
Вырубить ВМ:
$ virsh destroy VMName
Пометить ВМ к автозапуску:
$ virsh autostart VMName
Исключить ВМ из гипервизора (без удаления файлов образов дисков):
$ virsh undefine VMName
Тоже самое касается и виртуальных сетей:
$ virsh net-list --all
$ virsh net-list --autostart
$ virsh net-start NetName
$ virsh net-destroy NetName
$ virsh net-autostart NetName
$ virsh net-undefine NetName
Пока в поиске аналога veeam backup для QEMU, поскольку snapshot - это всего лишь снимок конфигурации ВМ + можно дополнительно копировать образ диска ВМ (qcow2). Такое положение дел вряд ли можно назвать полноценным snapshot или backup, разве что резервная копия холодного состояния машины.
Работа с такими снимками простая:
# Список имеющихся снимков
$ virsh snapshot-list VMName
# Создание снимка
$ virsh snapshot-create VMName
# Получить информацию о снимке
$ virsh snapshot-info VMName SnapID
# Восстановить из снимка
$ virsh snapshot-revert VMName SnapID
# Дамп данных снимка
$ virsh snapshot-dumpxml VMName SnapID
# Удаление снимка
$ virsh snapshot-delete VMName SnapID
При любой операции со снимками, рекомендую также копировать qcow2-образы дисков (горячего и холодного типа, взависимости от критичности к целостности данных после восстановления)
Речь идет о входящей в комплект QEMU утилите qemu-img. Она вполне умеет конвертировать любые OpenStack образы, в частности MS Hyper-V (VHD, VHDX), VMware (VMDK), Oracle VirtualBox (VDI).
Соответствие типов и параметров для утилиты:
Формат образа | Параметр командной строки |
---|---|
QCOW2 (KVM, Xen) | qcow2 |
QED (KVM) | qed |
raw | raw |
VDI (VirtualBox) | vdi |
VHD (Hyper-V) | vpc |
VMDK (VMware) | vmdk |
Использование:
# Образец
$ qemu-img convert -f <исходный формат> -O <целевой формат> <исходный файл образа> <целевой файл образа>
# Пример
$ qemu-img convert -f raw -O qcow2 image.img image.qcow2
Если ВМ на ОС Windows - желательно перед переходом на QEMU установить драйвера virtio, иначе получите BSOD.
Строго рекомендуется при переходе с VDI (VirtualBox) сначала сконвертировать vdi-образ в raw. Для этого необходимо воспользоваться встроенной утилитой VirtualBox:
$ VBoxManage clonehd ~/VirtualBox\ VMs/image.vdi image.img --format raw
Как увеличить размер диска qcow2? А затем увеличить размер раздела внутри виртуального носителя? А если это LVM? А если нет? Обо всем по порядку.
Итак, необходимо погасить виртуальную машину, использующую виртуальный диск.
Затем посмотрим на реальные данные:
$ qemu-img info disk.qcow2
image: disk.qcow2
file format: qcow2
virtual size: 60 GiB (64424509440 bytes)
disk size: 12 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
filename: disk.qcow2
protocol type: file
file length: 60 GiB (64434601984 bytes)
disk size: 12 GiB
Увеличим на 40ГБ:
$ qemu-img resize disk.qcow2 +40G
Image resized.
$ qemu-img info disk.qcow2
image: disk.qcow2
file format: qcow2
virtual size: 100 GiB (107374182400 bytes)
disk size: 12 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: true
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
filename: disk.qcow2
protocol type: file
file length: 60 GiB (64434601984 bytes)
disk size: 12 GiB
Увеличение диска в Linux требует его размонтирования. Поскольку системный диск не размонтировать в штатном режиме, лучше такие манипуляции проводить прямо на хостовой машине (см. ниже Монтирование диска в хостовую машину). Итак допустим, мы смонтировали виртуальный диск в хостовую машину как /dev/nbd0. Проведем необъодимые манипуляции.
# Расширим нужный (последний раздел)
$ fdisk /dev/nbd0
$ p
Диск /dev/nbd0: 100 GiB, 107374182400 байт, 209715200 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 6C5137AA-A871-4651-9DA1-4268A9A88BDF
Устр-во начало Конец Секторы Размер Тип
/dev/nbd0p1 2048 4095 2048 1M BIOS boot
/dev/nbd0p2 4096 2101247 2097152 1G Файловая система Linux
/dev/nbd0p3 2101248 8624127 6522880 3,1G Linux своп
/dev/nbd0p4 8624128 87373823 78749696 37,6G Файловая система Linux
/dev/nbd0p5 87373824 125825023 38451200 18,3G Файловая система Linux
$ d
Номер раздела (1-5, default 5):
Раздел 5 был удален.
$ n
Номер раздела (5-128, default 5):
Первый сектор (87373824-209715166, default 87373824):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (87373824-209715166, default 209713151):
Создан новый раздел 5 с типом 'Linux filesystem' и размером 58,3 GiB.
Partition #5 contains a ext4 signature.
Do you want to remove the signature? [Y] Да/[N] Нет: n
$ p
Диск /dev/nbd0: 100 GiB, 107374182400 байт, 209715200 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 6C5137AA-A871-4651-9DA1-4268A9A88BDF
Устр-во начало Конец Секторы Размер Тип
/dev/nbd0p1 2048 4095 2048 1M BIOS boot
/dev/nbd0p2 4096 2101247 2097152 1G Файловая система Linux
/dev/nbd0p3 2101248 8624127 6522880 3,1G Linux своп
/dev/nbd0p4 8624128 87373823 78749696 37,6G Файловая система Linux
/dev/nbd0p5 87373824 209713151 122339328 58,3G Файловая система Linux
$ w
Таблица разделов была изменена.
Вызывается ioctl() для перечитывания таблицы разделов.
Синхронизируются диски.
# Запустим принудительную проверку вновь созданного раздела (при соблюдении начального сектора - данные не пропадут)
$ e2fsck -f /dev/nbd0p5
e2fsck 1.46.3 (27-Jul-2021)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/nbd0p5: 3073/1201872 files (0.5% non-contiguous), 610228/4806400 blocks
# Изменим размер файловой системы на разделе
$ resize2fs /dev/nbd0p5
resize2fs 1.46.3 (27-Jul-2021)
Resizing the filesystem on /dev/nbd0p5 to 15292416 (4k) blocks.
The filesystem on /dev/nbd0p5 is now 15292416 (4k) blocks long.
# Посмотрим размер разделов
$ lsblk
nbd0 43:0 0 100G 0 disk
├─nbd0p1 43:1 0 1M 0 part
├─nbd0p2 43:2 0 1G 0 part
├─nbd0p3 43:3 0 3,1G 0 part
├─nbd0p4 43:4 0 37,6G 0 part
└─nbd0p5 43:5 0 58,3G 0 part
Теперь остается отключить виртуальный диск и запустить ВМ.
Про работу с LVM можно почитать здесь
Краткий гайд по монтированию qcow2-образа диска в хостовую машину. Полезно при необходимости, например сброса парол root, редактированию файлов или восстановления чего либо, без включения ВМ.
$ modprobe nbd max_part=8
$ qemu-nbd --connect=/dev/nbd0 /var/lib/vz/images/100/vm-100-disk-1.qcow2
$ fdisk /dev/nbd0 -l
$ mount /dev/nbd0p1 /mnt/somepoint/
$ umount /mnt/somepoint/
$ qemu-nbd --disconnect /dev/nbd0
$ modprobe -r nbd
Для начала потребуется скачать образ дополнений qemu для Windows
Все, кто когда-либо ставил MS Windows на неподдерживаемые официально версии «железа» сталкивались с тем, что в процессе установки система просто не видит дисков. Тогда приходится руками подпихивать имеющиеся драйвера на контроллеры и т.п. В бою с «железными активами» достаточно просто подпихнуть диск с оными (если не имелся, то была головная боль, но производители «железа» позже придумали «костыль» ввиде штатного flash-диска с драйверами). В случае с виртуализацией - драйвера можно подгрузить из iso-образа дополнений (см.выше)
В последствии эту «технологию» назвали plug-and-play, типа воткнул и работай (по сути, это набор драйверов, входящих в состав ОС)
Запускаем установку Windows:
$ virt-install
--virt-type kvm \
--name WindowsOS \
--ram 2048 \
--vcpus 4 \
--os-variant win10 \
--network network=default,model=rtl8139 \
--graphics vnc,port=5900,listen=0.0.0.0,password=passwd \
--cdrom /var/lib/libvirt/iso/windows10.iso \
--disk path=/var/lib/libvirt/vms/vm.qcow2,size=60,bus=virtio,format=qcow2 &
Далее подключаемся к ней по VNC и стандартно проходим шаги установки до момента выбора раздела диска. Видим, что установщик не видит дисков.
Выясняем какой девайс внутри ВМки является CD-ROM.
virsh dumpxml WindowsOS | grep -A 8 cdrom
Находим в выводе <target dev='<DevName>' bus.../>
И подменяем образ Windows на virtio-win.iso:
# Так
virsh change-media WindowsOS <DevName> /var/lib/libvirt/iso/virtio-win.iso
# Или вот так, в зависимости от ситуации
virsh attach-disk WindowsOS /var/lib/libvirt/iso/virtio-win.iso <DevName> --driver file --type cdrom --mode readonly
Потом подгружаем необходимые драйвера с диска и снова подменяем образ обратно:
virsh change-media WindowsOS <DevName> /var/lib/libvirt/iso/windows10.iso
И продолжаем установку. После установки ОС, драйвера брать снова на virtio-win
Ниже вырезка из содержания XML-определения Windows-системы с реального физического диска
...
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-6.1'>hvm</type>
<firmware>
<feature enabled='yes' name='enrolled-keys'/>
<feature enabled='yes' name='secure-boot'/>
</firmware>
<loader readonly='yes' secure='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader>
<nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'>/var/lib/libvirt/qemu/nvram/VMName_VARS.fd</nvram>
</os>
...
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/nvme1n1'/>
<target dev='sdc' bus='sata'/>
<boot order='1'/>
<address type='drive' controller='0' bus='0' target='0' unit='2'/>
</disk>
...
Здесь:
Потребуется установленный Zabbix-агент версии 2.
Итак, на сервере с qemu необходимо создать следующий конфиг для агента Zabbix:
# Общее количество виртуальных машин
UserParameter=qemu.vm.count,virsh --connect qemu:///system list --all --name | head -n -1 | wc -l
# Статус ВМ (работает или нет)
UserParameter=qemu.vm.status[*],virsh --connect qemu:///system domstate $1 | head -n -1
# Используемая память ВМ
UserParameter=qemu.vm.memory[*],mon-qemu.sh mem $1
# Используемый CPU ВМ
UserParameter=qemu.vm.cpu[*],mon-qemu.sh cpu $1
# Автообнаружение виртуальных машин
UserParameter=qemu.vm.discovery,echo '{ "data": ['; virsh --connect qemu:///system list --all --name | head -n -1 | awk '{print "{\"VMNAME\":\"" $1 "\"}"}' | paste -sd, -; echo ']}'
Затем создаем исполняемый скрипт (/usr/local/bin/mon-qemu.sh):
#!/bin/bash
case "$1" in
"cpu")
virsh --connect qemu:///system cpu-stats $2 --total | grep 'cpu_time' | awk '{ print $2 }'
;;
"mem")
virsh --connect qemu:///system dommemstat $2 | grep actual | awk '{ print $2 }'
;;
*)
echo "Usage: { cpu | mem } vmname"
;;
esac
Добавляем пользователя Zabbix в группу libvirt
usermod -aG libvirt zabbix
Теперь надо сделать соответствующий шаблон для Zabbix сервера.
Yaml-описание содержания шаблона
zabbix_export:
version: '6.4'
template_groups:
- uuid: 7df96b18c230490a9a0a9e2307226338
name: Templates
- uuid: c2c162144c2d4c5491c8801193af4945
name: Templates/Cloud
- uuid: 02e4df4f20b848e79267641790f241da
name: Templates/Virtualization
templates:
- uuid: 220f342dcf5a41a1ad700ac1a539a42e
template: 'QEMU VMs Monitoring by Zabbix Agent 2'
name: 'QEMU VMs Monitoring by Zabbix Agent 2'
groups:
- name: Templates
- name: Templates/Cloud
- name: Templates/Virtualization
items:
- uuid: df6cdd612f62475bbb7455d1d21d121a
name: 'QEMU Count of VMs'
key: qemu.vm.count
discovery_rules:
- uuid: c202197431524c848c059061d5efef42
name: 'QEMU VM Discovery'
key: qemu.vm.discovery
item_prototypes:
- uuid: 99d70a27ea9948c7841d5eb5881baceb
name: 'QEMU VM CPU Use {#VMNAME}'
key: 'qemu.vm.cpu[{#VMNAME}]'
value_type: FLOAT
- uuid: eeda66abf65d4d4abd12de4dd6290190
name: 'QEMU VM Memory Used {#VMNAME}'
key: 'qemu.vm.memory[{#VMNAME}]'
- uuid: 18a2f81da2f94d11bec0be4df7dfa20f
name: 'QEMU VM Status {#VMNAME}'
key: 'qemu.vm.status[{#VMNAME}]'
value_type: TEXT
trends: '0'
trigger_prototypes:
- uuid: 4315b1a6fa60407ea3149cf2c79a56b7
expression: 'last(/QEMU VMs Monitoring by Zabbix Agent 2/qemu.vm.status[{#VMNAME}],#3)<>"работает"'
name: 'QEMU VM Down {#VMNAME}'
priority: AVERAGE
graph_prototypes:
- uuid: ed318d213c4f40ca9000480f114f3077
name: 'VM Usage {#VMNAME}'
graph_items:
- color: 199C0D
calc_fnc: ALL
item:
host: 'QEMU VMs Monitoring by Zabbix Agent 2'
key: 'qemu.vm.cpu[{#VMNAME}]'
- sortorder: '1'
color: F63100
calc_fnc: ALL
item:
host: 'QEMU VMs Monitoring by Zabbix Agent 2'
key: 'qemu.vm.memory[{#VMNAME}]'
lld_macro_paths:
- lld_macro: '{#VMNAME}'
path: $.VMNAME
preprocessing:
- type: JSONPATH
parameters:
- $.data
macros:
- macro: '{$VMNAME}'
Да-да, все так. Microsoft Hyper-V нельзя причислить к виртуализации уровня Enterprise. Все дело в фундаментальном стремлении данной компании сделать цельное коробочное решение all-in-one. На этом пути, компания скупает, как нынче модно говорят, стартаппы, что зачастую того не стоит. Но здесь не об этом. В процессе описания, станет ясно, почему это решение не годится для Enterprise. И да, это единственная часть статьи, где используется Windows в качестве хостовой машины.
Приведу небольшую историческую справку о Microsoft и ее продуктах. Не теряй время и перехожи дальше.
Итак, некогда никому неизвестный Билл Гейтс работал в скромной компании IBM, которая на тот момент выпускала «железо». Билл пошел к руководству компании и предложил выпускать софт. Руководство посчитало эту идею неперспективной, так и появился Microsoft. Первым ее продуктом стал небезысвестный MS-DOS, который по сути был выкуплен (DR. DOS). Затем появились первые форточки, запускаемые прямо из DOS (WIN.COM). Однако свою наибольшую популярность Microsoft получил за счет Windows 98 (даже не 95). Эта ОС была революционной и прорывной для компании. В параллельной вселенной развивалась и ветка NT. Ее самый лучший продукт, на котором они перестали называть ее NT стал Windows XP (попытка сделать Windows ME провалилась, эта была первая попытка навести «красоту», покрасить форточки). До WinXP было 2 редакции NT-систем: Windows 2000 Professional и Windows 2000 Server (обратите внимание на порядок «слов» в названии продукта). По сути, Win2000Server - это Windows 2000 Pro + утилита установки серверных тулзов. Лишь в редакции 2003 серверная ОС получила название (и принцип именования по-прежнему сохраняется) Windows Server 2003. Тем временем (в параллели 2000 ОС) независимая команда программистов выпустила софт под Win - bochs (в последствии Connectix VirtualPC). Эта идея также приглянулась на тот момент уже богатому Биллу и он выкупил этот проект с потрохами. Проект свернулся, а в Windows 2008 выстрелил как MS Hyper-V. Если заинтересовал историей, то более подробно опишу в другой статье.
Потребуется на вход MS Windows Server 2008 и выше.
Разворачивается все стандартным способов MS - Далее, Далее, Далее, Готово.
Весь сыр-бор данного гипервизора снова упирается в сеть.