Как запустить виртуальную машину qemu и выполнить несколько команд с хоста, чтобы в конечном итоге её завершить.

Вопрос или проблема

Я разворачиваю виртуальные машины с помощью qemu. Установленная ОС – Debian с ядром linux debian 6.8.11-amd64. Мой способ развертывания ВМ – это прямой запуск команды qemu-system (т.е. без менеджера ВМ).

В командном формате я хочу – с хоста -:

  1. Запустить ВМ
  2. Выполнить серию команд внутри гостя (git clone что-то, сконфигурировать что-то, собрать что-то, выполнить что-то, вернуть успех!)
  3. Выключить ВМ

Я нашел, что можно обмениваться данными с ВМ через QMP с использованием специфических команд,
(https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html#id2)

Но я не могу найти, как выполнить мой шаг 2. Похоже, что только определенный набор команд разрешен с QMP..

Заранее спасибо,

Пьер

Вам нужно создать собственный образ файловой системы, который включает в себя скрипты и/или другие инструменты, которые выполнят ваши команды и выключат виртуальную машину. Существуют разные способы решения этой проблемы. Вот одно возможное решение:

  1. Начните с образа операционной системы. В этом примере я использую образ облака debian 12.

  2. Мы создадим копию образа с возможностью записи, чтобы удержать наши изменения. Это облегчает возможность начать с нуля. Здесь мы создаем образ размером 5 ГБ; вы можете отрегулировать размер образа в зависимости от вашей рабочей нагрузки:

    qemu-img create -f qcow2 -F qcow2 \
      -b debian-12-genericcloud-amd64.qcow2 root.qcow2 5g
    
  3. Теперь нам нужно встроить некоторую дополнительную информацию в образ. В этом примере нам нужен файл netplan для включения DHCP и скрипт rc.local, который выполнит наши действия по клонированию/сборке/установке и т.д.

    У меня есть файл netplan под названием network.yaml, который выглядит следующим образом:

    network:
      version: 2
      renderer: networkd
      ethernets:
        ens3:
          dhcp4: true
    

    И файл rc.local, который выглядит следующим образом:

    #!/bin/sh
    
    set -e
    
    while ! ping -c1 dns.google; do
      echo "ожидание сети"
      sleep 1
    done
    
    apt-get -y update
    DEBIAN_FRONTEND=noninteractive apt-get -y install gcc make autoconf automake libtool git autopoint gperf texinfo help2man
    
    mkdir -p /srv/build
    cd /srv/build
    git clone https://git.savannah.gnu.org/git/hello.git
    cd hello
    ./bootstrap
    ./configure --prefix=/usr/local
    make
    make install
    /usr/local/bin/hello
    
    poweroff
    

    Мы можем использовать команду virt-customize, чтобы встроить их в образ:

    virt-customize -a root.qcow2 \
      --copy-in network.yaml:/etc/netplan/ \
      --copy-in rc.local:/etc/
    
  4. Теперь мы можем использовать команду qemu-system-x86_64, чтобы загрузить наш образ:

    qemu-system-x86_64 -m 1g -enable-kvm \
      -nographic \
      -serial mon:stdio \
      -drive file=root.qcow2,driver=qcow2 \
      -nic user,model=virtio-net-pci
    

    Это выполнит команды в нашем файле rc.local и выключит ВМ по завершении.

Если вам нужно явно сообщить результаты обратно на хост, у вас есть множество опций. Вы можете добавить второй последовательный порт к вашей виртуальной машине (-serial file:status.txt) и записать статусные данные туда (echo OK > /dev/ttyS1), или вы можете захватить вывод консоли в файл (замените -serial mon:stdio на -serial file:console.txt) и затем grep вывод, когда ВМ завершит работу и т.д.

Если вас беспокоит, что скрипт может не завершиться из-за ошибки, вы можете обернуть вашу команду qemu-system-x86_64 в команду timeout. Например, чтобы убедиться, что qemu ВМ завершает работу за менее чем 2 минуты:

timeout 120 qemu-system-x86_64 -m 1g -enable-kvm ...

Я также могу предложить qemu-web-desktop, который предоставляет интерфейс на основе браузера и позволяет загружать bash-скрипты в процессе загрузки. Там также есть настройка тайм-аута.

Ответ или решение

Как запустить виртуальную машину QEMU и выполнить команды в ней из хост-системы

Введение

QEMU — мощный эмулятор, позволяющий создавать и управлять виртуальными машинами (VM) на платформе хост-операционной системы. В этой статье мы обсудим, как запустить виртуальную машину, выполнить в ней несколько команд, а затем корректно завершить её работу. Особенно стоит выделить, что мы будем использовать QEMU без сторонних менеджеров виртуальных машин, полагаясь на прямой ввод команд в терминале.

Шаг 1: Запуск виртуальной машины

Для начала нам потребуется создать виртуальную машину. Для этого мы будем использовать образ операционной системы Debian. Предполагается, что у вас уже установлен QEMU и необходимо создать новый виртуальный диск, на котором будет располагаться ваша виртуальная машина.

Команда для создания виртуального диска
qemu-img create -f qcow2 debian_vm.qcow2 10G

Эта команда создаст пустой диск размером 10 ГБ в формате QCOW2. Далее, чтобы запустить виртуальную машину с использованием этого диска, используем следующую команду:

qemu-system-x86_64 -m 1024 -enable-kvm -hda debian_vm.qcow2 -nographic -serial mon:stdio
  • -m 1024 — выделяем 1 ГБ оперативной памяти для виртуальной машины.
  • -enable-kvm — включает аппаратную виртуализацию (если поддерживается вашим процессором).
  • -hda debian_vm.qcow2 — указывает на созданный ранее диск.
  • -nographic — отключает графический вывод, позволяя работать только в текстовом режиме.
  • -serial mon:stdio — позволяет отправлять и получать данные через стандартный ввод/вывод.

Шаг 2: Выполнение команд внутри гостевой системы

Теперь, когда ваша виртуальная машина запущена, вы можете взаимодействовать с ней через QEMU Monitor Protocol (QMP). Однако, основной вопрос заключается в том, как выполнять произвольные команды внутри самой гостьевой операционной системы.

Чтобы выполнить команды в виртуальной машине, можно использовать такие инструменты, как virt-customize или создать скрипт на языке Bash, который будет автоматически запускаться при старте системы. Давайте рассмотрим создание простого сценария, который будет выполнять необходимые команды.

Пример файла rc.local

Создайте файл rc.local, который будет включать команды, которые вы хотите выполнить:

#!/bin/bash
set -e

# Ожидание доступности сети
while ! ping -c1 google.com; do
  echo "Waiting for network..."
  sleep 1
done

# Установка необходимых пакетов
apt-get update
apt-get install -y git build-essential

# Клонирование репозитория и сборка
git clone https://github.com/example/repo.git
cd repo
make install

# Завершение работы виртуальной машины
poweroff

Теперь вставьте этот файл в образ вашей виртуальной машины с помощью virt-customize:

virt-customize -a debian_vm.qcow2 --copy-in rc.local:/etc/rc.local

Не забудьте сделать его исполняемым:

chmod +x /etc/rc.local

Шаг 3: Завершение работы виртуальной машины

Как только все команды выполнены, виртуальная машина будет выключена автоматически благодаря команде poweroff в вашем скрипте. Вы можете также вручную завершить работу виртуальной машины, используя QMP команды:

{ "execute": "system_powerdown" }
Пример полной команды с QEMU

Вот как можно запустить QEMU с вашим вариантом образа:

qemu-system-x86_64 -m 1024 -enable-kvm -nographic -serial mon:stdio -drive file=debian_vm.qcow2,format=qcow2

Заключение

Следуя описанным шагам, вы сможете эффективно управлять виртуальными машинами на основе QEMU, запускать нужные вам команды и правильно завершать работу системы. Если вам потребуется дополнительная информация о QMP или QEMU, ознакомьтесь с официальной документацией.

Применяя описанные методы, вы значительно упростите процесс автоматизации развертывания и управления вашими виртуальными машинами, что оптимизирует вашу рабочую среду и увеличивает продуктивность.

Оцените материал
Добавить комментарий

Капча загружается...