Очень часто в разработке возникает необходимость поднять локальное окружение для отладки каких-либо рабочих моментов. В своей работе я постоянно пользуюсь Vagrant для тестирования инфраструктурного кода, например ansible-ролей. Vagrant остаётся одной из самых популярных утилит для подобных задач, имеет гибкий синтаксис и поддержку базовых алгоритмических структур – можно поднимать N и K машин в цикле, используя заранее вводимые переменные, а потом еще и ansible-inventory генерировать на выходе, разбивая машины по группам.

Рисунок 1. Конфигурация Vagrant для цикличного создания виртуальных машин

Долгое время я оставался пользователем MacBook на процессоре Intel, но больше так продолжаться не могло – пришлось сменить компьютер, хотя я и знал о некоторых особенностях работы М1 с виртуальными машинами.

В этой статье я расскажу, как настроить и запустить Vagrant на процессорах Apple M1/M2 и вернуться в привычный рабочий режим.

Рабочая инсталляция

Рисунок 2. Рабочая инсталляция Vagrant на Apple M1/M2
  1. Rosetta 2: позволяет компьютерам Mac с процессорами Apple использовать приложения, созданные для компьютеров Mac с процессорами Intel.

  2. Vagrant (2.3.0+): программное обеспечение для создания и конфигурирования виртуальной среды разработки. Является обёрткой для программного обеспечения виртуализации, например VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и Puppet.

  3. Vagrant-vmware-desktop (3.0.1+): Плагин, который позволяет вагранту контролировать VMware-based машины, обеспечивая более высокую стабильность и производительность, чем ПО от VMware.

  4. Vagrant vmware utility (1.0.21+): Сервис предоставляющий vagrant-vmware-desktop e доступ к различным функциям VMware. Так же используется для выполнения операций, требующих привилегированного доступа на хосте, сетевых операций и верификации машин.

  5. Гипервизор (VMware Fusion Public Tech Preview 22H2): Гипервизор виртуальных машин


Установка

1. Rosetta

Первым делом, нужно установить Rosetta 2, для этого выполним следующую команду:

/usr/sbin/softwareupdate --install-rosetta --agree-to-license

2. Vagrant

Далее, необходимо установить сам Vagrant. Это можно сделать скачав его с официального сайта https://www.vagrantup.com/downloads – выбрав MacOS и установив dmg, либо через brew, выполнив команду:

brew install vagrant

Проверить, что Vagrant работает можно также из консоли:

vagrant -v                                                                                                                                                                 ✔
vagrant global-status
Рисунок 3. Примерный вывод только что установленного Vagrant

3. Гипервизор

Тут начинаются первые приколы, но обо всём по порядку. Просто так взять и скачать с сайта VMWare – мы не можем. Но можем посмотреть актуальную версию. Переходим на сайт https://customerconnect.vmware.com/downloads/get-download?downloadGroup=FUS-PUBTP-22H2, там находим и записываем цифры:

Рисунок 4. Запоминаем актуальную версию VMware Fusion Technology Preview II 22H2

После этого, можем скачать данный файл по ссылке, заменив версию на актуальную. Например, можно использовать команду:

wget https://download3.vmware.com/software/FUS-PUBTP-22H2/VMware-Fusion-e.x.p-#{version}_universal.dmg

В качестве альтернативы, можно поставить через brew:

brew install --cask vmware-fusion

Но это еще не всё. Дело в том, что "Tech preview" устанавливается по собственному пути (/Applications/VMWare Fusion Tech Preview.app), а провайдеры вагранта будут искать VMWare по стандартному (/Applications/VMWare Fusion.app). Чтобы исправить это недоразумение, воспользуемся командой:

ln -s /Applications/VMWare\ Fusion\ Tech\ Preview.app /Applications/VMWare\ Fusion.app

4. Vagrant vmware utility

Страница, посвященная данной утилите: https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility, но можно просто перейти по следующей ссылке, скачать и установить последнюю версию https://developer.hashicorp.com/vagrant/downloads/vmware. В качестве альтернативы, можно снова воспользоваться brew:

brew install vagrant-vmware-utility

После установки рекомендую проверить работоспособность утилиты, кстати, таким же образом её можно дебажить чтобы понять, что не работает (я так и узнал про несоответствие путей установки):

sudo /opt/vagrant-vmware-desktop/bin/vagrant-vmware-utility api -debug

В выводе может получиться ошибка, что порт 9922 уже занят. Такое случается, если утилита уже включилась и работает. Её можно выключить и подебажить.

Проверить заняты ли порты:

sudo lsof -i -P | grep LISTEN | grep 'vagrant-v'
Рисунок 5. Вывод консоли, если vagrant vmware utility занимает порт

Выгрузить утилиту:

sudo launchctl unload -w /Library/LaunchDaemons/com.vagrant.vagrant-vmware-utility.plist

Загрузить утилиту обратно:

sudo launchctl load -w /Library/LaunchDaemons/com.vagrant.vagrant-vmware-utility.plist

Также, проверить работоспособность утилиты можно командой:

sudo launchctl list | grep vagrant
Рисунок 6. Вывод консоли, если vagrant vmware utility успешно запущена

5. Vagrant VMWare Plugin

Для установки плагина просто выполняем команду:

vagrant plugin install vagrant-vmware-desktop

На этом инсталляция завершена, пора попробовать запустить виртуальную машину.

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

Далее, самое сложное :) В целом, всё вышеперечисленное может пройти без ошибок, но машина всё равно не запустится. Я перепробовал множество вариантов, комбинаций и настроек vagrantfile и предоставлю вам решение, которое заработало у меня и моих студентов.

Мне удалось выявить три главных проблемных места при запуске виртуальной машины:

  1. Бокс (образ виртуальной машины) для процессоров ARM
    Готовые образы отличаются провайдерами, под которые они заточены, процессорами, и содержимым. Есть популярные образы, которые у меня не заработали, есть образы с 100 загрузок, которые показали себя успешно.
    Я остановился на следующих: spox/ubuntu-arm и bytesguy/ubuntu-server-20.04-arm64

  2. GUI
    По причинам, которые я пока не смог выяснить (подскажите в комментариях!) – виртуальная машина не стартует, если GUI выключен (а он выключен по-умолчанию). В виду этой особенности, приходится добавлять параметр vmware.gui = true в конфигурации Vagrantfile

  3. Сеть
    Когда ваша машина уже практически работает, вагрант может предательски замереть на шаге ==> default: Waiting for the VM to receive an address...
    Решение было найдено – указать vmware.vmx["ethernet0.virtualdev"] = "vmxnet3" в конфигурации Vagrantfile

Создаем директорию для конфигурации нашей будущей машины и Vagrantfile в ней. Итоговый Vagrantfile получается следующим:

Vagrant.configure("2") do |config|
  config.vm.box = "spox/ubuntu-arm"
  config.vm.box_version = "1.0.0"
  config.vm.provider :vmware_desktop do |vmware|
    vmware.gui = true
    vmware.cpus = 2
    vmware.vmx["ethernet0.virtualdev"] = "vmxnet3"
    vmware.ssh_info_public = true
    vmware.linked_clone = false
  end
end

Выполняем запуск машины обычной командой vagrant up:

Рисунок 7. Успешный запуск виртуальной машины

Подключаемся к свежесозданной машине через vagrant ssh:

Рисунок 8. Успешное подключение по SSH

На этом всё, надеюсь моё руководство помогло вам сэкономить нервы и время. Желаю вам приятного пользования ноутбуком и до новых встреч :) Ну а если вы увлекаетесь DevOps и системным администрированием – жду вас у себя в ламповом сообществе в телеграмм: https://t.me/deusops

Полезные источники

  1. https://www.vagrantup.com/intro

  2. https://github.com/hashicorp/vagrant-vmware-desktop

  3. https://www.vagrantup.com/docs/providers/vmware/installation

  4. https://gist.github.com/sbailliez/f22db6434ac84eccb6d3c8833c85ad92

  5. https://github.com/hashicorp/vagrant/issues/12195

  6. https://github.com/hashicorp/vagrant/issues/12050

  7. https://www.youtube.com/watch?v=UZXFMCfXqh8

  8. https://www.vagrantup.com/docs/providers/vmware/configuration