Поиск по сайту:

Как написать и выполнить автоматическую установку Ubuntu с помощью автоустановки


Возможность предоставлять и создавать реплицируемые установки операционной системы имеет решающее значение, особенно в корпоративных средах. Для выполнения автоматической установки Ubuntu использовала поддержку файлов Debian Preseed и Kickstart. Начиная с сервера Ubuntu 20.04 и версии 23.04 рабочего стола Ubuntu, эти методы установки устарели, и в дистрибутиве принят новый формат автоматической установки, который использует преимущества Cloud-init.

В этом уроке мы узнаем, как написать файл автоустановки Ubuntu и как использовать его для выполнения автоматической, воспроизводимой установки.

В этом уроке вы узнаете:

  • Как написать файл автоустановки и определить установку Ubuntu во всех ее аспектах
  • Как передать файл автоустановки установщикам рабочего стола и сервера Ubuntu

Представляем файл автоустановки

Будучи производным дистрибутивом Debian, Ubuntu изначально поддерживала файлы предварительной настройки как метод выполнения автоматической и воспроизводимой установки. Позже в качестве уровня совместимости была добавлена поддержка синтаксиса установки Kickstart, но не все команды Kickstart были реализованы. Начиная с сервера Ubuntu 20.04 и начиная с настольной версии Ubuntu 23.04, Ubuntu использует собственный метод автоматической установки, основанный на синтаксисе YAML: автоматическая установка.

Первое, что мы обычно видим в файлах автоустановки, — это комментарий «#cloud-config»: он необходим, если мы хотим, чтобы файл обрабатывался Cloud-init (подробнее об этом позже). Основной ключ, используемый в файле конфигурации, — autoinstall; вместо этого версия синтаксиса файла указывается с помощью ключа version. На момент написания доступна только версия 1:

#cloud-config
autoinstall:
  version: 1

Выбор источника

Чтобы указать «среду», которую мы хотим установить, мы можем использовать ключ source, который принимает в качестве значения сопоставление. Внутри этого сопоставления мы передаем имя среды, которую хотим установить, в качестве значения ключа id. Например, при установке рабочего стола Ubuntu мы можем выбирать между ubuntu-minimal-desktop и полноценным ubuntu-desktop. Если ключ опущен, используется первый доступный источник:

#cloud-config
autoinstall:
  source:
    id: ubuntu-desktop-minimal

Настройка языкового стандарта системы, часового пояса и раскладки клавиатуры

Чтобы установить языковой стандарт системы, мы используем ключ locale. Вместо этого настройки клавиатуры задаются с помощью клавиши keyboard. Этот ключ принимает в качестве значения сопоставление; в приведенном ниже примере мы указываем только тот макет , который хотим использовать (нас); также можно указать и другие параметры, например вариант планировки. Наконец, чтобы установить часовой пояс системы, мы используем ключ timezone:

#cloud-config
autoinstall:
  locale: en_US.UTF-8
  keyboard:
    layout: us
  timezone: Europe/Rome

Настройка сетевых интерфейсов

Чтобы настроить системную сеть, мы используем ключ network, используя синтаксис netplan. В приведенном ниже примере я указываю, что хочу, чтобы интерфейс Ethernet enp1s0 автоматически настраивался через dhcp4:

#cloud-config
autoinstall:
  network:
    version: 2
    ethernets:
      enp1s0:
        dhcp4: true

Настройка имени хоста и начального пользователя системы

Чтобы безопасно использовать нашу систему, нам необходимо создать хотя бы одного непривилегированного пользователя. Нам также необходимо установить имя хоста системы. Оба эти аспекта управляются с помощью ключа identity. Ключ принимает отображение в качестве значения; мы определяем имя пользователя, пароль и имя хоста с помощью соответствующих ключей:

#cloud-config
autoinstall:
  identity:
    username: egidio
    hostname: linuxconfig
    password: '$6$mzOdSSVUfhWRNhcX$mkm.drDfOLfpZRX/58ouJqMvitV2O0147VgKzKGYE6Qx4adJ8TXqMHs2dh2L7kT4TW5e97FCRDkGK1J.LouyV.'

Как вы можете видеть в примере, предоставленный нами пароль должен быть уже хеширован с использованием алгоритма sha512.

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

В файле автоустановки у нас есть возможность указать, хотим ли мы установить и настроить SSH-сервер. Мы можем включить или отключить аутентификацию по паролю и, в конечном итоге, передать список авторизованных открытых ключей, который будет добавлен в файл authorized_keys первоначального пользователя:

#cloud-config
autoinstall:
  ssh:
    install-server: true
    allow-pw: true
    authorized-keys: []

Установка дополнительных пакетов

Чтобы указать список дополнительных пакетов, которые будут загружены менеджером пакетов apt-get в рамках установки системы, мы можем использовать ключ packages. Вот пример:

#cloud-config
autoinstall:
  packages:
    - git
    - python3-pip

Вместо этого для установки пакетов моментальных снимков мы используем ключевое слово snaps. Ключевое слово принимает в качестве значения список сопоставлений. В каждом сопоставлении мы используем ключи name, channel и classic, чтобы указать, соответственно, имя устанавливаемого Snap-пакета, канал, из которого должен быть установлен снап (по умолчанию — «стабильный»), и следует ли устанавливать пакет снап в классическом режиме (по умолчанию — «false»):

#cloud-config
autoinstall:
  snaps:
    - name: pycharm-community
      channel: stable 
      classic: true

Определение действия после установки

Чтобы определить действие после установки, мы используем клавишу shutdown. Этот ключ принимает два возможных значения: «poweroff» и «reboot»:

#cloud-config
autoinstall:
  shutdown: reboot

Определение настройки хранилища

Одним из наиболее важных аспектов установки системы является настройка разделов. При интерактивной установке Ubuntu мы можем выбирать среди предустановленных макетов или создавать собственные настройки. Мы можем сделать то же самое при выполнении автоматической установки. Доступны предопределенные макеты: lvm, direct и zfs.

Макет lvm используется по умолчанию: он создает EFI (в случае современных систем UEFI) и стандартные загрузочные разделы, а остальную часть системы устанавливает на логический том LVM. Размер корневого логического тома определяется в соответствии с политикой: если для него установлено значение «масштабируемый» (по умолчанию), объем пространства, выделенного логическому тому, зависит от размера группы томов. По возможности некоторое пространство остается неиспользованным, чтобы можно было создавать снимки:

Less than 10 GiB

100% доступного пространства

Between 10 GiB and 20 GiB

10 ГиБ

Between 20GiB and 200 GiB

50% доступного пространства

Greater than 200 GiB

100 ГиБ

Если для политики установлено значение «все», вместо этого все доступное пространство назначается корневому логическому тому. В этом контексте ключ password можно использовать для включения шифрования LUKS и для предоставления пароля шифрования:

#cloud-config
autoinstall:
  storage:
    layout:
      name: lvm
      policy: all
      password: mysecretpassword

Макет прямой устанавливает Ubuntu на стандартные разделы. В системах UEFI он создает раздел EFI размером 1 ГБ, а остальное пространство выделяет корневому разделу.

Наконец, макет zfs устанавливает систему в пул ZFS, создавая несколько томов. Ниже вы можете увидеть снимок экрана установки zfs после новой установки Ubuntu:

Выбор диска для установки

Помимо структуры разделов, мы можем явно указать, какой диск следует использовать для установки. Мы делаем это с помощью ключа match. Мы можем выбрать диск по пути, производителю, модели, серийному номеру и т. д. Если ключевое слово опущено, установка происходит на самый большой доступный диск. В примере ниже мы выбираем диск по пути (/dev/vda):

#cloud-config
autoinstall:
  storage:
    layout:
      name: lvm
      match:
        path: /dev/vda

Создание индивидуального макета

Чтобы определить собственный макет разделов, мы используем ключевое слово config. Это ключевое слово принимает в качестве значения список сопоставлений, каждое из которых описывает команду установщика Curtin. Давайте посмотрим пример. Предположим, мы хотим установить Ubuntu на LVM в настройке LUKS, создав следующие разделы:

  1. Небольшой раздел EFI размером 600 МБ, отформатированный в fat32, который нужно смонтировать в /boot/efi.
  2. Загрузочный раздел размером 1 ГиБ, отформатированный в ext4 для монтирования в /boot.
  3. Третий раздел, охватывающий остальную часть пространства, зашифрованный с помощью LUKS и отформатированный как физический том LVM.
  4. Один логический том LVM объемом 45 ГиБ, который необходимо смонтировать на /
  5. Один логический том LVM объемом 50 ГиБ, который необходимо смонтировать в /home.

Вот как мы будем действовать. Первое, что нам нужно сделать, это использовать команду disk. Он используется для настройки дисков и создания таблиц разделов:

#cloud-config
autoinstall:
  storage:
    config:
      - id: disk-vda
        type: disk
        ptable: gpt
        path: /dev/vda
        wipe: superblock-recursive

С помощью ключевого слова id мы предоставляем идентификатор раздела и команды: это позволяет нам ссылаться на диск при использовании других команд. Вместо этого с помощью ключевого слова type мы указываем команду, которую хотим запустить, в данном случае это «диск».

При наличии ключа ptable на диске создается таблица разделов указанного типа. В данном случае мы использовали в качестве значения «gpt». Ключевое слово path используется для идентификации диска по его пути (/dev/vda).

Ключевое слово wipe очень важно: при его использовании уничтожается содержимое дисков или разделов. Мы можем использовать множество типов «затирания»: суперблок, суперблок-рекурсивный, ноль, случайный, и pvremove. Мы используем superblock, когда хотим стереть только суперблок диска, и superblock-recursive, когда хотим стереть также возможные встраиваемые суперблоки (они могут присутствовать при использовании LVM , например). Используя zero или random, мы можем перезаписать диск нулями или случайными данными соответственно. Наконец, pvremove специально стирает метаданные LVM, чтобы гарантировать, что диск не является частью настройки LVM. В приведенном выше примере мы использовали superblock-recursive, которого в большинстве случаев должно быть достаточно.

Создание стандартных разделов с помощью команды «partition».

Теперь нам нужно создать на диске три «стандартных» раздела. Первый — это раздел EFI, второй — раздел, который будет смонтирован в /boot, а третий — раздел, который будет зашифрован с помощью LUKS и использован в качестве физического тома LVM. Чтобы создать раздел, мы используем команду partition. В примерах ниже для ясности мы сосредоточимся на текущих командах, опуская те, которые использовали ранее:

#cloud-config
autoinstall:
  storage:
    config:
      # [...]

      - id: efipart
        type: partition
        device: disk-vda
        offset: 1048576
        size: 600M
        flag: boot
        grub_device: true

      - id: bootpart
        type: partition
        device: disk-vda
        size: 1G

      - id: pvpart
        type: partition
        device: disk-vda
        size: -1

Поскольку раздел «efipart» является первым, мы использовали ключевое слово offset, чтобы обеспечить его создание в размере 1 МБ от начала диска (значение указывается в байтах: 1048576). Мы использовали ключевое слово flag, чтобы указать флаг, который будет установлен для раздела, в данном случае «boot». Наконец, мы использовали ключевое слово grub_device, чтобы убедиться, что GRUB установлен в разделе.

Во всех определениях мы использовали ключ device для ссылки на диск, на котором необходимо создать раздел, и ключ  size для указания размера раздела. В случае раздела «pvpart» мы используем значение «-1»: это гарантирует, что раздел займет все оставшееся пространство на диске.

Создание зашифрованного тома LUKS с помощью команды dm_crypt

В качестве следующего шага мы хотим использовать LUKS для шифрования раздела «pvpart». Мы можем сделать это с помощью команды dm_crypt:

#cloud-config
autoinstall:
  storage:
    config:
      # [...]

      - id: pvpart-crypt
        type: dm_crypt
        volume: pvpart
        key: mysecretpassword

При использовании команды dm_crypt мы передаем идентификатор раздела, который мы хотим зашифровать, как значение ключа volume и используем key для укажите парольную фразу шифрования.

Создание группы томов LVM и логических томов

Чтобы создать группу томов LVM, мы используем команду lvm_volgroup и ключевое слово devices, чтобы перечислить физические тома, которые мы хотим добавить в группу:

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
     
      - id: vg0
        type: lvm_volgroup
        name: vg0
        devices:
          - pvpart-crypt

Для создания логических томов мы используем команду lvm_partition. Мы указываем имя LV с помощью ключа name, группу томов, в которой должен быть создан LV, как значение volgroup и ее размер с помощью size. клавиша :

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
      - id: root_lv
        type: lvm_partition
        name: root_lv
        volgroup: vg0
        size: 45G
 
      - id: home_lv
        type: lvm_partition
        name: home_lv
        volgroup: vg0
        size: 50G

Форматирование разделов

Чтобы создать файловые системы в определенных нами разделах и установить их точки монтирования, мы используем команду format. Мы используем ключевое слово volume для ссылки на раздел по идентификатору и ключевое слово fstype, чтобы указать, какую файловую систему следует создать:

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
    
      - id: efipart_fs
        type: format
        volume: efipart
        fstype: fat32

      - id: bootpart_fs
        type: format
        volume: bootpart
        fstype: ext4

      - id: root_lv_fs
        type: format
        volume: root_lv
        fstype: ext4

      - id: home_lv_fs
        type: format
        volume: home_lv
        fstype: ext4

Наконец, чтобы указать где должна быть смонтирована файловая система, мы используем команду mount. С помощью ключа device мы указываем идентификатор файловой системы; с path вместо этого его точкой монтирования:

#cloud-config
autoinstall:
  storage:
    config:
      # [...]
     
      - id: efipart-mount
        type: mount
        device: efipart_fs
        path: /boot/efi

      - id: bootpart-mount
        type: mount
        device: bootpart_fs
        path: /boot

      - id: root_lv_mount
        type: mount
        device: root_lv_fs
        path: /

      - id: home_lv_mount
        type: mount
        device: home_lv_fs
        path: /home

Передача конфигурации установщику Ubuntu

Вот как выглядит наш файл конфигурации автоустановки целиком:

#cloud-config
autoinstall:
  version: 1

  source:
    id: ubuntu-server-minimal

  locale: en_US.UTF-8
  keyboard:
    layout: us
  timezone: Europe/Rome

  network:
    version: 2
    ethernets:
      enp1s0:
        dhcp4: true

  identity:
    username: egidio
    hostname: linuxconfig
    password: '$6$mzOdSSVUfhWRNhcX$mkm.drDfOLfpZRX/58ouJqMvitV2O0147VgKzKGYE6Qx4adJ8TXqMHs2dh2L7kT4TW5e97FCRDkGK1J.LouyV.'

  ssh:
    install-server: true
    allow-pw: true
    authorized-keys: []

  packages:
    - git
    - python3-pip

  snaps:
    - name: pycharm-community
      channel: stable 
      classic: true

  shutdown: reboot
  storage:
    config:
      - id: disk-vda
        type: disk
        ptable: gpt
        path: /dev/vda
        wipe: superblock-recursive

      - id: efipart
        type: partition
        device: disk-vda
        offset: 1048576
        size: 600M
        flag: boot
        grub_device: true

      - id: bootpart
        type: partition
        device: disk-vda
        size: 1G

      - id: pvpart
        type: partition
        device: disk-vda
        size: -1

      - id: pvpart-crypt
        type: dm_crypt
        volume: pvpart
        key: mysecretpassword

      - id: vg0
        type: lvm_volgroup
        name: vg0
        devices:
          - pvpart-crypt

      - id: root_lv
        type: lvm_partition
        name: root_lv
        volgroup: vg0
        size: 45G
 
      - id: home_lv
        type: lvm_partition
        name: home_lv
        volgroup: vg0
        size: 50G

      - id: efipart_fs
        type: format
        volume: efipart
        fstype: fat32

      - id: bootpart_fs
        type: format
        volume: bootpart
        fstype: ext4

      - id: root_lv_fs
        type: format
        volume: root_lv
        fstype: ext4

      - id: home_lv_fs
        type: format
        volume: home_lv
        fstype: ext4

      - id: efipart-mount
        type: mount
        device: efipart_fs
        path: /boot/efi

      - id: bootpart-mount
        type: mount
        device: bootpart_fs
        path: /boot

      - id: root_lv_mount
        type: mount
        device: root_lv_fs
        path: /

      - id: home_lv_mount
        type: mount
        device: home_lv_fs
        path: /home

Как передать конфигурацию установщику Ubuntu? При установке настольной версии Ubuntu самый простой и удобный способ состоит в том, чтобы сделать наш файл конфигурации доступным через HTTP или FTP и передать его URL-адрес в соответствующем разделе графического установщика:

Файл конфигурации автоматической установки автоматически создается после каждой установки Ubuntu, даже если она выполняется в интерактивном режиме. Вы можете найти файл, сохраненный как /var/log/installer/autoinstall-user-data. Этот файл можно использовать для репликации установки.

Если мы хотим выполнить полностью автоматическую установку или использовать конфигурацию автоматической установки при установке сервера Ubuntu, мы должны использовать Cloud-init и использовать конфигурацию в виде файла данных Cloud-Config: это то, что «#cloud-config» Комментарий в самом начале файла автоустановки предназначен для.

Чтобы Cloud-init мог прочитать файл при загрузке, нам нужно переименовать его в user-data и создать пустой файл с именем meta-data в том же каталоге. Мы нажимаем «e», чтобы изменить первую запись живого меню ISO GRUB:

Затем мы модифицируем строку, начинающуюся с «linux», добавляя следующую строку перед тремя дефисами (важно избегать точки с запятой!):

autoinstall ds=nocloud-net\;s=<directory-URL>

Где — URL-адрес каталога, содержащего файлы пользовательских данных и метаданных:

На этом этапе, чтобы начать установку, мы просто нажимаем Ctrl-x.

Заключительные мысли

Начиная с версии сервера Ubuntu 20.04 и настольной версии Ubuntu 23.04, можно выполнять автоматическую и воспроизводимую установку системы, используя собственный формат автоматической установки. В этом уроке мы увидели, как написать файл автоустановки и некоторые ключи, которые можно в нем использовать. Наконец, мы увидели, как передать файл установщикам рабочего стола и сервера Ubuntu. Полную информацию по автоматической установке Ubuntu можно найти в официальной документации.

Статьи по данной тематике: