Данная статья это авторский перевод/русскоязычная версия моей статьи на Medium, и первая из цикла про этот интересный инструмент.
Пожалуй, наиболее адекватным эпиграфом будет перефразированный английский перевод частушки «по реке плывет топор»:
Down the pipeline flows the code
From the towers of London.
Let it setup by itself
On this fancy piece of iron
Как это часто бывает, данный проект появился в результате случайности. Я всего лишь устанавливал Ubuntu на новую Dell rack workstation, когда элементарная задача неожиданно превратилась в «увлекательную». Зато открыло для меня совершенно новый уровень.
Поскольку это не совсем сервер, в машине нет модуля IPMI. Зато у этой модной железки есть 2 порта USB-C/DisplayPort и ни одного простого интерфейса для монитора. К сожалению, в коробке не было фирменного адаптера USB-C/DP – HDMI или в display port. А no-name, который оказался у меня в офисе под рукой, требовал изрядных танцев с бубном, чтобы на экране можно было увидеть хоть что-нибудь, пока к машине нельзя было добраться по SSH.
Поскольку машина предназначалась для тестов и разработки, переустанавливать систему приходилось неоднократно. Мне довольно быстро надоело это занятие, и я задумался, а можно ли как-то без этих альтернативных ощущений с монитором? Воображение рисовало идеальное конечное решение: хотелось вставить флэшку в бездыханную железяку, и на выходе получить вход по SSH. С одной стороны, без IPMI короткий ответ «нет» - нужно хотя бы вручную выбрать загрузочный диск, а лучше настроить boot sequence в BIOS. К сожалению, из коробки железяка мало того, что не загружается с внешнего носителя, так еще требуется сменить настройку RAID, чтобы система увидела внутренний SSD. И сделать это необходимо с едва работающим монитором. Но есть и хорошая новость: достаточно добраться до BIOS хотя бы один раз.
После этого жизнь начинает играть новыми красками. Поиск быстро привел меня к Ubuntu autoinstall https://ubuntu.com/server/docs/install/autoinstall Но если бы все было так просто. Как это часто бывает, качество документации не просто оставляет желать, но иногда может вводить в заблуждение. Например, я долго не мог разобраться с разницей между Ubuntu autoinstall и cloud-init. Позже объясню, почему.
С другой стороны, путешествие по граблям оказалось неожиданно полезным. Разработанные workarounds очень пригодились в дальнейшем, и них я расскажу в следующих статьях. Данный цикл статей это попытка восполнить пробел в документации, и поделиться знанием об очень интересном инструменте Ubuntu, и куда это может завести.
Это первая статья из цикла, и в ней мы реализуем простейший вариант. Мы создадим загрузочный образ ISO, который пока просто накатывает минимальный Ubuntu server. Все настройки по-умолчанию, сеть DHCP, OpenSSH сервер, логин и пароль. Я буду использовать авторизацию SSH по паролю, но ничего не мешает использовать ключи.
Все происходит полностью автоматически, причем без клавиатуры и монитора: вставили флэшку, нажали кнопку «вкл», и получили систему с SSH. И оно правда работает.
Готовим ингредиенты
Autoinstall использует yaml, который должен называться "user-data". Для ISO с автозапуском мы сохраним его в папке “/nocloud”. Вот содержимое /nocloud/user-data:
#cloud-config
autoinstall:
version: 1
identity:
hostname: ubuntu22auto
username: ubuntulogin
password: <mkpasswd -m sha-512 ubuntupass>
ssh:
install-server: yes
allow-pw: yes
Это минимально возможный конфиг autoinstall.
Важный момент: после установки система перезагрузится. Поскольку все происходит на полном автомате, система ничего не спросит, и ничем не выдаст свои намерения. На этот счет у меня есть любимый анекдот:
Человек приходит в патентное бюро регистрировать свое изобретение, универсальную бритвенную машину. Патентный клерк его спрашивает:
- Расскажите пожалуйста немного про свое изобретение? Как работает ваша машина?
- Ну вы вставляете в нее свое лицо, нажимаете на кнопку, и она вас бреет.
- Очень интересно.... Но лица же у людей все разные?
- Первый раз да.
Некоторые гипервизоры и карты IPMI сами отключат загрузочный образ при перезагрузке. Но давайте сделаем гарантированно безопасный вариант. На мой взгляд, наиболее чистой и аккуратной реализацией для автоматической установки без всего является выключение машины после установки системы. Таким образом у нас появляется совершенно четкая индикация, когда нужно извлечь загрузочный носитель, и включить сервер. Это можно сделать, добавив в конфиг bash комманду (об этом позже), но в autoinstall уже есть встроенная функция. Достаточно добавить:
shutdown: poweroff
Итак, у нас есть yaml для autoinstall. Теперь нужно объяснить Ubuntu, как его активировать. За это отвечает grub.cfg:
menuentry "Ubuntu autoinstall test" {
set fgxpayload=keep
linux /casper/vmlinuz "ds=nocloud;s=/cdrom/nocloud/" debug autoinstall ---
initrd /casper/initrd.gz
}
Вот, что на самом деле запускает автоматическую установку: “ds=nocloud;s=/cdrom/nocloud/” debug autoinstall Это папка, где лежит наш файл user-data, который мы только что создали. Данная строчка стоила мне изрядного количества седых волос - у меня получилось надежно заставить это работать с кавычками. Желающим не возбраняется поэкспериментировать с escape символами без кавычек. Так же, для прода я бы заменил ‘debug’ на ‘quiet’.
Настраиваем среду разработки
Итак, конфиги готовы. А как их теперь встроить в загрузочный ISO образ Ubuntu?
Документация autoinstall обычно описывает хардкор вариант через боль, и не слишком подробно. К этому мы тоже придем в дальнейших статьях цикла, по мере продвижения в сторону сложных сценариев и сборки образа с помощью CI/CD pipeline. Пока начнем с простого, и будем наращивать сложность постепенно.
Итак, просто и не больно это делается с помощью приложения CUBIC, Custom Ubuntu ISO Creator, https://github.com/PJ-Singh-001/Cubic. Давайте его установим. Начнем с чистой виртуалки Ubuntu 22.04 Desktop в качестве среды для сборки образа. Дальше все просто, как написано в readme:
sudo apt-add-repository universe
sudo apt-add-repository ppa:cubic-wizard/release
sudo apt update
sudo apt install --no-install-recommends cubic
Теперь он откликается на "cubic" в терминале. Создаем папку под наш проект, например U22AutoInstallBuildV0.1:
![Стартовый экран CUBIC Стартовый экран CUBIC](https://habrastorage.org/getpro/habr/upload_files/304/466/423/304466423ca762d93cda4c0bd414c200.jpg)
Скачиваем ISO образ Ubuntu server. Я сохраню его в папке "Downloads". Обратите внимание на ссылку, которую я использую. В дальнейшем это пригодится:
wget http://releases.ubuntu.com/22.04/ubuntu-22.04.4-live-server-amd64.iso
Теперь, выбираем его в качестве исходника, и настраиваем проект. CUBIC подтянет метаданные из ISO. Давайте внесем изменения:
![CUBIC, метаданные проекта CUBIC, метаданные проекта](https://habrastorage.org/getpro/habr/upload_files/aa0/7dc/207/aa07dc207e97ca9ec73685d922b333a1.jpg)
Распаковываем дистрибутив ISO:
![CUBIC, распаковка образа CUBIC, распаковка образа](https://habrastorage.org/getpro/habr/upload_files/b98/731/857/b9873185792639e9a04fa8e120444915.jpg)
Теперь мы попадаем в chroot shell, где можно вносить изменения в дистрибутив. В данной статье мы этого делать не будем, поэтому пока пропускаем:
![CUBIC chroot shell. CUBIC chroot shell.](https://habrastorage.org/getpro/habr/upload_files/165/2d6/225/1652d6225d055f6b88a92716c7c760c2.jpg)
![CUBIC image customization progress. CUBIC image customization progress.](https://habrastorage.org/getpro/habr/upload_files/071/3b5/7c8/0713b57c8675b17b2846d6dad07ecfb0.jpg)
На этом экране мы могли бы изменить версию ядра, если бы у нас были варианты на выбор. Раздел "Preseed", вероятно, наследие старых версий Debian/Ubuntu. Свежие версии Ubuntu устанавливаются с помощью Subiquity, и не используют preseed файлы:
![CUBIC kernel options. CUBIC kernel options.](https://habrastorage.org/getpro/habr/upload_files/cd0/ad6/488/cd0ad6488ff179132a4e2fae37f7f7d1.jpg)
Редактируем конфиги с помощью VSCode.
Вкладка “Boot” уже более полезна. Помните, нам необходимо внести правки в grub.cfg?
![CUBIC boot settings. CUBIC boot settings.](https://habrastorage.org/getpro/habr/upload_files/1b8/1ab/76d/1b81ab76d81b573d480df7671bb19d34.jpg)
Это можно сделать здесь, но я предпочитаю VSCode.
Если на нашей чистой виртуалке Ubuntu еще не установлен OpenSSH server, то:
sudo apt install openssh-server
Теперь в нее необходимо скопировать ключ ssh, чтобы VSCode не задолбал запросами пароля 100 раз. В случае Windows я предпочитаю MS Windows Terminal который устанавливается из Microsoft Store. В нем уже есть встроенный клиент ssh:
ssh-keygen
Сгенерированные ключи id_rsa & id_rsa.pub лежат в папке .ssh в домашней директории пользователя. В других операционных системах работает примерно так же.
Если у вас чистая Ubuntu, проверьте наличие хотя бы пустого файла ~/.ssh/authorized_keys в домашней директории пользователя. Если его еще нет, создаем:
mkdir -p ~/.ssh
cd ~/.ssh
touch authorized_keys
Теперь копируем публичный ключ с нашей основной машины. В Windows:
scp ~/.ssh/id_rsa.pub ubuntulogin@<remotehost>:~/.ssh/authorized_keys
Проверяем:
ssh ubuntulogin@<remotehost>
Теперь подключаемся из VSCode. Проверьте, что у вас установлен Remote extension pack или хотя бы Remote-SSH:
![](https://habrastorage.org/getpro/habr/upload_files/94c/5a9/21e/94c5a921e9519ef9bc86b30e56af4329.jpg)
Не забудьте проверить/поменять логин:
![](https://habrastorage.org/getpro/habr/upload_files/3b4/417/324/3b441732494bd9b04a8c684120d325e5.jpg)
После этого система запросит конфигурацию, и запустит удаленное подключение в новом окне. Чтобы не путаться, я сразу открою непосредственно папку проекта:
![Структура папок проекта CUBIC Структура папок проекта CUBIC](https://habrastorage.org/getpro/habr/upload_files/f54/15e/cc9/f5415ecc9d3163f20f7f728c93a46b78.jpg)
Перед нами структура папок дистрибутива Ubuntu в варианте, как ее распаковал CUBIC. В следующих статьях мы посмотрим на нее более детально, а сейчас нас интересует только custom-disk:
![Структура папки custom-disk Структура папки custom-disk](https://habrastorage.org/getpro/habr/upload_files/45c/d01/43b/45cd0143b3f359c6cd0d0b10201afc47.jpg)
Первым делом, создаем папку nocloud и yaml файл user-data, который мы уже сформировали выше. Так же необходимо создать пустой файл meta-data. Он нам не понадобится, но система требует наличие заглушки.
Следующий важный элемент это пароль пользователя:
mkpasswd -m sha-512 ubuntupass
полученный хэш необходимо вставить в наш конфиг:
$6$LmPUjxOfMHOMgRlg$pSXXVlcfwSKUSotcoG6ed7DUu7.iOX7kJEylN9V9z3C96uNBIMfCJjtL1tNjLx9dDbKS/kH9W7B8oIMKxmXb70
Если mkpasswd не установлен по-умолчанию,
![недостающий mkpasswd недостающий mkpasswd](https://habrastorage.org/getpro/habr/upload_files/456/2d2/48a/4562d248aa2cd2f95ce5419e525313a8.jpg)
добавляем, как указано:
sudo apt install whois
Вот наш рабочий user-data yaml:
![файл user-data файл user-data](https://habrastorage.org/getpro/habr/upload_files/a5c/66f/572/a5c66f572c6e8a14c73aaa3ba50b0a04.jpg)
Все практически готово. Осталось подредактировать grub.cfg. Он хранится в папке custom-disk/boot/grub:
![grub.cfg grub.cfg](https://habrastorage.org/getpro/habr/upload_files/cd2/b5f/14d/cd2b5f14d177d5a42fddcd9091672496.jpg)
Это простой конфиг. Я добавил в него пункт меню, причем он запустится по-умолчанию, поскольку стоит первым в списке.
Второе изменение это таймаут. Его я изменил с 30 секунд на 10, но можно и меньше, если не планируете вмешиваться в процесс загрузки.
Собираем ISO
На этом все. Остается только запаковать это обратно в ISO образ. Нажимаем "Next", и можно запускать. Лично я предпочитаю паковать образы xz, почему объясню в следующих статьях.
![CUBIC, выбор архиваторов для упаковки CUBIC, выбор архиваторов для упаковки](https://habrastorage.org/getpro/habr/upload_files/15b/101/a20/15b101a20c8df0875624c4a58c8c6cd5.jpg)
![CUBIC image generation progress CUBIC image generation progress](https://habrastorage.org/getpro/habr/upload_files/3cd/f0f/cd8/3cdf0fcd8c58efdcf66d71d82e5d7ee5.jpg)
Проверяем готовый образ
![CUBIC готовый образ с метаданными CUBIC готовый образ с метаданными](https://habrastorage.org/getpro/habr/upload_files/4c0/c46/f48/4c0c46f481a97197c63ccd6a4e881e94.jpg)
В CUBIC есть функция проверки “Test” готового ISO с помощью QEMU. Она может быть полезной для простых сценариев (убедитесь, что у вас настроена вложенная виртуализация). Пробуем:
![CUBIC тестируем образ с помощью QEMU. CUBIC тестируем образ с помощью QEMU.](https://habrastorage.org/getpro/habr/upload_files/66f/763/b05/66f763b05aedecfc9122ce2ec36a8010.jpg)
К сожалению, в моей практике работает нестабильно. В частности потому, что обычно я запускаю его на виртуалках:
![вылетел вылетел](https://habrastorage.org/getpro/habr/upload_files/5cc/651/13b/5cc65113bb7fdaebb13523729f5ca592.jpg)
Вам может повезти больше. Это зависит от гипервизора, ресурсов, некоторых тонкостей в настройках, фазы луны и т.д. С ESXi мне обычно везет больше, и то на простых образах, а в данном случае я использую Hyper-V. В любом случае, для реальных проектов я от этого способа давно отказался, и использую полноценные виртуалки.
Создадим выделенную виртуальную машину для теста. Проверяем, что в ней есть стандартные настройки под Ubuntu. ESXi, Proxmox, XCP-NG, LXD ничего дополнительно не требуют. Hyper-V, который я использую для данного демо, требует отключить “Enable Secure Boot”:
![Hyper-V требует отключить “Enable Secure Boot” Hyper-V требует отключить “Enable Secure Boot”](https://habrastorage.org/getpro/habr/upload_files/951/32a/cbb/95132acbbc120d6cd0e5d675aa5a0ef0.jpg)
Подключаем наш полученный образ.... и оно просто работает:
![Успешно установленная Ubuntu Успешно установленная Ubuntu](https://habrastorage.org/getpro/habr/upload_files/53d/408/fd2/53d408fd230a45df302edafc3361e350.jpg)
Итог
В данной статье мы научились создавать образ Ubuntu с простейшими настройками для автоматической установки. Так же я обратил ваше внимание на некоторые грабли. Еще мы настроили среду для сборки образов с необходимыми утилитами, и успешно протестировали полученный ISO.
В следующих статьях, мы рассмотрим уже более сложные сценарии.
Комментарии (3)
qwertyshka
13.05.2024 13:52Теперь мы попадаем в chroot shell, где можно вносить изменения в дистрибутив. В данной статье мы этого делать не будем, поэтому пока пропускаем...
Не так давно, при работе с Кубиком, именно на этом этапе у меня были проблемы - не смог установить дополнительные программы через apt и snap.
Sanes
Cloud-init не тоже самое?
Phoenixforge Автор
Вот именно, что нет. И про то, как я долго ходил по этим граблям, пока не понял разницу, будет в следующей статье.