Вопрос или проблема
Я разворачиваю виртуальные машины с помощью qemu. Установленная ОС – Debian с ядром linux debian 6.8.11-amd64. Мой способ развертывания ВМ – это прямой запуск команды qemu-system (т.е. без менеджера ВМ).
В командном формате я хочу – с хоста -:
- Запустить ВМ
- Выполнить серию команд внутри гостя (git clone что-то, сконфигурировать что-то, собрать что-то, выполнить что-то, вернуть успех!)
- Выключить ВМ
Я нашел, что можно обмениваться данными с ВМ через QMP с использованием специфических команд,
(https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html#id2)
Но я не могу найти, как выполнить мой шаг 2. Похоже, что только определенный набор команд разрешен с QMP..
Заранее спасибо,
Пьер
Вам нужно создать собственный образ файловой системы, который включает в себя скрипты и/или другие инструменты, которые выполнят ваши команды и выключат виртуальную машину. Существуют разные способы решения этой проблемы. Вот одно возможное решение:
-
Начните с образа операционной системы. В этом примере я использую образ облака debian 12.
-
Мы создадим копию образа с возможностью записи, чтобы удержать наши изменения. Это облегчает возможность начать с нуля. Здесь мы создаем образ размером 5 ГБ; вы можете отрегулировать размер образа в зависимости от вашей рабочей нагрузки:
qemu-img create -f qcow2 -F qcow2 \ -b debian-12-genericcloud-amd64.qcow2 root.qcow2 5g
-
Теперь нам нужно встроить некоторую дополнительную информацию в образ. В этом примере нам нужен файл 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/
-
Теперь мы можем использовать команду
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, ознакомьтесь с официальной документацией.
Применяя описанные методы, вы значительно упростите процесс автоматизации развертывания и управления вашими виртуальными машинами, что оптимизирует вашу рабочую среду и увеличивает продуктивность.