Как написать и выполнить автоматическую установку 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, создав следующие разделы:
- Небольшой раздел EFI размером 600 МБ, отформатированный в fat32, который нужно смонтировать в /boot/efi.
- Загрузочный раздел размером 1 ГиБ, отформатированный в ext4 для монтирования в /boot.
- Третий раздел, охватывающий остальную часть пространства, зашифрованный с помощью LUKS и отформатированный как физический том LVM.
- Один логический том LVM объемом 45 ГиБ, который необходимо смонтировать на /
- Один логический том 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>
Где
На этом этапе, чтобы начать установку, мы просто нажимаем Ctrl-x.
Заключительные мысли
Начиная с версии сервера Ubuntu 20.04 и настольной версии Ubuntu 23.04, можно выполнять автоматическую и воспроизводимую установку системы, используя собственный формат автоматической установки. В этом уроке мы увидели, как написать файл автоустановки и некоторые ключи, которые можно в нем использовать. Наконец, мы увидели, как передать файл установщикам рабочего стола и сервера Ubuntu. Полную информацию по автоматической установке Ubuntu можно найти в официальной документации.