- Разбираемся с загрузкой ArchLinux по сети
- Снова устанавливаем Linux
- Сравним загрузку с диска и загрузку по сети
- Настраиваем загрузку по сети с помощью GRUB
- Подготавливаем initramfs
- Загружаемся в Firefox
- Настраиваем загрузочный сервер
- Устанавливаем DHCP сервер
- Устанавливаем TFTP сервер
- Устанавливаем NFS сервер
- Пробуем загрузиться по сети
- Boot Ubuntu via http/ftp server with pxe(diskless boot)
- Intro
- Pxe short info
- How i do it
- Customize initramfs
- Creating squashfs
- Setup bootloader, squashfs, and pxe server
- Conclusion
Разбираемся с загрузкой ArchLinux по сети
В предыдущей статье мы подготовили базовую систему. Закончим настройку в следующей статье.
Здесь мы создадим новую систему Arch Linux, способную загружаться по сети и автоматически запускать браузер Firefox, а между делом разберёмся с необходимой функциональностью загрузочного сервера. Потом настроим сам сервер и попробуем с него загрузиться. Всё произойдёт в точности, как на картинке, которую нашёл гугл по запросу «PXE»:
Снова устанавливаем Linux
Archlinux выгодно отличается от готовых дистрибутивов тем, что установка новой системы из рабочей машины осуществляется точно так же, как при использовании установочного образа, и в обоих случаях вы получаете самую актуальную на данный момент версию системы. Понадобятся лишь небольшие установочные скрипты:
Совершенно предсказуемое начало:
Установим только базовые пакеты, поэтому:
Далее повторите все действия вплоть до установки загрузчика согласно предыдущей статье. Вот чек-лист:
- проведите русификацию (интернационализацию);
- укажите часовой пояс и настройте автозапуск службы NTP;
- добавьте пользователя username и заблокируйте его пароль от изменения.
Сравним загрузку с диска и загрузку по сети
В предыдущей статье мы рассматривали процесс загрузки Linux с точки зрения внутреннего накопителя. Сейчас мы представим происходящее глазами сетевой карты. Картинка из заголовка хорошо иллюстрирует события за исключением того, что все серверы в нашем случае будут работать на одном компьютере.
Сразу после включения компьютера, срабатывает код PXE (Preboot eXecution Environment, произносится пикси — спасибо вики), разместившийся непосредственно в ПЗУ сетевой карты. Его задача — найти загрузчик и передать ему управление.
Сетевой адаптер совершенно не представляет в какой сети сейчас находится, поэтому назначает себе адрес 0.0.0.0 и отправляет сообщение DHCPDISCOVER. К сообщению прикреплются паспортные данные, которые обязательно нам пригодятся:
- ARCH Option 93 — архитектура PXE клиента (UEFI, BIOS);
- Vendor-Class Option 60 — идентификатор, который у всех PXE клиентов имеет вид «PXEClient:Arch:xxxxx:UNDI:yyyzzz», где цифры xxxxx – архитектура клиента, yyyzzz – мажорная и минорная версии драйвера UNDI (Universal Network Driver Interface).
Адаптер ожидает получить ответ от DHCP сервера по протоколу BOOTP (Bootstrap Protocol), где помимо нужного IP адреса, маски подсети и адреса шлюза, присутствует информация об адресе TFTP-сервера и названии файла загрузчика, который с него следует забрать. Сервер TFTP, в свою очередь, просто отдаёт любому желающему любые файлы, которые у него попросят.
После получения ответа и применения сетевых настроек, дальнейшее управление загрузкой передаётся полученному файлу, размер которого не может превышать 32 кБ, поэтому используется двухстадийная загрузка. Всё необходимое для отображения на экране загрузочного меню докачивается следом по тому же протоколу TFTP. Подавляющее большинство руководств по сетевой загрузке использует загрузчик pxelinux, но GRUB умеет то же самое, и даже больше: в нём есть разные загрузчики для разных архитектур, включая UEFI.
Далее загрузка приостанавливается на время отображения загрузочного меню, а потом по тому же протоколу TFTP докачиваются выбранные файлы vmlinuz и initramfs, которым передается дальнейшее управление загрузкой. На этом этапе уже нет вообще никакой разницы в механизме загрузки по сети или с внутреннего накопителя.
Настраиваем загрузку по сети с помощью GRUB
Поскольку GRUB на нашем сервере уже есть, создадим с его помощью структуру папок для сетевого клиента вот таким образом:
В папке $root/boot появится папка grub и несколько других. Эту файловую структуру мы будем целиком «отдавать» с помощью TFTP-сервера. Сейчас мы используем 64-битный ArchLinux по той причине, что в 32-битной системе нет папки /grub/x86_64-efi/, которая требуется для загрузки систем UEFI. Можно взять эту папку с нашего 64-битного сервера и в неизменном виде перенести на 32-битный сервер, тогда в нём также появится поддержка UEFI.
Создайте файл конфигурации загрузчика со следующим содержимым:
Я взял файл grub.cfg с сервера и убрал из него всё то, что не участвует в отображении загрузочного меню GRUB или как-то связано с дисками.
Обратите внимание на знакомую нам строку с параметрами ядра:
Как и в предыдущий раз присваиваем значение переменной «ip». Напоминаю, что она используется в обработчике «net», который мы приспособили для настройки сетевой карты в загрузочном сервере. Здесь снова указывается статический IP адрес и постоянное имя сетевой карты eth0. Значения $net_default_ip и $net_default_server подставляются GRUB самостоятельно на основании данных, полученных из самого первого DHCP запроса. $net_default_ip – это выделенный для нашей машины IP адрес, а $net_default_server — IP адрес загрузочного сервера.
Большинство руководств по сетевой загрузке (среди обнаруженных на просторах рунета), предлагают устанавливать переменную так «ip=. eth0:dhcp», что вынуждает обработчик net отправлять новый запрос DHCPDISCOVER для повторного получения сетевых настроек.
Нет объективной причины лишний раз «спамить» DHCP-сервер и ждать, пока он откликнется, поэтому снова используем статику и не забываем указать DNS-серверы. Такую задачу мы уже решали, поэтому просто копируем нужные файлы и добавляем службу в автозагрузку:
Возвращаемся к строке с параметрами ядра. Ещё незнакомая нам команда add_efi_memmap (EFI memory map) добавляет EFI memory map доступной RAM. В прошлый раз мы её намеренно пропустили, из-за сравнительно сложной предварительной разметки носителя для поддержки UEFI. Сейчас нам ничего размечать не нужно, потому что файловая система на загрузочном сервере уже существует и будет использоваться в неизменном виде.
Переменная ядра — nfsroot показывает, где именно в сети нужно искать корневую файловую систему. Она выполняет ту же самую функцию, что и переменная root в загрузочном сервере. В данном случае указан адрес NFS-сервера, который в нашем случае совпадает с TFTP-сервером, но это совершенно необязательно.
Подготавливаем initramfs
За подключение корневой файловой системы по протоколу NFS отвечает обработчик net. В прошлый раз мы убирали из него эту функциональность, но сейчас она нам понадобится, правда, в немного доработанном виде. Дело в том, что обработчик net из коробки поддерживает подключение только по протоколу NFS версии 3. К счастью, поддержка 4-й версии добавляется очень просто.
Сначала установим пакет, в который входит нужный нам обработчик net, а также пакет утилит для работы с NFS (модуль nfsv4 и программа mount.nfs4):
Исправим обработчик net из папки hooks (вместо команды для монтирования nfsmount, теперь будем использовать mount.nfs4):
С помощью установщика обработчика из папки install добавим модуль nfsv4 и программу mount.nfsv4 в iniramfs. Сначала копируем и переименовываем заготовку:
Теперь исправляем только одну функцию build(), а всё остальное не трогаем:
Добавляем обработчик в initramfs путём исправления строки в файле mkinitcpio.conf:
Если ничего не трогать, то обычно для сжатия файла initramfs используется быстрый архиватор gzip. Мы не настолько торопимся, насколько хотим компрессию посильнее, поэтому воспользуемся xz. Снимаем комментарий с этой строки в файле mkinitcpio.conf:
Архивация xz происходит значительно дольше, но файл initramfs при этом уменьшается минимум в пару раз, из-за чего гораздо быстрее передается TFTP сервером по сети. Копируем пресет с нашего сервера, чтобы в ходе работы генерировался только один файл initramfs, после чего запускаем mkinitcpio:
Напоследок отредактируем fstab. Здесь можно подобрать опции монтирования корневой файловой системы, чтобы оптимизировать её работу, но мы ничего трогать не будем:
Базовая установка клиентской системы на этом закончена. Но мы хотим добавить графическое окружение и автоматический запуск Firefox.
Загружаемся в Firefox
Для уменьшения объема памяти, занимаемого нашей системой, мы откажемся от использования экранного менеджера и остановимся на простейшем оконном менеджере, например, openbox с автоматической авторизацией пользователя username. Использование «облегченных» компонентов позволит системе замечательно запускаться и работать даже на самом древнем железе.
Установим модули для поддержки VirtualBox, сервер X, симпатичный TTF-шрифт, openbox и firefox (все остальные модули будут установлены как зависимости):
Включаем автозагрузку службы virtualbox:
Добавим автоматический вход пользователя username без ввода пароля, для этого изменим строку запуска agetty:
Сразу же после авторизации пользователя выполняется файл
/.bash_profile, из его домашней папки, куда мы добавляем автоматический запуск графического сервера:
За запуском X-сервера должен стартовать openbox:
Закомментируйте следующие строки в самом конце файла (от строки twm до добавленной нами строки с запуском openbox, но не включая её):
Копируем конфигурационные файлы openbox
Добавляем firefox в автозагрузку в окружении openbox:
Поскольку мы только что от имени суперпользователя хозяйничали в домашней папке пользователя username, нам нужно вернуть ему права на все файлы, расположенные в его папке:
Подготовка системы к загрузке по сети закончена, и настала пора переходить к настройке загрузочного сервера. Теперь мы знаем, что для загрузки нам понадобятся:
- DHCP-сервер с поддержкой протокола BOOTP для настройки сетевой карты;
- TFTP-сервер для передачи загрузчика и файлов vmlinuz и initramfs, которые у нас находятся в папке $root/boot/grub;
- NFS-сервер для размещения корневой файловой системы, которая лежит у нас в папке $root.
Настраиваем загрузочный сервер
Дальнейшие шаги с небольшими изменениями повторяют эту статью из вики, поэтому минимум комментариев с моей стороны.
Устанавливаем DHCP сервер
и приводим содержимое конфигурационного файла /etc/dhcpd.conf к следующему виду:
Как видите, DHCP-сервер будет отвечать только на те запросы DHCPDISCOVER, которые придут от PXE клиентов, а остальные просто проигнорируются.
Запускаем DHCP сервер:
Устанавливаем TFTP сервер
Скачиваем и устанавливаем необходимый пакет:
Нам нужно, чтобы TFTP сервер предоставлял доступ к файлам загрузчика, которые мы разместили в папке $root/boot. Для этого модифицируем запуск службы уже проверенным способом:
Первая строка «ExecStart=» отменяет выполнение команды, указанной в оригинальном файле $root/usr/lib/systemd/system/tftpd.service, а вместо нее выполняется «/usr/bin/in.tftpd -s /srv/nfs/diskless/boot». Только в том случае, когда служба запускается однократно (Type=oneshot), мы можем использовать несколько строк ExecStart= чтобы выполнять команды одну за другой. Это не тот случай, поэтому отменяем одну команду и выполняем другую.
Запускаем TFTP сервер:
Устанавливаем NFS сервер
Добавляем папку, в которую мы установили систему, в список экспортируемых:
Не забываем использовать синтаксис NFS v.4 указывая путь относительно папки с fsid=root (корневой по отношению ко всем остальным экспортируемым папкам, без указания которой ничего работать не будет).
Запускаем службы, обеспечивающие работу NFS-сервера:
На этом загрузочный сервер готов к работе.
Пробуем загрузиться по сети
Проследим за процессом загрузки с сервера с помощью программы tcpdump
Первая строка «ловит» запрос DHCPDISCOVER от PXE клиента. В выводе, отфильтрованном второй строкой, будут перечислены имена всех файлов, запрашиваемых по TFTP. Третья строка показывает два tcp-syn запроса, отправляемых в самом начале подключения по протоколу NFS (первое соединение осуществляется обработчиком net, а второе переподключение происходит во время обработки файла fstab).
Создаём новую виртуальную машину, для краткости будем называть её «клиент». В настройках сети снова указываем тип подключения «Сетевой мост» и включаем машину. Сразу же нажимаем клавишу F12 на клавиатуре для выбора загрузочного устройства, а потом клавишу l, чтобы загрузиться по сети.
Дождитесь окончания загрузки. Если всё в порядке, то на сервере добавляем используемые службы в автозагрузку:
Все серверы DHCP, TFTP и NFS мы запустили на одном загрузочном сервере. Делать так необязательно. Например, роутеры Mikrotik поддерживают Bootp и позволяют использовать себя в качестве TFTP — просто закачайте туда все нужные файлы и проверьте сетевые настройки.
Сейчас графическое окружение будет работать только в VirtualBox, потому что мы не устанавливали драйверы для «железных» видеокарт. Мы решим проблему автоматического подбора нужных драйверов в следующей статье. Заодно ускорим загрузку системы и сделаем из неё «живой образ».
Источник
Boot Ubuntu via http/ftp server with pxe(diskless boot)
Intro
PXE is a great solution for booting a diskless computer (or a computer without an OS installed). This method is often used for terminal stations and OS mass installation.
Stock ubuntu (16.04) in pxe-mode can mount rootfs only from NFS. But this is not a great idea: any difficulties with the network/NFS server and the user gets problems.
In my opinion, it’s best to use other protocols, such as http/ftp. Once booting, you will have an independent system
You should add information about the limits of applicability of the proposed solution and what are the dependencies and restrictions.
Pxe short info
PXE (Preboot Execution Environment) is a special method for booting a computer from the bios / EFI.
How it works (simplified scheme):
- The computer bios/uefi sends ordinary dhcp request (DHCPDISCOVER)
- The dhcp server sends a response with the next-server option
- The computer sends DHCPREQUEST/DHCPINFORM request
- The dhcp server sends TFTP server address and the filename to upload
- The computer downloads this file from the tftp server. Its size is limited so, often, it’s a bootloader like pxeinux
- pxelinux reads its own config and downloads Linux kernel using initramfs
- Linux kernel downloads squashfs with main rootfs
- switch_root to its squashfs
Keep in mind that TFTP is a slow protocol. It works around UDP with a small block size (512K). Of course, you can increase this value, but this is a way of unstable operation.
A better solution:
- get bootloader via tftp
- get kernel (+ initramfs) via tftp
- get main rootfs squash via http/tftp
How i do it
Steps to solve the task:
- Add modules to initramfs
- Write my own boot script and add it to initramfs
- Make new initramfs
- Create squashfs with future rootfs
- Setup pxe server
- Run it
I used squashfs for rootfs (the simplest way is to create squashfs from installed ubuntu). Overlayfs is necessary to make rootfs writable.
Supported protocols are http/ftp, but you can try to add others via curl/other software.
Customize initramfs
There are 2 places where you can customize initramfs in ubuntu:
I’ll use /usr/share/initramfs-tools. First, I added needed support modules in initramfs:
Next, I wrote a boot script that does all the work:
The script has a lot of messages for understanding how it works.
After the modules and script, add your need to generate new initramfs:
Creating squashfs
The simplest method:
- install ubuntu on drive
- boot from LiveCD
- create squashfs from the installed system
I don’t recommend this way for production since you’ll have a very large squashfs (not the best idea for pxe)!
Setup bootloader, squashfs, and pxe server
I use pxelinux as a pxe bootloader. It’s an easy way. My pxe servers are Debian 10, tftp-hpa,dhcpd, and lighttpd.
I’ll omit the installation details, but I’ll show the important info.
TFRP server file struct (/srv/tftp is root dir fot tftp-hpa):
- firmware.sq is squashfs with rootfs
- *c32 are files for pxelinux
- vmlinuz is kernel
- initrd is initramfs(which i rebuild earler)
- pxelinux.bin — main pxelinux file
- default is config for pxelinux
It’s impotant to set the correct kernel parameters:
- rooturl=http://192.168.56.2/ubuntu/firmware.sq, url for rootfs
- boot=pxe, use my script for boot
- maxTryCount=10, number of tries for rootfs download (optional, default value 5)
And the last one is the dhcp config:
The extended variant (if the dhcp and tftp servers placed on different machines) requires the next-server option for dhcp.
Conclusion
This article shows you how to change the boot mode of ubuntu without any difficulties. Use it as information and write your solutions. This can be a system in the form of firmware (with squashfs), pxe, or another solution.
Источник