PXE + preseed/kickstart: новый сервер за 12 минут без администратора
Написали preseed для Ubuntu 8.04 и kickstart для CentOS 5 - виртуальный сервер разворачивается за 12 минут без участия человека. Документируем шаблоны.
Практика автоматизации развёртывания серверов через PXE + kickstart/preseed набирает популярность в 2008 году вместе с ростом виртуализации
Месяц назад количество виртуальных машин у нас перевалило за отметку, при которой разворачивать каждую вручную уже физически неудобно. Не то чтобы мы раньше этого не понимали - понимали. Просто при пяти машинах в месяц можно было терпеть. Сейчас запросы на новые VM приходят быстрее, чем мы успеваем их обрабатывать, и каждая ручная установка - это час-полтора работы, которую хочется отдать скрипту.
Решение очевидное: PXE-загрузка плюс автоответные файлы. На Ubuntu это preseed, на CentOS - kickstart. Оба механизма существуют давно, мы о них знали, но руки дошли только сейчас.
Как это работает в общем виде
Схема загрузки простая:
DHCP -> PXE -> TFTP (pxelinux + ядро) -> HTTP (preseed/ks.cfg) -> установщик
Новая виртуальная машина при старте получает адрес по DHCP, сервер возвращает опции 66 и 67 с адресом TFTP и именем загрузчика. Машина скачивает pxelinux.0, загружает ядро из TFTP и начинает установку. Установщик в процессе запрашивает preseed- или kickstart-файл по HTTP и отвечает на все вопросы сам.
В итоге: включил VM, через 12 минут она готова к работе. Без единого нажатия.
Preseed для Ubuntu 8.04
Ubuntu использует debian-installer, и preseed-файл - это просто набор ответов на все вопросы установщика, заранее записанных в формате d-i <директива> <значение>.
Ключевые блоки нашего шаблона:
- Локаль и клавиатура.
d-i debian-installer/locale string ru_RU.UTF-8- и установщик не спрашивает про язык. - Сеть. Берём по DHCP во время установки, статику прописываем уже постфактум через puppet. Так удобнее: установщику нужен адрес, чтобы скачать пакеты, но окончательную сетевую конфигурацию лучше держать в одном месте.
- Разметка диска.
d-i partman-auto/method string lvm- автоматическая разметка с LVM. Схема типовая: небольшой /boot без LVM, остальное - volume group, из которой нарезаем /, /var, swap. Минимальный набор томов, чтобы потом было куда расширяться. - Пользователь и sudo. Создаём одного пользователя-администратора, пароль root блокируем. Все дальнейшие доступы - через sudo и SSH-ключи, которые puppet раскладывает при первом прогоне.
- Постустановочный скрипт.
d-i preseed/late_command string ...- самое главное. Здесь мы устанавливаем puppet, прописываем адрес puppet master и запускаем первыйpuppet agent --test. Дальше puppet берёт машину под контроль.
Одна тонкость, на которой мы споткнулись: preseed-файл нужно давать установщику до того, как он начнёт задавать вопросы, иначе часть ответов он уже запросил и файл их не закрывает. Для PXE это решается параметром ядра url=http://... в pxelinux.cfg - тогда preseed подтягивается в самом начале.
Kickstart для CentOS 5
Формат kickstart читается легче - он больше похож на ini-файл с секциями, чем на список команд debian-installer.
Существенные части нашего ks.cfg:
%packages- явный список пакетов без лишнего. Базовая система, openssh-server, puppet, vim. Никакого@baseбез разбора - ставим то, что нужно.clearpart --all --initlabel- очистка диска. Важно не забыть, иначе при переустановке установщик встанет и будет ждать подтверждения.part /bootиvolgroup/logvol- та же LVM-схема, что в preseed. CentOS умеет описывать LVM прямо в kickstart-директивах, без отдельного скрипта.%post- аналог late_command. Ставим puppet, прописываем puppet master, генерируем сертификат и запускаем первый прогон.
На CentOS 5.2 была одна засада: anaconda в некоторых комбинациях %packages выдавала ошибку зависимостей и прерывала установку. Лечится добавлением --nobase и явным перечислением нужных пакетов. Не самое очевидное поведение, но после пары итераций разобрались.
Где лежат файлы и как это обслуживается
DHCP-сервер у нас уже был - ISC dhcpd. Добавили в конфиг блок class "pxeclients" с опциями next-server и filename для нужного диапазона адресов.
TFTP поднял tftpd-hpa на той же машине. В TFTP-корне - pxelinux.0 из пакета syslinux, ядра и initrd для Ubuntu 8.04 и CentOS 5.2, каталог pxelinux.cfg с конфигами загрузчика.
Preseed и kickstart отдаются простым Apache с directory listing - никакой магии, просто статические файлы. URL передаётся в параметрах ядра PXE.
Для разных профилей (веб-сервер, база данных, мониторинг) у нас сейчас три варианта preseed и два kickstart. Разница небольшая - размер томов да набор пакетов, - но заготовить их заранее проще, чем каждый раз редактировать.
Что получилось на практике
Двенадцать минут - это от момента первого DHCP-запроса до того, как puppet закончил первый прогон и машина отвечает по SSH. Цифра воспроизводимая: за последние три недели развернули новые VM, и время примерно одинаковое.
Ошибки бывают. Одна VM зависла на старте из-за того, что DHCP не успел выдать адрес, пока grub уже пытался загрузить ядро - проблема с таймингом в ESX, решилась увеличением boot delay. Одна VM получила kickstart с опечаткой в имени puppet master - установилась нормально, но puppet не запустился, пришлось заходить руками. Это уже вопрос к тому, как тестировать шаблоны перед тем, как считать их готовыми.
Для сопровождаемой инфраструктуры это меняет ритм работы: запрос на новый сервер перестаёт быть задачей на завтра. Пока не все профили покрыты шаблонами - Windows-машины разворачиваем пока вручную, там своя история с WDS и unattended.xml. Но Linux-часть парка - уже автоматически.
Шаблоны выложим в следующий раз - сначала хотим убедиться, что они стабильно работают на нескольких новых объектах.