Bare-metal provisioning через PXE + kickstart + Ansible: новый сервер за 20 минут без рук
Собрали конвейер: PXE-загрузка, kickstart/preseed, Ansible playbook. Физический сервер от включения до рабочего состояния - без единого ручного шага.
Рост числа bare-metal серверов делает ручную установку ОС узким местом; PXE + kickstart/preseed автоматизируют первый этап, Ansible закрывает провизионирование
Когда серверов три-пять, установить операционную систему руками - не проблема. Когда их становится больше, и они прибывают пачками (расширение стойки, перевод клиента на новую платформу, замена железа), ручная установка превращается в унылый ритуал с флешкой и кликами по инсталлятору. Мы дотерпели до того момента, когда за месяц нужно было поднять полтора десятка физических машин, и наконец взялись за нормальный конвейер.
Задача звучит просто: воткнул сервер в сеть, включил - через двадцать минут он готов к работе. Без ISO, без консоли KVM, без ручного ввода пароля на шаге «Куда ставить?». На сопровождении это экономит не только время, но и нервы - особенно когда сервер в ДЦ, а инженер в офисе.
Из чего состоит конвейер
Три звена, каждое делает своё.
PXE-загрузка. Сервер уходит в сеть, DHCP отдаёт ему адрес и указывает на TFTP. Оттуда - pxelinux, меню загрузки, ядро и initrd с инсталлятора. Никакого физического носителя. DHCP у нас уже был, TFTP подняли отдельно - несложно, но надо аккуратно с DHCP-опциями (66, 67) и убедиться что broadcast доходит до нужного VLAN.
Kickstart (для CentOS/RHEL) / preseed (для Debian). Файл ответов: разбивка диска, root-пароль (захешированный), базовый набор пакетов, сеть, временная зона, и главное - в самом конце секция %post, которая скачивает и запускает Ansible. Файлы лежат на простом HTTP-сервере в управляющей сети, pxelinux передаёт путь к нужному через ks= или preseed/url=.
Ansible playbook. После того как инсталлятор заканчивает работу, %post делает ровно два действия: устанавливает ansible из репозитория и запускает ansible-pull из нашего git-репозитория. Дальше - те же роли, что мы описывали в январе: пользователи, SSH, Zabbix-агент, NTP, базовые пакеты. Роли лежат в структуре, которую выстраивали отдельно.
Что на практике
Схема выглядит красиво на бумаге и работает - но с нюансами, которые выяснились при первых прогонах.
Timing PXE-меню. По умолчанию pxelinux ждёт выбора в меню несколько секунд, потом грузится в первый пункт. Мы сначала поставили автоматический старт на «Install CentOS 7» и чуть не переустановили сервер, который просто перезагружался. Пришлось разделить: в managed-сети меню по умолчанию загружается с локального диска, автоматическая установка - только в отдельном VLAN для провизионирования. Теперь новый сервер приходит с тегом VLAN, после установки его перекидывают в нужный сегмент.
%post и сеть. В секции %post установщик работает в chroot, и сеть там иногда ведёт себя странно - особенно на CentOS 6. ansible-pull с первого раза не запускался, потому что git clone падал с таймаутом. Решили: установщик ставит только git и ansible, записывает unit-файл systemd (или скрипт в /etc/rc.local для CentOS 6), который запускается при первой загрузке уже в полноценной системе. Чуть дольше, зато надёжно.
Kickstart для разного железа. Разбивка диска зависит от конфигурации: одно у серверов с одним диском, другое с RAID-контроллером, третье с NVMe. Сделали несколько вариантов kickstart-файлов - ks-singlehdd.cfg, ks-raid1.cfg и так далее. В меню pxelinux - отдельные пункты для каждого варианта. Не идеально (хочется детектировать автоматически), но работает.
ansible-pull vs ansible-playbook. Изначально думали использовать обычный push-режим: Ansible-сервер сам подключается к новому хосту и гонит playbook. Не взлетело - хост появляется в сети в момент первой загрузки, и точный момент когда SSH уже готов - неизвестен. Polling с ожиданием можно сделать, но ansible-pull проще: хост сам инициирует, сам тянет, сам применяет. Нет проблемы «когда подключаться».
Сколько занимает
От включения питания до «сервер в мониторинге и готов принимать роли» - 18-22 минуты на нашем железе. Из них: PXE-boot и загрузка инсталлятора - 2-3 минуты, разбивка и установка ОС - 8-10 минут, перезагрузка и Ansible - 5-7 минут. Цифра зависит от скорости сети в ДЦ и диска - на SAS быстрее, на SATA медленнее.
Раньше то же самое занимало 40-60 минут вместе с дорогой к консоли (или ожиданием KVM-доступа), установкой с флешки и ручным провизионированием по чеклисту. И это в лучшем случае - без ошибок и отвлечений.
Что ещё не автоматизировано
Два момента пока остаются ручными. Первый - добавление записи в DHCP с MAC-адресом нового сервера: нужно знать MAC заранее или подключиться к коммутатору и посмотреть ARP. Второй - перекладывание порта в нужный VLAN после установки. Оба места можно автоматизировать через API управляемых коммутаторов, но это следующий шаг, пока руки не дошли.
В целом конвейер работает и уже прошёл через несколько реальных серверов. Основная ценность не в скорости даже, а в воспроизводимости: каждый сервер проходит один и тот же путь, никаких «ой, я тут вручную поправил» и отклонений от базовой конфигурации.