Установка Cobbler под Ubuntu 22.04

Подготовка к установке

Переменные, используемые для инсталяции тестового стенда

  1. Адрес cobbler сервера, с dhcp и tftp серверами:

    SERVER_IP='10.102.9.145'
    
  2. Данные сервера, который будет устанавливаться:

    # MAC адрес сетевого интерфейса:

    VM_MAC='52:54:00:41:88:12'
    
  3. Адрес, присваемый серверу:

    VM_IP_ADDR='10.102.9.111'
    
  4. Название сервера в cobbler:

    VM_NAME='cob02'
    
  5. Хостнейм, который будет присвоен серверу после установки:

    VM_HOSTNAME='cob02'
    
  6. Имя пользователя и пароль, созданные после установки сервера:

    VM_USERNAME='accentos'
    VM_PASSWORD='$6$PhhNQG5Xq0nRZH/T$9kxoeWAXOyU//QZiv9ODOdV4JfDt6ImC07wUnh.k395.jM2rRVvgU5./AW8DEYA4YCpZHwkMUyPUPs2RBAHYl0'
    

    Пароль можно сгенерировать, выполнив комманду:

    mkpasswd --method=sha-512 password
    

Подключение репозитория и установка необходимого ПО

Предварительно установим grub-pc-bin для корректной сборки загрузчика grub (grub.0 в частности):

apt -y install grub-pc-bin

Подключим репозиторий и установим дополнительные пакеты:

echo "Add apt repos"
cat > /etc/apt/sources.list << EOF
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy main restricted
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates main restricted
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy universe
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates universe
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy multiverse
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates multiverse
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-backports main restricted universe multiverse
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security main restricted
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security universe
deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security multiverse
EOF

apt -y remove bind9-utils bind9-libs
apt -y autoremove
apt -y install mc isc-dhcp-server bind9 shim shim-signed ipxe grub2-common ipxe pxelinux grub-ipxe grub-efi-amd64 syslinux-efi syslinux apache2 gunicorn tftpd-hpa debmirror

Установим дополнительные пакеты и библиотеки для корректной работы cobbler:

apt -y install \
    fence-agents \
    rsync \
    xorriso \
    python3
    python3-cheetah \
    python3-distro \
    python3-dnspython \
    python3-gunicorn \
    python3-ldap \
    python3-netaddr
    python3-pymongo \
    python3-requests \
    python3-schema \
    python3-yaml
ln -s /usr/bin/grub-mkimage /usr/bin/grub2-mkimage

ln -s /usr/sbin/dhcpd /usr/sbin/isc-dhcp-server

mkdir /var/www/cobbler

Для корректной работы cobbler под ubuntu и совместимостью с cobbler делаем симлики:

ln -s /usr/bin/grub-mkimage /usr/bin/grub2-mkimage

ln -s /usr/sbin/dhcpd /usr/sbin/isc-dhcp-server

mkdir /var/www/cobbler

Установка cobbler

Сохраняем крайнюю версию cobbler. На момент установки использовалась версия:

Cobbler 3.4.0
  source: 67d05ce5, Tue Sep 19 13:09:43 2023 +0200
  build time: Wed Sep 21 07:30:00 2022::

git clone https://github.com/cobbler/cobbler
cd cobbler
make install

Настройка cobbler

Настройка файлов конфигурации cobbler

Далее следует произвести настройку параметров в файле конфигурации /etc/cobbler/settings.yaml:

sed -i 's/manage_dhcp: false/manage_dhcp: true/g' /etc/cobbler/settings.yaml
sed -i 's/manage_dhcp_v4: false/manage_dhcp_v4: true/g' /etc/cobbler/settings.yaml
sed -i 's/manage_dhcp_v6: false/manage_dhcp_v6: false/g' /etc/cobbler/settings.yaml
sed -i "s/next_server_v4: 127.0.0.1/next_server_v4: ${SERVER_IP}/g" /etc/cobbler/settings.yaml

sed -i "s/server: 127.0.0.1/server: ${SERVER_IP}/g" /etc/cobbler/settings.yaml
sed -i "s/convert_server_to_ip: false/convert_server_to_ip: true/g" /etc/cobbler/settings.yaml
sed -i "s/restart_dns: true/restart_dns: false/g" /etc/cobbler/settings.yaml

sed -i "s/next_server_v6: \"::1\"/next_server_v6: '1.1.1.1'/g" /etc/cobbler/settings.yaml

Настройка шаблона dhcp сервера

Замените содержимое файла /etc/cobbler/dhcp.template:

# ******************************************************************
# Cobbler managed dhcpd.conf file
#
# generated from cobbler dhcp.conf template ($date)
# Do NOT make changes to /etc/dhcpd.conf. Instead, make your changes
# in /etc/cobbler/dhcp.template, as /etc/dhcpd.conf will be
# overwritten.
#
# ******************************************************************

ddns-update-style interim;

allow booting;
allow bootp;

ignore client-updates;
set vendorclass = option vendor-class-identifier;

option system-arch code 93 = unsigned integer 16;

subnet 10.102.9.0 netmask 255.255.255.0 {
     option routers             10.102.9.254;
     option domain-name-servers 10.102.9.144;
     option subnet-mask         255.255.255.0;
     range dynamic-bootp        10.102.9.150 10.102.9.249;
     default-lease-time         21600;
     max-lease-time             43200;
     next-server                $next_server_v4;
     class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";

          # Legacy
          if option system-arch = 00:00 {
              filename "grub/grub.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
              # petitboot should support pxelinux config files
              filename "unsupported";
          }
          #RiskV 32 bit
          else if option system-arch = 00:27 {
              #ToDo petitboot loader
              # petitboot should support pxelinux config files
              filename "unsupported";
          }
          else if option system-arch = 00:0e {
              # FIXME add petitboot support for ppc64(le)
              filename "grub/grub.ppc64le";
          }
          else
          {
              filename "grub/grub.0";
          }
     }
}
#for dhcp_tag in $dhcp_tags.keys():
    ## group could be subnet if your dhcp tags line up with your subnets
    ## or really any valid dhcpd.conf construct ... if you only use the
    ## default dhcp tag in cobbler, the group block can be deleted for a
    ## flat configuration
# group for Cobbler DHCP tag: $dhcp_tag
group {
    #for mac in $dhcp_tags[$dhcp_tag].keys():
        #set iface = $dhcp_tags[$dhcp_tag][$mac]
    host $iface.name {
        #if $iface.interface_type == "infiniband":
            option dhcp-client-identifier = $mac;
        #else
            hardware ethernet $mac;
        #end if
        #if $iface.ip_address:
            fixed-address $iface.ip_address;
        #end if
        #if $iface.dns_name:
           option host-name "$iface.dns_name";
        #else if $iface.hostname:
            option host-name "$iface.hostname";
        #end if
        #if $iface.netmask:
            option subnet-mask $iface.netmask;
        #end if
        #if $iface.if_gateway:
            option routers $iface.if_gateway;
        #else if $iface.gateway:
            option routers $iface.gateway;
        #end if
        #set breed = $getVar('iface.distro.breed',None)
        #if $breed == "vmware":
            #if $iface.enable_ipxe:
            if option system-arch = 00:07 or option system-arch = 00:09 { ## UEFI
                if exists user-class and option user-class = "iPXE" {
                    filename = "$iface.filename_esxi";
                } else {
                    filename = "esxi/snponly.efi";
                }
            } else { ## BIOS
                if exists user-class and option user-class = "iPXE" {
                    filename = "esxi/pxelinux.0";
                } else {
                    filename = "esxi/undionly.pxe";
               }
            }
            #else
            if option system-arch = 00:07 or option system-arch = 00:09 {
                filename = "$iface.filename_esxi";
            } else {
                filename = "esxi/pxelinux.0";
            }
            #end if
        #else if $iface.enable_ipxe:
            if exists user-class and option user-class = "iPXE" {
                filename "http://$cobbler_server/cblr/svc/op/ipxe/system/$iface.owner";
            } else {
                filename "undionly.pxe";
            }
        #end if
        #if $iface.next_server_v4:
            next-server $iface.next_server_v4;
        #end if
        #if $iface.filename:
            filename "$iface.filename";
         #end if
        #if $iface.name_servers:
            #set $mynameservers = ','.join($iface.name_servers)
            option domain-name-servers $mynameservers;
        #end if
    }
    #end for
}
#end for

Создание служб cobbler и cobbler-gunicorn

К сожалению, инсталятор cobbler не создает службы сам. Поэтому добавим их вручную.

Необходимо в каталоге /etc/systemd/system/ создать следующие службы:

/etc/systemd/system/cobblerd.service:

[Unit]
Description=Cobbler Helper Daemon
After=syslog.target network.target
Wants=apache2.service

[Service]
ExecStart=/usr/local/bin/cobblerd -F
PrivateTmp=yes
KillMode=process

[Install]
WantedBy=multi-user.target
 /etc/systemd/system/cobblerd-gunicorn.service

[Unit]
Description=Cobbler Gunicorn Daemon
After=syslog.target network.target
Wants=cobblerd.service

[Service]
ExecStart=/usr/bin/gunicorn cobbler.services:application
PrivateTmp=yes
KillMode=process

[Install]
WantedBy=multi-user.target

Перечитаем и запустим cobbler:

systemctl daemon-reload
systemctl enable cobblerd
systemctl enable cobblerd-gunicorn
systemctl start cobblerd
systemctl start cobblerd-gunicorn

Подключаем cobbler API

Для корректной работы api и доступа к статическим файлам включим необходимые модули в apache2:

a2enconf cobbler
a2enmod proxy
a2enmod proxy_http
a2enmod rewrite
systemctl reload apache2

Создание загрузчика grub

Выполнить комманду:

cobbler mkloaders

Создание каталога для ISO образов

Необходимо место для хранения iso образов с организацией доступности по протоколу http.

Создаем каталоги для метаданных и образов:

mkdir -p /var/www/iso
mkdir -p /var/www/meta

Добавим каталоги для организации доступа к образам и к метаданным по http в файл конфигурации apache:

if ! grep -q '    Alias /isos /var/www/iso' /etc/apache2/conf-available/cobbler.conf; then
    sed -i '6i\    Alias /isos /var/www/iso' /etc/apache2/conf-available/cobbler.conf
fi

if ! grep -q '    Alias /metas /var/www/meta' /etc/apache2/conf-available/cobbler.conf; then
    sed -i '7i\    Alias /metas /var/www/meta' /etc/apache2/conf-available/cobbler.conf
fi

systemctl restart apache2

Загрузим образ ubuntu 22.04.2 LTS:

wget -q -O /var/www/iso/ubuntu-22.04.2-live-server-amd64.iso http://repostand.accentos.ru/os-iso/ubuntu/ubuntu-22.04.2-live-server-amd64.iso

Импорт образа и настройка

Для импорта образа следует выполнить на сервере Cobbler:

mkdir -p /mnt/ubuntu
mount -o loop /var/www/iso/ubuntu-22.04.2-live-server-amd64.iso  /mnt/ubuntu
cobbler import --name=ubuntu-22.04.2-x86_64 --arch=x86_64 --path=/mnt/ubuntu --breed=ubuntu --os-version=jammy
umount /mnt/ubuntu

Добавим опции для ядра:

cobbler distro edit --name=ubuntu-22.04.2-casper-x86_64 --kernel-options='root=/dev/ram0 ramdisk_size=2500000 ip=dhcp cloud-config-url=/dev/null url=http://${SEVER_IP}/isos/ubuntu-22.04.2-live-server-amd64.iso ds="nocloud-net;s=http://${SERVER_IP}/cblr/svc/op/autoinstall/system/cob02/"'

где http://${SERVER_IP}/cblr/svc/op/autoinstall/system/cob02/ - путь к каталогу с метаданными.

Важно

Учтите, что данные опции работать корректно не будут, и придется править файл с опциями grub руками. Либо править код cobbler для корректной установки через autoinstall для ubuntu выше 20.04. Однако нужны для корректного формирования grub menu.

Опции ядра для запуска виртуальных машин /srv/tftp/grub/system/52:54:00:41:88:12:

set system="cob02"
set timeout=1
set default='cob02'
menuentry 'cob02' --class gnu-linux --class gnu --class os {
  echo 'Loading kernel ...'
  clinux /images/ubuntu-22.04.2-casper-x86_64/vmlinuz  root=/dev/ram0 ramdisk_size=2500000 ip=dhcp cloud-config-url=/dev/null url=http://${SEVER_IP}/isos/ubuntu-22.04.2-live-server-amd64.iso autoinstall "ds=nocloud-net;s=http://${SEVER_IP}/metas/cob02/"
  echo 'Loading initial ramdisk ...'
  cinitrd /images/ubuntu-22.04.2-casper-x86_64/initrd
  echo '...done'
}

Добавляем устанавливаемый хост в систему

Выполнить:

cobbler system add \
    --name=${VM_NAME} \
    --profile=ubuntu-22.04.2-casper-x86_64 \
    --mac=${VM_MAC} \
    --hostname=${VM_HOSTNAME} \
    --ip-address=${VM_IP_ADDR} \
    --kernel-options='root=/dev/ram0 ramdisk_size=2500000 ip=dhcp cloud-config-url=/dev/null url=http://${SERVER_IP}/isos/ubuntu-22.04.2-live-server-amd64.iso ds="nocloud-net;s=http://${SERVER_IP}/metas/cob02/"'

Метаданные для ubuntu22.04

Метаданные для деплоя тестового сервера под Ubuntu22.04 в файле /var/www/html/meta/cob02/user-data:

#cloud-config
autoinstall:
  identity:
    hostname: jammy-server
    password: $6$PhhNQG5Xq0nRZH/T$9kxoeWAXOyU//QZiv9ODOdV4JfDt6ImC07wUnh.k395.jM2rRVvgU5./AW8DEYA4YCpZHwkMUyPUPs2RBAHYl0
    realname: Ubuntu user
    username: ubuntu
  apt:
    preserve_sources_list: false
    sources_list: |
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-backports main restricted universe multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security multiverse
  storage:
    layout:
        name: lvm
  late-commands:
  - 'echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /target/etc/sudoers.d/ubuntu-nopw'
  - chmod 440 /target/etc/sudoers.d/ubuntu-nopw
  version: 1

Для отключения дальнейшей сетевой загрузки и повторной переустановки сервера следует в конце перед version: 1 добавить еще две строки:

- wget "http://${SERVER_IP}/cblr/svc/op/nopxe/system/${VM_NAME}" -O /dev/null
- wget "http://${SERVER_IP}/cblr/svc/op/trig/mode/post/system/${VM_NAME}" -O /dev/null

Примечание

Не работает в текущей версии! После вызова хост продолжает сетевую установку и переустановку.

Пароль для пользователя ubuntu можно сгенерировать командой:

mkpasswd --method=sha-512 ubuntu

Содержимое файла /var/www/html/meta/cob02/meta-data:

instance-id: jammy-autoinstall

Файл /var/www/html/meta/cob02/vendor-data пустой.

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

cat > /srv/tftp/grub/system/${VM_MAC} << EOF
set system="${VM_NAME}"
set timeout=1
set default='${VM_NAME}'
menuentry '${VM_NAME}' --class gnu-linux --class gnu --class os {
echo 'Loading kernel ...'
clinux /images/ubuntu-22.04.2-casper-x86_64/vmlinuz  root=/dev/ram0 ramdisk_size=2500000 ip=dhcp cloud-config-url=/dev/null url=http://${SERVER_IP}/isos/ubuntu-22.04.2-live-server-amd64.iso autoins
tall "ds=nocloud-net;s=http://${SERVER_IP}/metas/${VM_NAME}/"
echo 'Loading initial ramdisk ...'
cinitrd /images/ubuntu-22.04.2-casper-x86_64/initrd
echo '...done'
}
EOF

MPATH="/var/www/meta/${VM_NAME}"
mkdir -p ${MPATH}
touch ${MPATH}/vendor-data

cat > ${MPATH}/meta-data << EOF
instance-id: jammy-autoinstall
EOF

cat > ${MPATH}/user-data << EOF
#cloud-config
autoinstall:
  identity:
    hostname: ${VM_HOSTNAME}
    password: ${VM_PASSWORD}
    realname: ${VM_USERNAME}
    username: ${VM_USERNAME}
  apt:
    preserve_sources_list: false
    sources_list: |
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-updates multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-backports main restricted universe multiverse
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security main restricted
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security universe
      deb http://repostand.accentos.ru:8081/repository/apt-ubuntu2204/ jammy-security multiverse
  storage:
    layout:
        name: lvm
  late-commands:
  - 'echo "${VM_USERNAME} ALL=(ALL) NOPASSWD:ALL" > /target/etc/sudoers.d/${VM_USERNAME}-nopw'
  - chmod 440 /target/etc/sudoers.d/${VM_USERNAME}-nopw
  - wget -O- http://${SERVER_IP}/cblr/svc/op/nopxe/system/${VM_NAME}
  version: 1
EOF

Дополнительная информация

Работа через ansible

Данная информация приведена для справки. В реальной работе без модификации кода cobbler не применим. Позволяет добавлять хосты в систему через ansible playbook. Повторное добавление хоста через нижеприведенный таск приведет к ошибке в случае, если хост уже существует в системе.

username и password - реквизиты доступа к cobbler api. Приведены справочно, в вашей инсталации они будут другие:

- name: Query all systems in Cobbler
  community.general.cobbler_system:
    host: "10.102.9.144"
    username: "cobbler"
    password: "cobbler"
    state: query
    use_ssl: false
  register: cobbler_systems
  delegate_to: localhost


- name: Ensure the system exists in Cobbler
  community.general.cobbler_system:
    host: "10.102.9.144"
    username: "cobbler"
    password: "cobbler"
    use_ssl: false
    name: cob02
    properties:
      profile: ubuntu-22.04.2-casper-x86_64
      #profile: CentOS7-x86_64
      name_servers: [ 10.102.9.100 ]
      name_servers_search: test.loc
      netboot_enabled: true
      power_type: ipmilan
      power_address: "10.102.9.10"
      power_user: "admin"
      power_pass: "password"
    interfaces:
       eth0:
        macaddress: 52:54:00:41:88:12
        ipaddress: 10.102.9.111
  delegate_to: localhost

Проблема с работой через ipmi

Установленно, что cobbler не может корректно выполнять задачи по impi (через прослойку fence_) в случае, если хост управляется через vbmc.

При том, что impitools может корректно работать с хостом:

sudo ipmitool -I lanplus -U adMin -P paSSword -H 10.102.9.10 -p 6270 power status
Chassis Power is on

Скрипты для разворачивания стенда

Ссылка для скачивания скриптов.