Статьи

Параллельное обеспечение ускорения Vagrant

Бродяга — удивительный инструмент. Это довольно существенно изменило мои рабочие процессы во множестве областей. Это особенно интересный инструмент для сборки пакетов или запуска тестов в нескольких ОС или дистрибутивах из одного набора скриптов.

Недавний пример полезности Vagrant — новая работа по упаковке и тестированию, проводимая в проекте Sensu . Проект был направлен на создание нового набора собственных пакетов ОС с целью облегчить развертывание Sensu на различных платформах и без особых трудностей, которые иногда сопровождают приложения Ruby. В рамках процесса упаковки нам понадобился простой механизм для создания собственных пакетов на соответствующих платформах, а именно: .deb в debian и .rpm в redhat / centos.

В итоге мы использовали комбинацию Vagrant и некоторых доморощенных инструментов, таких как Bunchr .

Вы можете увидеть работу в этих двух репозиториях:

Обе кодовые базы содержат скрипт para-vagrant.sh, который используется вместо обычного vagrant для запуска параллельных задач обеспечения. Sensu-tests — более интересный пример, поскольку он запускает набор тестов rspec для Sensu на 14 виртуальных машинах , и в будущем он, вероятно, будет расширяться, чтобы охватить другие ОС. Тесты выполняются как провайдеры Vagrant (комбинация Chef и shell для вызова rspec).

Самый простой способ использовать несколько виртуальных машин с Vagrant — это типичный vagrant up. Однако это будет запускать и запускать задачи обеспечения последовательно на каждой виртуальной машине. Для тестирования 14 виртуальных машин этот процесс может занять много времени.

Можем ли мы ускорить это? Да. Фактически мы смогли сократить время, необходимое для выполнения задач сборки Sensu, с 33 до 12 минут, а задачи Sensu — почти с 90 до 15 минут!

Вот первая попытка сценария распараллеливания:

#!/bin/sh
 
# concurrency is hard, let's have a beer
 
MAX_PROCS=4
 
parallel_provision() {
    while read box; do
        echo "Provisioning '$box'. Output will be in: $box.out.txt" 1>&2
        echo $box
    done | xargs -P $MAX_PROCS -I"BOXNAME" \
        sh -c 'vagrant provision BOXNAME >BOXNAME.out.txt 2>&1 || echo "Error Occurred: BOXNAME"'
}
 
## -- main -- ##
 
# start boxes sequentially to avoid vbox explosions
vagrant up --no-provision
 
# but run provision tasks in parallel
cat <<EOF | parallel_provision
centos_5_64
centos_5_32
ubuntu_1004_32
ubuntu_1004_64
EOF

Есть 2 шага к процессу:

  • Последовательно загрузите каждую виртуальную машину, указанную в Vagrantfile, но без запуска инициаторов (vagrant up —no-provision). Причина, по которой мы последовательно выполняем загрузку, состоит в том, чтобы избежать потенциальной паники ядра, которую склонен делать VirtualBox, по крайней мере, в OSX.

  • Передайте список виртуальных машин в xargs для параллельного выполнения процессов $ BOXNAME $ MAX_PROCS vagrant предоставления. Xargs будет управлять параллелизмом для нас.

Последний скрипт, который мы использовали с репозиторием sensu-tests, немного отличается от приведенного выше примера, который можно посмотреть здесь: para-vagrant.sh . Этот скрипт сократил время, необходимое для запуска полного набора тестов, с более чем 90 минут до 15 минут. Отличия в этой финальной версии скрипта:

  • использует параллельный GNU вместо xargs для лучшей обработки / группировки выходных данных от процессов vagrant предоставления.

  • читает список виртуальных машин из файла JSON (Vagrantfile также использует этот файл JSON). Чтобы добавить / удалить новые виртуальные машины, вам нужно отредактировать только один файл.

Будущее?

Должна быть возможность ускорить процесс, распараллелив фазу загрузки, но я еще не пробовал, потому что беспокоюсь о стабильности VirtualBox.

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

Альтернативы?

Как правильно указывает @vvuksan , выполнение таких коротких задач с Vagrant, вероятно, всегда будет немного медленным из-за накладных расходов при раскрутке виртуальных машин, поэтому возможной альтернативой может быть LXC. Уже есть инструмент, похожий на Vagrant для LXC, который называется Toft . LXC должен нормально работать для рабочих процессов, которые включают только различные дистрибутивы Linux, но не поможет, если вам нужно протестировать другие ОС, такие как FreeBSD или Solaris.