PXE-загрузка Fedora CoreOS (FCOS) или Red Hat CoreOS (RHCOS) в среде Proxmox часто превращается в квест из-за особенностей работы Ignition вместо cloud-init. Если вы, как и я, потратили часы на перебор конфигов DHCP, переустановку TFTP-серверов и поиск волшебной комбинации параметров ядра – вы не одиноки.
Основная проблема в том, что традиционный подход с pxelinux.0 и menu.c32 не всегда дружит с современными версиями CoreOS, особенно когда речь заходит о совместимости загрузчиков.
Почему возникает ошибка ldlinux.c32 и как её обойти
Ошибка Failed to load ldlinux.c32 – классический симптом несовместимости между версией Syslinux (на которой построен PXE-загрузчик) и структурой вашего TFTP-сервера. Вот что стоит проверить в первую очередь:
- Соответствие версий: Убедитесь, что файлы pxelinux.0, ldlinux.c32 и menu.c32 взяты из одного и того же релиза Syslinux (рекомендую 6.xx или выше). Частая ошибка – смешивание файлов из разных дистрибутивов (например, CentOS 8 и Debian 12).
- Права доступа: TFTP-серверы иногда капризничают с правами на файлы. Попробуйте выставить chmod 644 на все файлы в директории /var/lib/tftpboot.
- Сетевые настройки Proxmox: Виртуальные машины должны быть подключены к мосту (vmbrX), а не к NAT (это частая ошибка при первом запуске).
Вот пример рабочего DHCP-конфига (обратите внимание на next-server и filename):
subnet 10.11.0.0 netmask 255.255.0.0 {
range 10.11.223.2 10.11.223.40;
option routers 10.11.111.100;
option domain-name-servers 10.11.2.71;
next-server 10.11.223.1; # Адрес TFTP-сервера
filename "undionly.kpxe"; # Ключевое изменение для iPXE
}
Кстати, если после всех манипуляций загрузка всё равно не работает – возможно, пора рассмотреть альтернативы. В моём случае спасением стал переход на iPXE (об этом ниже).
iPXE как решение проблем с традиционным PXE
iPXE – это расширенная версия PXE с поддержкой HTTP, SSL и других протоколов. Для CoreOS он подходит идеально, так как позволяет грузить скрипты напрямую с веб-сервера, минуя ограничения TFTP. Вот как это настроить:
1. Установите пакеты:
apt install ipxe tftpd-hpa isc-dhcp-server apache2 (Для Debian/Ubuntu; для RHEL/CentOS используйте ipxe-bootimgs и dhcp-server).
2. Скопируйте undionly.kpxe в директорию TFTP:
cp /usr/lib/ipxe/undionly.kpxe /var/lib/tftpboot/
3. Создайте скрипт загрузки (например, bootstrap.ipxe) на HTTP-сервере:
#!ipxe
kernel http://${WEB_SERVER_IP}/fcos/kernel nomodeset rd.neednet=1 console=tty0 console=ttyS0
initrd http://${WEB_SERVER_IP}/fcos/initramfs.img
initrd http://${WEB_SERVER_IP}/fcos/rootfs.img
boot
Важный нюанс: в Proxmox нужно указать MAC-адрес виртуальной машины в DHCP-конфиге, чтобы автоматизировать процесс. Для этого добавьте в /etc/dhcp/dhcpd.conf:
host okd-bootstrap {
hardware ethernet AA:BB:CC:DD:EE:FF;
filename "http://10.11.223.1/bootstrap.ipxe";
}
Совет: Если вы используете Terraform, добавьте параметр args = “-drive file=http://…/bootstrap.ipxe,readonly=on” в ресурс proxmox_vm_qemu — это избавит от ручного ввода MAC-адресов.
Подводные камни и альтернативные подходы
Даже с iPXE могут возникнуть сложности. Например:
- Ошибка No such file or directory при загрузке initrd – проверьте, что веб-сервер отдаёт файлы с правильным MIME-типом (особенно для .img и .ign).
- Проблемы с UEFI – если ваши VM используют UEFI вместо BIOS, замените undionly.kpxe на ipxe.efi.
Альтернативный вариант – использовать coreos-installer с предварительно модифицированными образами. Например:
coreos-installer install /dev/sda
--ignition-url http://${IP}/bootstrap.ign
--image-url http://${IP}/fcos/metal.qcow2
Но тут есть свои нюансы: нужно монтировать ISO в Proxmox, настраивать virtio-диски и т.д. Для автоматизации через Ansible я рекомендую модуль community.general.proxmox_kvm с параметром cloud_init: yes (да, это иронично, учитывая, что CoreOS его не поддерживает – но для скриптов установки подойдёт).
И напоследок: если всё это кажется слишком сложным, посмотрите в сторону OKD4 All-in-One – он может запускаться даже на одной ноде, что удобно для тестовых сред. Но для продакшена на Proxmox iPXE + Terraform + Ansible – пока самый живучий вариант (проверено на версиях 4.16–4.18).