Создание виртуальной машины CentOS-7 из облачного образа для QEMU/KVM


Для тестирования установки PowerMTA перед развертыванием на VPS сервере провайдера решил установить будущую виртуальную машину у себя на машине. У меня уже установлен QEMU/KVM с вируальными машинами Ubuntu и Win11. Для PowerMTA эксперты советуют брать минимальную конфигурацию:

  • CentOS 7 x64 minimal
  • 1 core
  • 1 GB RAM
  • 10 GB HDD
  • 1 IP
  • 1 domain

Готовим снимок машины

Сначала качаем CentOS-7-x86_64-GenericCloud.qcow2 дистрибутив. Он занимает 903 Мб, а в развёрнутом виде 8 Гб.

Затем делаем копию в папке где хранятся снимки виртуальных машин:

sudo cp ~/Downloads/CentOS-7-x86_64-GenericCloud.qcow2 /var/lib/libvirt/images/centos7-image-snapshot.qcow2

На всякий случай расширим размер будущего снимка до 15 Гб.

sudo qemu-img resize /var/lib/libvirt/images/centos7-image-snapshot.qcow2 15G

Готовим ключи для доступа по ssh

Облачный образ обычно подразумевает доступ только по ssh, поэтому сгенерируем ключи для него:

ssh-keygen -t rsa -b 4096 -f id_rsa -C centos7 -N "" -q

В домашней папке появятся два файла “id_rsa” and “id_rsa.pub”. Чтобы потом не ломать голову, как зайти на виртуальную машину с помощью ssh и sftp (в файловом менеджере Nautilus в Ubuntu) надо добавить секретный ключ в файл known_hosts:

ssh-add id_rsa

Готовим конфигурацию облачного снимка

Создаем файл конфигурации cloud_init.cfg:

#cloud-config
hostname: my-domain
fqdn: my-domain.ru
manage_etc_hosts: true
users:
  - name: centos
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: adm,sys
    home: /home/centos
    shell: /bin/bash
    lock_passwd: false
    ssh-authorized-keys:
      - <sshPUBKEY>
# only cert auth via ssh (console access can still login)
ssh_pwauth: false
disable_root: false
chpasswd:
  list: |
     root:linux
     centos:newpass123
  expire: False

package_update: true
packages:
  - qemu-guest-agent
  - bind-utils
  - nano

# manually set BOOTPROTO for static IP
#runcmd:
#    - [ sh, -c, 'sed -i s/BOOTPROTO=dhcp/BOOTPROTO=static/ /etc/sysconfig/network-scripts/ifcfg-eth0' ]
#    - [ sh, -c, 'ifdown eth0 && sleep 1 && ifup eth0 && sleep 1 && ip a' ]
# written to /var/log/cloud-init.log, /var/log/messages
final_message: "The system is finally up, after $UPTIME seconds"

В этом файле не забудьте заменить “<sshPUBKEY>” содержимым файла “id_rsa.pub”.

Небольшое отступление. Мой ноутбук получает IP по DHCP от домашнего Wi-Fi роутера. Делать мост для гостевых машин c IP-адресами из той же сети смысла я не вижу, поэтому я сделал их за NAT. То есть мой ноутбук сидит помимо сети Wifi роутера в ещё одной, из которой динамически раздает гостевым машинам адреса. В последствии, естественно, захотелось зафиксировать адреса за отдельными машинами, чтобы не гадать, какой адрес у этой машины сейчас. Поэтому я в Virtual Machine Manager->Edit->Connection details->Virtual Netwroks->XML прописано следующее:

<network connections="1">
  <name>default</name>
  <uuid>d1a6181e-8c5d-43cd-b455-8551740869bf</uuid>
  <forward mode="nat">
    <nat>
      <port start="1024" end="65535"/>
    </nat>
  </forward>
  <bridge name="virbr0" stp="on" delay="0"/>
  <mac address="52:54:00:33:44:24"/>
  <ip address="192.168.122.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.122.100" end="192.168.122.254"/>
      <host mac="52:54:00:79:09:c5" name="centos-7" ip="192.168.122.62"/>
    </dhcp>
  </ip>
</network>

То есть закрепил за отпределенным MAC адресом свой IP адрес, помня, что у вирутальных гостевых машин MAC адрес всегда начинается с 52:54:00:. Чтобы внести эти изменения, сеть надо остановить, поправить настройки, применить их, и стартовать сеть снова.

Затем создаем файл настроек сети network_config_dynamic.cfg:

version: 2
ethernets:
  eth0:
    dhcp4: true
    dhcp6: false

Если на Ubuntu-хосте нет cloud-localds, то надо установить пакет:

sudo apt install cloud-image-utils

Создаем специальный конфигурационный образ:

sudo cloud-localds -v --network-config=network_config_dynamic.cfg /var/lib/libvirt/images/centos7-seed.qcow2 cloud_init.cfg

Создание виртуальной машины

Устанавливаем виртуальную машину:

sudo virt-install --name centos7 --virt-type kvm --memory 2048 --vcpus 1 \
--boot hd,menu=on \
--disk path=/var/lib/libvirt/images/centos7-seed.qcow2,device=cdrom \
--disk path=/var/lib/libvirt/images/centos7-image-snapshot.qcow2,device=disk \
--graphics spice --video qxl --channel spicevmc --os-variant centos7.0 \
--network network:default,model=virtio,mac=52:54:00:79:09:c5 \
--import

После того, как новая система загрузится, дайте ей пару минут на настройку сети и заходите через консоль или по ssh.

ssh centos@192.168.122.62

Примечание. У меня почему-то не сразу вируальная машина подхватила нужный ip адрес. Помогло передёргивание настроек сети Вируальной машины в Virtual Machine Manager. Пересоздание машины заново во второй раз прошло успешно. Возможно, я ждал чуть дольше.

Результаты работы можно посмотреть с помощью:

sudo less /var/log/cloud-init.log

и

grep cloud-init /var/log/messages

Небольшая приборка

Убираем cloud-init внутри гостевой машины:

# flag that signals that cloud-init should not run
touch /etc/cloud/cloud-init.disabled

# optional, remove cloud-init completely
yum remove cloud-init

# shutdown VM so CDROM seed can be ejected
shutdown -h now

Отключаем образ centos7-seed.qcow2 смонтированный в cd-rom с помощью Virtual Machine Manager.