Установка Cobbler под Debian 10

Предварительная подготовка

Возможны два варианта сетевой реализации:

  1. Сервер Cobbler, сервера, развертываемые через Cobbler и шлюз находятся в одной локальной сети (в одном vlan);
  2. Сервер Cobbler является шлюзом для серверов, развертываемых с помощью Cobbler.

Оба варианта равнозначны, но второй вариант позволяет иметь в сети для подчиненных серверов Cobbler независимые DNS и DHCP, не конфликтующие с остальной сетью. Данный вариант требует два сетевых интерфейсов либо физических, либо виртуальных для реализации VLAN.

Рассмотрим второй вариант.

Устанавливаем на сервер Cobbler операционную систему Debian 10 (Buster) любым удобным для вас способом. Настраиваем сеть в файле /etc/network/interfaces:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

allow-hotplug enp1s0
iface enp1s0 inet dhcp

auto enp2s0
iface enp2s0 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    dns-nameservers 192.168.1.2

Установка программного обеспечения

Установка выполняется командой:

apt-get install -y make gcc python3-dev python3-pip python3-future python3-distro python3-sphinx python3-coverage \
     python3-dnspython apache2 libapache2-mod-wsgi-py3 python3-netaddr python3-simplejson python3-yaml python3-cheetah \
     tftpd-hpa ipxe rsync syslinux isolinux pxelinux syslinux-efi syslinux-utils python3-django isc-dhcp-server debmirror \
     fence-agents xorriso bind9 bind9utils dnsutils ipmitool

По умолчанию TFTPD использует каталог /srv/tftp, а Cobbler - /var/lib/tftpboot.

С одной стороны можно перенастроить и первый, и второй сервис на любой каталог, но во избежание возможных проблем при обновлениях свяжем оба каталога симлинком:

mkdir -pv /srv/tftp
ln -s /srv/tftp /var/lib/tftpboot

Настройка DHCP-сервера

Установленный DHCP-сервер будет управлять непосредственно Cobbler’ом, но нам необходимо указать интерфейсы, которые он будет обслуживать в файле /etc/default/isc-dhcp-server:

INTERFACESv4="enp2s0"

Замените enp2s0 на используемый сетевой интерфейс. Затем проверьте работоспособность службы:

systemctl enable isc-dhcp-server
systemctl restart isc-dhcp-server

Установка и настройка Cobbler

Установка Cobbler

На момент написания статьи актуальной версией является 3.1.1. Устанавливаем командой:

wget https://github.com/cobbler/cobbler/archive/v3.1.1.tar.gz
tar -xf v3.1.1.tar.gz
cd cobbler-3.1.1
make install

Используемые каталоги

Библиотеки Python будут установлены в /usr/local/lib/python3.7/dist-packages/cobbler.

Код веб-кабинета: /usr/local/share/cobbler.

Исполняемые файлы будут размещены в /usr/local/bin.

Конфигурационные файлы: /etc/cobbler и /etc/apache2.

Для внутренних данных будет создан каталог /var/lib/cobbler.

Все файлы, к которым будет необходим доступ по http-протоколу: /var/www/cobbler и /var/www/cobbler_webui_content и для управления загрузкой серверов: /var/lib/tftpboot.

Настройка Cobbler

Настройка взаимодействия с Apache

Изначально Cobbler подразумевает доступ к панели управления по протоколу HTTPS. Для доступа по HTTP необходимо добавить в /etc/apache2/conf-available/cobbler_web.conf разрешение:

echo "
<Location /cobbler_web>
    Require all granted
</Location>
" >> /etc/apache2/conf-available/cobbler_web.conf

Корректируем права доступа для каталога данных панели управления:

chown www-data /var/lib/cobbler/webui_sessions

Включаем необходимые для работы модули и конфигурации Apache:

a2enmod ssl
a2enmod proxy
a2enmod rewrite
a2enmod proxy_http
a2enconf cobbler
a2enconf cobbler_web

В файле /etc/systemd/system/cobblerd.service меняем ExecStart=/usr/bin/cobblerd -F на ExecStart=/usr/local/bin/cobblerd -F.

Проверяем правильность настроек в файлах согласно используемым каталогам:

/etc/apache2/conf-enabled/cobbler.conf
/etc/apache2/conf-enabled/cobbler_web.conf

Создаем папку /var/www/cobbler/pub, в этой папке создаем симлинки:

- images -> /var/www/cobbler/images
- pxelinux.cfg -> /srv/tftp/pxelinux.cfg

Перезапускаем Apache в новой конфигурации:

systemctl restart apache2

Настройка конфигурации Cobbler

Копируем файл службы Cobbler в служебный каталог systemd, корректируем его и разрешаем автоматический запуск:

cp -f /etc/cobbler/cobblerd.service /etc/systemd/system/
sed -i 's/httpd.service/apache2.service/g' /etc/systemd/system/cobblerd.service
systemctl enable cobblerd

Для кооректной работы Django корректируем некоторые параметры в коде Cobbler:

SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
sed -i "s/SECRET_KEY =.*/SECRET_KEY = '$SECRET_KEY'/" /usr/local/share/cobbler/web/settings.py
sed -i "s/TIME_ZONE =.*/SECRET_KEY = 'Europe\/Moscow'/" /usr/local/share/cobbler/web/settings.py
sed -i "s/\/usr\/share\/cobbler\/web\/templates/\/usr\/local\/share\/cobbler\/web\/templates/" /usr/local/share/cobbler/web/settings.py

В файле настроек Cobbler /etc/cobbler/settings необходимо скорректировать некоторые значения согласно настройкам самого сервера.

IP-адрес сервера Cobbler:

server: 192.168.1.1

IP-адрес сервера TFTPD:

next_server: 192.168.1.1

Разрешаем Cobbler управлять DHCP и DNS:

manage_dhcp: 1
manage_dns: 1

Разрешаем управление загрузкой через TFTPD:

pxe_just_once: 1

Создаем список прямых и обратных зон DNS:

manage_forward_zones: [test.loc]
manage_reverse_zones: [192.168.1]

Проверяем корректность указания каталога для TFTP-загрузки серверов:

tftpboot_location: /var/lib/tftpboot

Создаем пароль для root вновь устанавливаемых серверов, для этого используем ранее сформированную случайную строку:

PASSWORD=’password_for_root’
CRYPTED_PASSWORD=$(openssl passwd -1 -salt $SECRET_KEY $PASSWORD)
sed -i "s/^default_password_crypted:.*/default_password_crypted: $CRYPTED_PASSWORD/" /etc/cobbler/settings

Настройка взаимодействия с DNS-сервером bind9

Корректируем шаблон /etc/cobbler/named.template для DNS-сервера, а именно прописываем IP-адрес(а) DNS сервера и сети, которые будет обслуживать данный сервер. Также корректируем каталоги согласно размещаемой операционной системе:

options {
      listen-on port 53 { 127.0.0.1; 192.168.1.1; };
      directory       "/etc/bind";
      dump-file       "/etc/bind/cache_dump.db";
      statistics-file "/etc/bind/named_stats.txt";
      memstatistics-file "/etc/bind/named_mem_stats.txt";
      allow-query     { localhost; 192.168.0.0/16; 172.16.0.0/12; 10.0.0.0/8; };
      recursion yes;
      max-cache-size 256M;
      max-acache-size 256M;
};

logging {
    channel default_debug {
            file "/var/cache/bind/named.run";
            severity dynamic;
    };
};

#for $zone in $forward_zones
    zone "${zone}." {
    type master;
    file "$zone";
};

#end for
#for $zone, $arpa in $reverse_zones
zone "${arpa}." {
   type master;
   file "$zone";
};

#end for

Важно

Все что ниже секции logging не меняем!

Корректируем права на каталог для /etc/bind. Данный пункт необходим в случае использования динамических зон:

chown bind:bind /etc/bind

В случае использования динамических зон необходимо активировать модуль Cobbler для работы с nsupdate в файле:

/etc/cobbler/settings.d/nsupdate.settings

nsupdate_enabled: 1

Создаем ключ для обновления DNS:

dnssec-keygen -a HMAC-SHA512 -b 512 -n USER cobbler_update_key

Прописываем данный ключ в /etc/cobbler/settings.d/nsupdate.settings:

nsupdate_tsig_algorithm: "hmac-sha512"
nsupdate_tsig_key: [ "cobbler_update_key.", "hvnK54HFJXFasHjzjEn09ASIkCOGYSnofRq4ejsiBHz3udVyGiuebFGAswSjKUxNuhmllPrkI0HRSSmM2qvZug==" ]

А также добавить после секции logging в шаблоне /etc/cobbler/named.template:

key cobbler_update_key {
    algorithm hmac-sha512;
    secret "hvnK54HFJXFasHjzjEn09ASIkCOGYSnofRq4ejsiBHz3udVyGiuebFGAswSjKUxNuhmllPrkI0HRSSmM2qvZug==";
};

Настройка взаимодействия с DHCP-сервером

Корректируем шаблон DHCP-сервера /etc/cobbler/dhcp.template.

Для каждой используемой сети необходимо прописать секцию:

subnet 192.168.1.0 netmask 255.255.255.0 {
    option routers             192.168.1.1;
    option domain-name-servers 192.168.1.1;
    option subnet-mask         255.255.255.0;
    range dynamic-bootp        192.168.1.100 192.168.1.254;
    default-lease-time         21600;
    max-lease-time             43200;
    next-server                $next_server;
    class "pxeclients" {
         match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";

         # Legacy
         if option system-arch = 00:00 {
             filename "pxelinux.0";
         }
         # UEFI-32-1
         if option system-arch = 00:06 {
              # Not supported, no 32 bit UEFI grub executable
             filename "unsupported";
         }
         # UEFI-32-2
         if option system-arch = 00:02 {
             # Not supported, no 32 bit UEFI grub executable
             filename "unsupported";
         }
         # UEFI-64-1
         else if option system-arch = 00:07 {
             filename "grub/grubx64.efi";
         }
         # UEFI-64-2
         else if option system-arch = 00:08 {
             filename "grub/grubx64.efi";
         }
         # UEFI-64-3
         else if option system-arch = 00:09 {
             filename "grub/grubx64.efi";
         }
         # armv7   (aka arm 32 bit)
         else if option system-arch = 00:0a {
             filename "grub/armv7.efi";
         }
         # aarch64 (aka arm 64 bit)
         else if option system-arch = 00:0b {
             filename "grub/grubaa64.efi";
         }
         # RiskV 32 bit
         else if option system-arch = 00:25 {
             #ToDo petitboot loader
             filename "unsupported";
         }
         #RiskV 32 bit
         else if option system-arch = 00:27 {
             #ToDo petitboot loader
             filename "unsupported";
         }
         else if option system-arch = 00:0e {
             filename "grub/grub.ppc64le";
         }
         else
         {
             filename "pxelinux.0";
         }
        }
}

Таким образом, прописываем шаблон сети, адреса роутеров и сервера загрузки, а также указываем загружаемый клиент pxelinux.0. В остальных файлах изменения производить не надо!

Первый запуск и проверка конфигурации Cobbler

После внесения всех изменений запускаем службу cobblerd:

systemctl start cobblerd

Загружаем загрузчики:

cobbler get-loaders

Проводим проверку:

cobbler check

Выполняем все рекомендации, предлагаемые проверкой конфигурации.

Проводим синхронизацию:

cobbler sync

Настройка Cobbler завершена.

Импорт дистрибутива Debian 10

Загружаем дистрибутив для сетевой установки:

wget -q -O /tmp/debian-10.2.0-amd64-netinst.iso https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso

Монтируем дистрибутив в локальный каталог:

mkdir -pv /mnt/debian
mount /tmp/debian-10.2.0-amd64-netinst.iso /mnt/debian

Импортируем дистрибутив:

cobbler import --name=debian-10.2.0-amd64 --arch=x86_64 --path=/mnt/debian
umount /mnt/debian

Сам дистрибутив никакого ПО не содержит - он содержит только ядро Linux и окружение для инсталлятора трех конфигураций:

cobbler distro list
   debian-10.2.0-gtk-x86_64
   debian-10.2.0-x86_64
   debian-10.2.0-xen-x86_64

Удаляем “лишние” для нас конфигурации:

cobbler profile remove --name=debian-10.2.0-gtk-x86_64
cobbler profile remove --name=debian-10.2.0-xen-x86_64
cobbler distro remove --name=debian-10.2.0-gtk-x86_64
cobbler distro remove --name=debian-10.2.0-xen-x86_64

Но это еще не все, загрузчик с диска предназначен для использования cdrom и не поднимает сетевой интерфейс в начале установки, поэтому установить с его помощью дистрибутив на сервер не удасться - инсталлятор будет требовать установку cd-диска. Для исправления ситуации качаем инсталлятор для сетевой установки и заменяем файлы инсталлятора в каталогах Cobbler:

mkdir -pv /tmp/netboot
wget -q -O /tmp/netboot/netboot.tar.gz https://mirror.yandex.ru/debian/dists/buster/main/installer-amd64/current/images/netboot/netboot.tar.gz
cd /tmp/netboot
tar -xf /tmp/netboot/netboot.tar.gz

cp -fv /tmp/netboot/debian-installer/amd64/linux /var/www/cobbler/distro_mirror/debian-10.2.0-amd64-x86_64/install.amd
cp -fv /tmp/netboot/debian-installer/amd64/initrd.gz /var/www/cobbler/distro_mirror/debian-10.2.0-amd64-x86_64/install.amd

Проводим синхронизацию:

cobbler sync

Сразу дистрибутив из архива netboot.tar.gz не устанавливали, так как Cobbler при импорте дистрибутива проверяет сигнатуру дистрибутива и ставит только известные ему, поэтому изначально нам нужен оригинальный iso-образ.

Создание файла ответов для установки Debian

После импорта дистрибутива мы имеем инсталлятор, способный обратиться к любому зеркалу Debian для установки нужной конфигурации. Осталось создать файл ответов для установки дистрибутива в неинтерактивном режиме.

Нижеприведенный файл ответов был создан на базе /var/lib/cobbler/templates/sample.seed и сохранен как /var/lib/cobbler/templates/debian_buster.seed:

# Mostly based on the Ubuntu installation guide
# https://help.ubuntu.com/18.04/installation-guide/
# Debian sample
# https://www.debian.org/releases/stable/example-preseed.txt

# Preseeding only locale sets language, country and locale.
d-i debian-installer/locale string ru_RU

# Keyboard selection.
# Disable automatic (interactive) keymap detection.
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us
d-i keyboard-configuration/toggle select No toggling
d-i keyboard-configuration/layoutcode string us
d-i keyboard-configuration/variantcode string

# netcfg will choose an interface that has link if possible. This makes it
# skip displaying a list if there is more than one interface.
set $myhostname = $getVar('hostname',$getVar('name','cobbler')).replace("_","-")
d-i netcfg/choose_interface select auto
#d-i netcfg/choose_interface select eth0
#d-i netcfg/dhcp_timeout string 60
#d-i netcfg/dhcpv6_timeout string 60
d-i netcfg/get_hostname string $myhostname

# If non-free firmware is needed for the network or other hardware, you can
# configure the installer to always try to load it, without prompting. Or
# change to false to disable asking.
# d-i hw-detect/load_firmware boolean true

# NTP/Time Setup
d-i time/zone string Europe/Moscow
d-i clock-setup/utc boolean false
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server  string ntp.ubuntu.com

# Setup the installation source
d-i mirror/country string manual
d-i mirror/http/hostname string http.mirror.yandex.ru
d-i mirror/http/directory string /debian
#d-i mirror/http/hostname string $http_server
#d-i mirror/http/directory string $install_source_directory
d-i mirror/http/proxy string

#set $os_v = $getVar('os_version','')
#if $breed == "ubuntu" and $os_v and $os_v.lower() != 'precise'
# Required at least for ubuntu 12.10+ , so test os_v is not precise. Olders versions are not supported anymore
d-i live-installer/net-image string http://$http_server/cobbler/links/$distro_name/install/filesystem.squashfs
#end if

# Suite to install.
d-i mirror/suite string buster
d-i mirror/udeb/suite string buster
# d-i mirror/suite string precise
# d-i mirror/udeb/suite string precise

# Components to use for loading installer components (optional).
#d-i mirror/udeb/components multiselect main, restricted

# Disk Partitioning
# Use LVM, and wipe out anything that already exists
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman-auto/method string lvm
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-partitioning/confirm_write_new_label boolean true

# You can choose one of the three predefined partitioning recipes:
# - atomic: all files in one partition
# - home:   separate /home partition
# - multi:  separate /home, /usr, /var, and /tmp partitions
d-i partman-auto/choose_recipe select atomic

# If you just want to change the default filesystem from ext3 to something
# else, you can do that without providing a full recipe.
# d-i partman/default_filesystem string ext4

# root account and password
d-i passwd/root-login boolean true
d-i passwd/root-password-crypted password $default_password_crypted

# skip creation of a normal user account.
d-i passwd/make-user boolean false

# You can choose to install restricted and universe software, or to install
# software from the backports repository.
d-i apt-setup/restricted boolean true
d-i apt-setup/universe boolean true
d-i apt-setup/backports boolean true

# Uncomment this if you don't want to use a network mirror.
# d-i apt-setup/use_mirror boolean false

# Select which update services to use; define the mirrors to be used.
# Values shown below are the normal defaults.
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string security.debian.org
d-i apt-setup/security_path string /debian

$SNIPPET('preseed_apt_repo_config')

# Enable deb-src lines
# d-i apt-setup/local0/source boolean true

# URL to the public key of the local repository; you must provide a key or
# apt will complain about the unauthenticated repository and so the
# sources.list line will be left commented out
# d-i apt-setup/local0/key string http://local.server/key

# By default the installer requires that repositories be authenticated
# using a known gpg key. This setting can be used to disable that
# authentication. Warning: Insecure, not recommended.
# d-i debian-installer/allow_unauthenticated boolean true

# Package selection
# Default for minimal
tasksel tasksel/first multiselect standard
# Default for server
# tasksel tasksel/first multiselect standard, web-server
# Default for gnome-desktop
# tasksel tasksel/first multiselect standard, gnome-desktop

# Individual additional packages to install
# wget is REQUIRED otherwise quite a few things won't work
# later in the build (like late-command scripts)
d-i pkgsel/include string ntp ssh wget

# Debian needs this for the installer to avoid any question for grub
# Please verify that it suit your needs as it may overwrite any usb stick
#if $breed == "debian"
d-i grub-installer/grub2_instead_of_grub_legacy boolean true
d-i grub-installer/bootdev string default
#end if

# Use the following option to add additional boot parameters for the
# installed system (if supported by the bootloader installer).
# Note: options passed to the installer will be added automatically.
d-i debian-installer/add-kernel-opts string $kernel_options_post

# Avoid that last message about the install being complete.
d-i finish-install/reboot_in_progress note

## Figure out if we're automating OS installation for a system or a profile
#if $getVar('system_name','') != ''
#set $what = "system"
#else
#set $what = "profile"
#end if

# This first command is run as early as possible, just after preseeding is read.
# d-i preseed/early_command string [command]
d-i preseed/early_command string wget -O- \
   http://$http_server/cblr/svc/op/script/$what/$name/?script=preseed_early_default | \
   /bin/sh -s

# This command is run immediately before the partitioner starts. It may be
# useful to apply dynamic partitioner preseeding that depends on the state
# of the disks (which may not be visible when preseed/early_command runs).
# d-i partman/early_command \
#       string debconf-set partman-auto/disk "\$(list-devices disk | head -n1)"

# This command is run just before the install finishes, but when there is
# still a usable /target directory. You can chroot to /target and use it
# directly, or use the apt-install and in-target commands to easily install
# packages and run commands in the target system.
# d-i preseed/late_command string [command]
d-i preseed/late_command string wget -O- \
   http://$http_server/cblr/svc/op/script/$what/$name/?script=preseed_late_default | \
   chroot /target /bin/sh -s; wget -O- \
   http://$http_server/cblr/svc/op/nopxe/$what/$name

В качестве зеркала используется mirror.yandex.ru. Данный вариант можно использовать для тестов или при наличии широкого и незагруженного канала в Интернет. В противном случае стоит воспользоваться утилитой ftpmirror, которую можно найти по ссылкe, позволяющей создать собственное зеркало.

Также вышеприведенная конфигурация использует при разбиении весь диск целиком. Для пользовательского разбиения можно воспользоваться примером:

d-i partman-auto/expert_recipe string                        \
     boot-root ::                                            \
             30000 5000 40000 ext4                           \
                     $primary{ } $bootable{ }                \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext4 }    \
                     mountpoint{ / }                         \
             .                                               \
             20000 3000 40000 ext3                           \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext3 }    \
                     mountpoint{ /srv }                      \
             .                                               \
             10000 2000 10000000 ext4                        \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext4 }    \
                     mountpoint{ /home }                     \
             .                                               \
             50% 6000 200% linux-swap                        \
                     method{ swap } format{ }                \
             .

Обратите внимание, что в конце установки дистрибутива в файле ответов указан вызов скрипта:

wget -O- http://$http_server/cblr/svc/op/nopxe/$what/$name

Это позволяет сбросить флаг сетевой загрузки для устанавливаемого сервера и после перезагрузки сервер стартует с уже установленного дистрибутива.

Заключение

Дальнейшая работа с Cobbler предполагает создание систем (system) с указанием для каждого физического или виртуального сервера MAC-адреса, профайла дистрибутива, сетевых интерфейсов, а также имен и ip-адресов.