---
title: 'Подготовить ISO-образ для автоустановки ОС на выделенный сервер'
sidebar_label: 'Подготовить ISO-образ для автоустановки'
sidebar_position: 8
description: 'Как создать и загрузить совместимый ISO-образ для автоустановки ОС на выделенный сервер в Selectel'
---

import Formbricks from '@theme/MDXComponents/Formbricks'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import {TabItemLabel} from '@selectel/docux/components'

# Подготовить ISO-образ для автоустановки ОС на выделенный сервер

Вы можете подготовить собственный образ ОС, который будет совместим с механизмом автоустановки ОС на выделенный сервер в Selectel.

Если у вас нет особых требований к ОС, мы рекомендуем использовать [стандартные образы](/dedicated/manage/install-os-from-preinstalled-iso-images.mdx) — из них можно [установить ОС автоустановкой](/dedicated/manage/autoinstall-os.mdx) или [вручную](/dedicated/manage/install-os-from-preinstalled-iso-images.mdx).

1. [Создайте ISO-образ](#create-image).
2. [Загрузите образ в хранилище S3](#upload-image-to-s3).
3. [Получите ссылку на объект в хранилище](#obtain-link-to-object).
4. [Добавьте ISO-образ в панель управления](#add-image-to-panel).

## 1. Создать ISO-образ \{#create-image}

Размер архива с образом ОС должен быть минимум на 3 ГБ меньше размера оперативной памяти выделенного сервера.
Например, если размер оперативной памяти сервера 8 ГБ, размер архива с образом не должен превышать 5 ГБ.

<Tabs queryString="create-image">
  <TabItem value="ubuntu" default>
    <TabItemLabel>
      Ubuntu
    </TabItemLabel>

    Рекомендуем выполнять подготовку системы от пользователя `root`.

    1. Для подготовки архива с образом установите ОС без программного RAID и без раздела `swap`.
       Рекомендуем [установить ОС автоустановкой](/dedicated/manage/autoinstall-os.mdx) на ваш выделенный сервер, тогда некоторые шаги инструкции будут уже выполнены.

    2. Проверьте состояние пакета `sssd` и удалите его, если он установлен:

       2.1. Проверьте состояние пакета `sssd`:

       ```bash
       dpkg -l sssd
       ```

       Если пакет установлен, в ответе появится строка со статусом `ii`, например `ii  sssd  2.9.1-...`.

       2.2. Если пакет `sssd` установлен, удалите его:

       ```bash
       sudo apt purge -y sssd
       sudo apt autoremove -y
       ```

    3. Установите обязательные пакеты:

       ```bash
       sudo apt install -y \
           openssh-server \
           cloud-init \
           grub2 \
           grub-efi-amd64-bin \
           mdadm \
           nftables
       ```

    4. Обновите ядро ОС до последней стабильной версии:

       ```bash
       linux-image-generic-hwe-24.04
       linux-headers-generic-hwe-24.04
       ```

    5. Обновите пакеты в системе:

       ```bash
       apt update && apt upgrade -y
       ```

    6. Подготовьте сервис `cloud-init` к использованию в образе:

       6.1. Удалите файлы и директории, которые содержат текущую конфигурацию `cloud-init`:

       ```bash
       rm -rf /etc/cloud/cloud.cfg.d /etc/cloud/cloud-init.disabled
       ```

       6.2. Удалите данные с прошлого выполнения `cloud-init`:

       ```bash
       cloud-init clean --logs
       ```

       6.3. Создайте директорию `/etc/cloud/cloud.cfg.d`:

       ```bash
       mkdir -p /etc/cloud/cloud.cfg.d
       ```

       6.4. Создайте файл `/etc/cloud/cloud.cfg` текстовым редактором `vi`:

       ```bash
       vi /etc/cloud/cloud.cfg
       ```

       6.5. Добавьте в файл конфигурацию `cloud-init`:

       <details>
         <summary>Файл `/etc/cloud/cloud.cfg`</summary>

         ```bash
         datasource_list:
             - NoCloud
             - None

         users:
             - default

         #disable_root: 1
         #ssh_pwauth:   0

         mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
         resize_rootfs_tmp: /dev
         ssh_deletekeys:   1
         ssh_genkeytypes:  ['rsa', 'ecdsa', 'ed25519']
         syslog_fix_perms: ~
         disable_vmware_customization: false

         cloud_init_modules:
             - disk_setup
             - growpart
             - resizefs
             - set_hostname
             - update_hostname
             - update_etc_hosts
             - users-groups
             - ssh
             - apt-configure
             - bootcmd
             - ca_certs
             - rsyslog
             - write_files

         cloud_config_modules:
             - mounts
             - locale
             - set-passwords
             - timezone
             - runcmd
             - snap
             - ssh_import_id
             - ubuntu_drivers
             - ntp

         cloud_final_modules:
             - package-update-upgrade-install
             - scripts-per-once
             - scripts-per-boot
             - scripts-per-instance
             - scripts-user
             - ssh-authkey-fingerprints
             - keys-to-console
             - final-message
             - power-state-change
             - lxd
             - puppet
             - chef
             - mcollective
             - salt_minion
             - phone_home

         system_info:
             default_user:
                 name: cloud-user
                 lock_passwd: true
                 gecos: Cloud User
                 groups: [adm, systemd-journal]
                 sudo: ["ALL=(ALL) NOPASSWD:ALL"]
                 shell: /bin/bash
             distro: ubuntu
             paths:
                 cloud_dir: /var/lib/cloud
                 templates_dir: /etc/cloud/templates
             ssh_svcname: sshd

         vendor_data:
             enabled: True

         # vim:syntax=yaml
         ```
       </details>

       6.6. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

       6.7. Создайте файл `cloud-init-local.service` текстовым редактором `vi`:

       ```bash
       sudo vi /usr/lib/systemd/system/cloud-init-local.service
       ```

       6.8. Добавьте в файл конфигурацию:

       ```bash
       [Unit]
       Description=Initial cloud-init job (pre-networking)
       DefaultDependencies=no
       Wants=network-pre.target
       After=hv_kvp_daemon.service
       After=systemd-remount-fs.service
       Before=NetworkManager.service
       Before=network-pre.target
       Before=shutdown.target
       Before=sysinit.target
       Conflicts=shutdown.target
       RequiresMountsFor=/var/lib/cloud
       ConditionPathExists=!/etc/cloud/cloud-init.disabled
       ConditionKernelCommandLine=!cloud-init=disabled
       ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled

       [Service]
       Type=oneshot
       ExecStartPre=sleep 30
       ExecStart=/usr/bin/cloud-init init --local
       RemainAfterExit=yes
       TimeoutSec=0

       # Output needs to appear in instance console output
       StandardOutput=journal+console

       [Install]
       WantedBy=cloud-init.target
       ```

       6.9. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

    7. Добавьте и настройте скрипт per-boot:

       7.1. Создайте файл скрипта `boot_order_sort.sh` текстовым редактором `vi`:

       ```bash
       sudo vi /var/lib/cloud/scripts/per-boot/boot_order_sort.sh
       ```

       7.2. Добавьте в файл текст скрипта:

       <details>
         <summary>Файл `boot_order_sort.sh`</summary>

         ```bash
         #!/bin/bash

         # Retrieve the output of efibootmgr
         efi_output=$(efibootmgr -D 2>&1)

         # Check if the system supports EFI
         if [[ $? -ne 0 ]]; then
             echo "[WARNING] System does not support EFI, boot order will not be changed."
             exit 0
         fi

         # Extract the current boot entry (BootCurrent)
         current_os=$(echo "$efi_output" | grep -oP '(?<=BootCurrent: )[0-9A-F]{4}')
         # Extract the boot order (BootOrder)
         boot_order=$(echo "$efi_output" | grep -oP '(?<=BootOrder: )[0-9A-F,]+')

         # Declare an associative array to store BootXXXX values and their descriptions
         declare -A boot_dict
         # boot_order_sorted will contain the sorted boot order
         # removed_entries will contain boot numbers that are not in the sorted list (and are removed)
         boot_order_sorted=()
         removed_entries=()

         # Parse all BootXXXX entries with their descriptions (remove 'Boot' prefix and *)
         boot_entries=$(echo "$efi_output" | grep -oP '(?<=Boot)[0-9A-F]{4}\*?.*')

         if [[ -z "$boot_entries" ]]; then
             echo "[ERROR] No boot entries found in EFI output."
             exit 1
         fi

         # Debug output
         echo "[INFO] Current Boot: ${current_os:-None}"
         echo "[INFO] Boot Order: ${boot_order:-None}"

         # Loop through and process each boot entry
         while read -r entry; do
             # Extract the four-digit boot number (excluding 'Boot' and '*')
             boot_number=$(echo "$entry" | grep -oP '^[0-9A-F]{4}')
             # Extract the description (everything after the boot number)
             description=$(echo "$entry" | sed 's/^[0-9A-F]\{4\}\* //')
             # Ensure the boot_number is not empty and add to the dictionary
             if [[ -n "$boot_number" ]]; then
                 boot_dict["$boot_number"]="$description"
             fi
             # Add entries containing "IP4" or "PXE", but not containing "HTTP", to the sorted list
             if [[ ("$description" =~ "IP4" || "$description" =~ "PXE" || "$description" =~ "IPv4" || "$description" =~ "NIC") && ! "$description" =~ "HTTP" ]]; then
                 boot_order_sorted+=("$boot_number")
             fi
             echo "$boot_number: $description"
         done <<< "$boot_entries"

         # Add the current OS to the main list if it exists
         if [[ -n "$current_os" ]]; then
             boot_order_sorted+=("$current_os")
         fi

         # Find all entries with the same description as current_os and add them to the sorted list
         if [[ -n "$current_os" ]]; then
             current_description="${boot_dict[$current_os]}"
             for boot_number in "${!boot_dict[@]}"; do
                 # If description matches the current OS but boot number is not the same, add it to the sorted list
                 if [[ "$boot_number" != "$current_os" && "${boot_dict[$boot_number]}" == "$current_description" ]]; then
                     boot_order_sorted+=("$boot_number")
                 fi
             done
         fi

         # Find all boot numbers that are not in the main sorted list and remove them
         if [[ ${#boot_dict[@]} -eq 0 ]]; then
             echo "[INFO] No boot entries to process."
         else
             for boot_number in "${!boot_dict[@]}"; do
                 if [[ ! " ${boot_order_sorted[*]} " =~ " $boot_number " ]]; then
                     # Remove the boot entry from the system
                     efibootmgr -b "$boot_number" -B > /dev/null 2>&1
                     removed_entries+=("$boot_number")  # Add removed boot number to the removed entries list
                     echo "[INFO] Removed Boot Entry: $boot_number"
                 fi
             done
         fi

         # Convert the main boot order list to a comma-separated string
         if [[ ${#boot_order_sorted[@]} -eq 0 ]]; then
             boot_order_sorted_str="None"
         else
             boot_order_sorted_str=$(IFS=,; echo "${boot_order_sorted[*]}")
             efibootmgr -o "$boot_order_sorted_str" > /dev/null 2>&1
             echo "[INFO] Updated boot order: $boot_order_sorted_str"
         fi

         # Show the final EFI boot entries for verification
         efibootmgr -D
         ```
       </details>

       7.3. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

       7.4. Установите права на файл `boot_order_sort.sh`:

       ```bash
       sudo chmod 700 /var/lib/cloud/scripts/per-boot/boot_order_sort.sh
       ```

    8. Опционально: настройте SSH.
       По умолчанию при установке ОС сервис `cloud-init` задает пароль только для пользователя `root`.
       Вы можете использовать собственную схему аутентификации, например запретить вход по паролю и под пользователем `root`, создав отдельного пользователя с авторизацией по SSH-ключу.
       В этом случае пароль `root`, переданный при установке, будет установлен, но использоваться не будет.

       8.1. Откройте файл конфигурации `/etc/ssh/sshd_config` текстовым редактором `vi`:

       ```bash
       sudo vi /etc/ssh/sshd_config
       ```

       8.2. Если хотите разрешить вход по SSH от имени пользователя `root`, измените или добавьте параметр `PermitRootLogin yes`.

       8.3. Если хотите разрешить аутентификацию по паролю, измените или добавьте параметр `PasswordAuthentication yes`.

       8.4. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

    9. Опционально: настройте `grub`:

       9.1. Откройте файл конфигурации `/etc/default/grub` текстовым редактором `vi`:

       ```bash
       sudo vi /etc/default/grub
       ```

       9.2. Измените или добавьте параметры:

       ```bash
       GRUB_DEFAULT=0
       GRUB_TIMEOUT=5
       GRUB_DISTRIBUTOR=Ubuntu
       GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet nomodeset"
       GRUB_CMDLINE_LINUX="rd.auto=1 net.ifnames=0 biosdevname=0"
       GRUB_PRELOAD_MODULES="part_gpt part_msdos"
       GRUB_TIMEOUT_STYLE=menu
       GRUB_TERMINAL_INPUT=console
       GRUB_GFXMODE=auto
       GRUB_GFXPAYLOAD_LINUX=keep
       GRUB_DISABLE_RECOVERY=true
       GRUB_DISABLE_OS_PROBER=false
       ```

       9.3. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

    10. Опционально: установите и настройте `Fail2ban` — сервис блокировки IP-адреса в случае неудачных попыток авторизации:

        10.1. Установите `Fail2ban`:

        ```bash
        fail2ban
        ```

        10.2. Откройте файл конфигурации `/etc/fail2ban/jail.d/service.conf` текстовым редактором `vi`:

        ```bash
        sudo vi /etc/fail2ban/jail.d/service.conf
        ```

        10.3. Измените или добавьте параметры:

        ```bash
        [sshd]
        enabled = true
        port = ssh
        filter = sshd
        action = nftables[name=sshd, port=ssh, protocol=tcp]
        logpath = /var/log/auth.log
        maxretry = 10
        findtime = 3600
        bantime = 86400
        ```

        10.4. Выйдите из текстового редактора `vi` с сохранением изменений:

        ```bash
        :wq
        ```

    11. Опционально: внесите дополнительные изменения в систему, например установите дополнительное ПО, пакеты или выполните другие необходимые настройки для вашего образа.
        Убедитесь, что внесенные изменения не противоречат предыдущим шагам инструкции.

    12. Отключите режим сна и гибернации:

        ```bash
        systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
        ```

    13. Создайте символьную ссылку для `mdamd`:

        ```bash
        ln -s /usr/sbin/mdadm /usr/bin/mdadm
        ```

    14. Включите службу `system-resolved`:

        ```bash
        systemctl enable --now systemd-resolved
        ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
        ```

    15. Удалите неиспользуемые пакеты:

        ```bash
        apt autoremove -y
        ```

    16. Примените изменения, для этого перезагрузите систему:

        ```bash
        systemctl reboot
        ```

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

        ```bash
        truncate -s 0 /etc/machine-id /var/lib/dbus/machine-id
        ```

    18. Подготовьте файл со списком каталогов, которые не должны попасть в архив образа ОС:

        18.1. Создайте файл `exclude.txt` текстовым редактором `vi`:

        ```bash
        sudo vi /root/exclude.txt
        ```

        18.2. Добавьте в файл `exclude.txt` список каталогов, которые нужно исключить из архива:

        ```bash
        /tmp/*
        /proc/*
        /sys/*
        /dev/*
        /run/*
        /mnt/*
        /media/*
        /var/lib/lxcfs
        /var/spool/postfix
        /lost+found
        ```

        18.3. Выйдите из текстового редактора `vi` с сохранением изменений:

        ```bash
        :wq
        ```

    19. Создайте архив файловой системы:

        ```bash
        tar -czp -f /mnt/base.tar.gz --exclude-from=/root/exclude.txt /
        ```
  </TabItem>

  <TabItem value="debian">
    <TabItemLabel>
      Debian
    </TabItemLabel>

    Рекомендуем выполнять подготовку системы от пользователя `root`.

    1. Для подготовки архива с образом установите ОС без программного RAID и без раздела `swap`.
       Например, вы можете установить ОС автоустановкой на ваш выделенный сервер, тогда некоторые шаги инструкции будут уже готовы.

    2. Проверьте состояние пакета `sssd` и удалите его, если он установлен:

       2.1. Проверьте состояние пакета `sssd`:

       ```bash
       dpkg -l sssd
       ```

       Если пакет установлен, в ответе появится строка со статусом `ii`, например `ii  sssd  2.9.1-...`.

       2.2. Если пакет `sssd` установлен, удалите его:

       ```bash
       sudo apt purge -y sssd
       sudo apt autoremove -y
       ```

    3. Установите обязательные пакеты:

       ```bash
       sudo apt install -y \
           openssh-server \
           cloud-init \
           grub2 \
           grub-efi-amd64-bin \
           mdadm \
           rsyslog \
           resolvconf \
           systemd-timesyncd \
           python3 \
           efibootmgr
       ```

    4. Подготовьте сервис `cloud-init` к использованию в образе:

       4.1. Удалите файлы и каталоги, которые содержат текущую конфигурацию `cloud-init`:

       ```bash
       rm -rf /etc/cloud/cloud.cfg.d
       rm -rf /etc/cloud/cloud-init.disabled
       ```

       4.2. Создайте файл конфигурации `/etc/cloud/cloud.cfg` текстовым редактором `vi`:

       ```bash
       sudo vi /etc/cloud/cloud.cfg
       ```

       4.3. Добавьте в файл конфигурацию:

       <details>
         <summary>Файл `/etc/cloud/cloud.cfg`</summary>

         ```bash
         datasource_list:
             - NoCloud
             - None
             
         users:
             - default
             
         #disable_root: 1
         #ssh_pwauth:   0

         mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
         resize_rootfs_tmp: /dev
         ssh_deletekeys:   1
         ssh_genkeytypes:  ['rsa', 'ecdsa', 'ed25519']
         syslog_fix_perms: ~
         disable_vmware_customization: false
             
         cloud_init_modules:
             - disk_setup
             - growpart
             - resizefs
             - set_hostname
             - update_hostname
             - update_etc_hosts
             - users-groups
             - ssh
             - write-files
             - bootcmd
             - apt_configure
             - ca_certs
             - rsyslog
             
         cloud_config_modules:
             - mounts
             - locale
             - set-passwords
             - timezone
             - runcmd
             - ssh_import_id
             - ntp
             
         cloud_final_modules:
             - package-update-upgrade-install
             - scripts-per-once
             - scripts-per-boot
             - scripts-per-instance
             - scripts-user
             - ssh-authkey-fingerprints
             - keys-to-console
             - final-message
             - power-state-change
             - puppet
             - chef
             - mcollective
             - salt_minion
             - phone_home
             
         system_info:
             default_user:
                 name: cloud-user
                 lock_passwd: true
                 gecos: Cloud User
                 groups: [adm, systemd-journal]
                 sudo: ["ALL=(ALL) NOPASSWD:ALL"]
                 shell: /bin/bash
             distro: debian
             paths:
                 cloud_dir: /var/lib/cloud
                 templates_dir: /etc/cloud/templates
             ssh_svcname: sshd
             
         vendor_data:
             enabled: True
         ```
       </details>

       4.4. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

    5. Добавьте и настройте скрипт per-boot:

       5.1. Создайте файл скрипта `boot_order_sort.sh` текстовым редактором `vi`:

       ```bash
       sudo vi /var/lib/cloud/scripts/per-boot/boot_order_sort.sh
       ```

       5.2. Добавьте в файл текст скрипта:

       <details>
         <summary>Файл `boot_order_sort.sh`</summary>

         ```bash
         #!/bin/bash

         # Retrieve the output of efibootmgr
         efi_output=$(efibootmgr -D 2>&1)
             
         # Check if the system supports EFI
         if [[ $? -ne 0 ]]; then
             echo "[WARNING] System does not support EFI, boot order will not be changed."
             exit 0
         fi
             
         # Extract the current boot entry (BootCurrent)
         current_os=$(echo "$efi_output" | grep -oP '(?<=BootCurrent: )[0-9A-F]{4}')
         # Extract the boot order (BootOrder)
         boot_order=$(echo "$efi_output" | grep -oP '(?<=BootOrder: )[0-9A-F,]+')

         # Declare an associative array to store BootXXXX values and their descriptions
         declare -A boot_dict
         # boot_order_sorted will contain the sorted boot order
         # removed_entries will contain boot numbers that are not in the sorted list (and are removed)
         boot_order_sorted=()
         removed_entries=()

         # Parse all BootXXXX entries with their descriptions (remove 'Boot' prefix and *)
         boot_entries=$(echo "$efi_output" | grep -oP '(?<=Boot)[0-9A-F]{4}\*?.*')

         if [[ -z "$boot_entries" ]]; then
             echo "[ERROR] No boot entries found in EFI output."
             exit 1
         fi
             
         # Debug output
         echo "[INFO] Current Boot: ${current_os:-None}"
         echo "[INFO] Boot Order: ${boot_order:-None}"

         # Loop through and process each boot entry
         while read -r entry; do
             # Extract the four-digit boot number (excluding 'Boot' and '*')
             boot_number=$(echo "$entry" | grep -oP '^[0-9A-F]{4}')
             # Extract the description (everything after the boot number)
             description=$(echo "$entry" | sed 's/^[0-9A-F]\{4\}\* //')
             # Ensure the boot_number is not empty and add to the dictionary
             if [[ -n "$boot_number" ]]; then
                 boot_dict["$boot_number"]="$description"
             fi
             # Add entries containing "IP4" or "PXE", but not containing "HTTP", to the sorted list
             if [[ ("$description" =~ "IP4" || "$description" =~ "PXE" || "$description" =~ "IPv4" || "$description" =~ "NIC") && ! "$description" =~ "HTTP" ]]; then
                 boot_order_sorted+=("$boot_number")
             fi
             echo "$boot_number: $description"
         done <<< "$boot_entries"
             
         # Add the current OS to the main list if it exists
         if [[ -n "$current_os" ]]; then
             boot_order_sorted+=("$current_os")
         fi
             
         # Find all entries with the same description as current_os and add them to the sorted list
         if [[ -n "$current_os" ]]; then
             current_description="${boot_dict[$current_os]}"
             for boot_number in "${!boot_dict[@]}"; do
                 # If description matches the current OS but boot number is not the same, add it to the sorted list
                 if [[ "$boot_number" != "$current_os" && "${boot_dict[$boot_number]}" == "$current_description" ]]; then
                     boot_order_sorted+=("$boot_number")
                 fi
             done
         fi
             
         # Find all boot numbers that are not in the main sorted list and remove them
         if [[ ${#boot_dict[@]} -eq 0 ]]; then
             echo "[INFO] No boot entries to process."
         else
             for boot_number in "${!boot_dict[@]}"; do
                 if [[ ! " ${boot_order_sorted[*]} " =~ " $boot_number " ]]; then
                     # Remove the boot entry from the system
                     efibootmgr -b "$boot_number" -B > /dev/null 2>&1
                     removed_entries+=("$boot_number")  # Add removed boot number to the removed entries list
                     echo "[INFO] Removed Boot Entry: $boot_number"
                 fi
             done
         fi
             
         # Convert the main boot order list to a comma-separated string
         if [[ ${#boot_order_sorted[@]} -eq 0 ]]; then
             boot_order_sorted_str="None"
         else
             boot_order_sorted_str=$(IFS=,; echo "${boot_order_sorted[*]}")
             efibootmgr -o "$boot_order_sorted_str" > /dev/null 2>&1
             echo "[INFO] Updated boot order: $boot_order_sorted_str"
         fi
             
         # Show the final EFI boot entries for verification
         efibootmgr -D
         ```
       </details>

       5.3. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

       5.4. Установите права на файл скрипта:

       ```bash
       sudo chmod 700 /var/lib/cloud/scripts/per-boot/boot_order_sort.sh
       ```

    6. Опционально: внесите дополнительные изменения в систему, например установите дополнительное ПО, пакеты или выполните другие необходимые настройки для вашего образа.
       Убедитесь, что внесенные изменения не противоречат предыдущим шагам инструкции.

    7. Создайте символьную ссылку для `mdamd`:

       ```bash
       ln -s /usr/sbin/mdadm /usr/bin/mdadm
       ```

    8. Удалите неиспользуемые пакеты:

       ```bash
       apt autoremove -y
       ```

    9. Примените изменения, для этого перезагрузите систему:

       ```bash
       systemctl reboot
       ```

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

        ```bash
        truncate -s 0 /etc/machine-id /var/lib/dbus/machine-id
        ```

    11. Подготовьте файл со списком каталогов, которые не должны попасть в архив образа ОС:

        11.1. Создайте файл `exclude.txt` текстовым редактором `vi`:

        ```bash
        sudo vi /root/exclude.txt
        ```

        11.2. Добавьте в файл `exclude.txt` список каталогов, которые нужно исключить из архива:

        ```bash
        /tmp/*
        /proc/*
        /sys/*
        /dev/*
        /run/*
        /mnt/*
        /media/*
        /var/lib/lxcfs
        /var/spool/postfix
        /lost+found
        ```

        11.3. Выйдите из текстового редактора `vi` с сохранением изменений:

        ```bash
        :wq
        ```

    12. Создайте архив файловой системы:

        ```bash
        tar -czp -f /mnt/base.tar.gz --exclude-from=/root/exclude.txt /
        ```
  </TabItem>

  <TabItem value="windows">
    <TabItemLabel>
      Windows Server
    </TabItemLabel>

    1. Для подготовки архива с образом вы можете установить ОС автоустановкой на ваш выделенный сервер, тогда некоторые шаги инструкции будут уже готовы.

       Чтобы избежать несовместимости с комплектующими сервера, рекомендуем установить обширный набор драйверов, которые не поставляются с ядром системы.

    2. Подготовьте службу `Cloudbase-Init` к использованию в образе:

       2.1. Установите [`Cloudbase-Init`](https://www.cloudbase.it/downloads/CloudbaseInitSetup_Stable_x64.msi).

       2.2. Откройте файл конфигурации `cloudbase-init.conf`.
       По умолчанию файл находится в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\`.

       2.3. Добавьте в файл конфигурацию:

       <details>
         <summary>Файл `cloudbase-init.conf`</summary>

         ```bash
         [DEFAULT]
         username=Administrator
         groups=Administrators
         inject_user_password=true
         config_drive_raw_hhd=false
         config_drive_cdrom=false
         config_drive_vfat=true
         config_drive_locations=partition
         bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
         mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
         verbose=true
         debug=true
         logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
         logfile=cloudbase-init.log
         default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
         logging_serial_port_settings=COM1,115200,N,8
         mtu_use_dhcp_config=false
         ntp_use_dhcp_config=false
         local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
         check_latest_version=false
         metadata_services=cloudbaseinit.metadata.services.nocloudservice.NoCloudConfigDriveService
         plugins=cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,
                 cloudbaseinit.plugins.common.userdata.UserDataPlugin,
                 cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin,
                 cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin,
                 cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin,
                 cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin
         ```
       </details>

       2.4. Откройте файл конфигурации `cloudbase-init-unattend.conf`.
       По умолчанию файл находится в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-init\conf\`.

       2.5. Добавьте в файл конфигурацию:

       <details>
         <summary>Файл `cloudbase-init-unattend.conf`</summary>

         ```bash
         [DEFAULT]
         username=Administrator
         groups=Administrators
         inject_user_password=true
         config_drive_raw_hhd=false
         config_drive_cdrom=false
         config_drive_vfat=true
         config_drive_locations=partition
         bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
         mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
         verbose=true
         debug=true
         logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
         logfile=cloudbase-init-unattend.log
         default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
         logging_serial_port_settings=COM1,115200,N,8
         mtu_use_dhcp_config=false
         ntp_use_dhcp_config=false
         local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
         check_latest_version=false
         metadata_services=cloudbaseinit.metadata.services.nocloudservice.NoCloudConfigDriveService
         plugins=cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,
                 cloudbaseinit.plugins.common.userdata.UserDataPlugin,
                 cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin,
                 cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin,
                 cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin,
                 cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin
         ```
       </details>

    3. Подготовьте скрипты `Cloudbase-Init` — они выполняются во время первоначальной настройки сервера:

       3.1. Чтобы установить загрузку сервера по сети в качестве приоритетной, создайте скрипт `get_efi_network.ps1` в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-init\LocalScripts\`:

       <details>
         <summary>Файл `get_efi_network.ps1`</summary>

         ```bash
         #ps1_x64

         $scriptPath = "C:\Scripts\set_boot_order.ps1"
             
         $scriptContent = @'
         $list_identifier_pxe = bcdedit /enum firmware |
             Select-String "U?EFI:?.*IP.*v?4|NIC.*Partition|Embedded NIC" -Context 1 |
             ForEach-Object { $_.Context.PreContext[0] } |
             ForEach-Object { $_ -replace "^identifier +", "" } |
             Sort-Object {Get-Random}
             
         foreach ($i in $list_identifier_pxe) {
             bcdedit /set "{fwbootmgr}" displayorder "$i" /addfirst
         }
         '@
             
         $folder = Split-Path $scriptPath
         if (-not (Test-Path $folder)) {
             New-Item -ItemType Directory -Path $folder -Force | Out-Null
         }
             
         Set-Content -Path $scriptPath -Value $scriptContent -Encoding UTF8
             
         $taskName = "SetUEFIBootOrder"
         for ($i = 0; $i -lt 5; $i++) {
             try {
                 $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"$scriptPath`""
                 if ($action) { break }
             } catch {
                 Start-Sleep -Seconds 5
             }
         }
         $trigger = New-ScheduledTaskTrigger -AtStartup
         $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest

         $taskExists = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue

         if ($taskExists) {
             Set-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal
         } else {
             Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal
         }

         Start-ScheduledTask -TaskName $taskName

         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

       3.2. Чтобы удалить раздел `CIDATA` с конфигурациями `Cloudbase-init` после завершения первоначальной настройки, создайте файл `remove_cidata.ps1` в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-init\LocalScripts\`:

       <details>
         <summary>Файл `remove_cidata.ps1`</summary>

         ```bash
         #ps1_sysnative

         # find partition with a name CIDATA
         $DataPartition=Get-WMIObject Win32_Volume | ? { $_.Label -eq 'CIDATA' }

         # remove disk letter from CIDATA object
         $DataPartition.DriveLetter = $null

         # save changes
         $DataPartition.Put()

         # self delete this script
         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

       3.3. Чтобы отключить NetBIOS на всех сетевых интерфейсах, создайте файл `disable_netbios.ps1` в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\`:

       <details>
         <summary>Файл `disable_netbios.ps1`</summary>

         ```bash
         #ps1_sysnative

         # disables netbios on all interfaces
         $i = 'HKLM:\SYSTEM\CurrentControlSet\Services\netbt\Parameters\interfaces'
         Get-ChildItem $i | ForEach-Object {Set-ItemProperty -Path "$i\$($_.pschildname)" -name NetBiosOptions -value 2}

         # self delete this script
         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

       3.4. Чтобы отключить технологию Large Send Offload (LSO) на сетевых интерфейсах для повышения совместимости с оборудованием, которое некорректно поддерживает эту функцию, создайте файл `disable_large_send_offload.ps1` в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\`:

       <details>
         <summary>Файл `disable_large_send_offload.ps1`</summary>

         ```bash
         #ps1_sysnative

         # disables large send offload on all adapters
         Disable-NetAdapterLso -Name *

         # self delete this script
         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

       3.5. Чтобы диск корректно определялся в [режиме WinPE](/dedicated/troubleshooting/boot-to-recovery.mdx#select-recovery-and-diagnostic-mode), создайте два файла:

       * скрипт `diskpart.ps1`, который запускает утилиту `diskpart` и выполняет команды из файла в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\`:

       <details>
         <summary>Файл `diskpart.ps1`</summary>

         ```bash
         # This script executes diskpart script stored in diskpart.txt
         diskpart /s C:\diskpart.txt

         # delete diskpart.txt config file
         Remove-Item "C:\diskpart.txt" -Force

         # self delete this script
         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

       * файл `diskpart.txt` с командами, которые снимают с системного раздела атрибут `NoDefaultDriveLetter` в директории `C:\`:

       <details>
         <summary>Файл `diskpart.txt`</summary>

         ```bash
         rem choose vol C where OS is stored
         sel vol C
         rem remove NoDefaultDriveLetter attribute from OS volume so it would be detected in WinPe without manual letter assignment
         attr vol clear nodefaultdriveletter
         ```
       </details>

       3.6. Чтобы отключить использование DHCP на сетевых интерфейсах, создайте файл `set_dhcp_disabled.ps1` в директории `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\`:

       <details>
         <summary>Файл `set_dhcp_disabled.ps1`</summary>

         ```bash
         #ps1_sysnative

         # set DHCP disabled on all network interfaces
         gci -Path HKLM:\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\ | Set-ItemProperty -Name EnableDhcp -Value 0

         # self delete this script
         Remove-Item $script:MyInvocation.MyCommand.Path -Force
         ```
       </details>

    4. Отключите механим защиты от подбора пароля `AllowAdministratorLockout`.
       Это исключит блокировку учетной записи пользователя в системе из-за подбора пароля или неудачных попыток авторизации.

       4.1. Создайте файл конфигурации `AllowAdministratorLockout.inf` в директории `C:\`.

       4.2. Добавьте в файл конфигурацию:

       ```bash
       [System Access]
       AllowAdministratorLockout = 0
       [Version]
       signature='$CHICAGO$'
       ```

       4.3. Примените файл конфигурации:

       ```bash
       secedit.exe /configure /db name.sdb /cfg C:\AllowAdministratorLockout.inf
       ```

       4.4. Удалите файл конфигурации `AllowAdministratorLockout.inf` в директории `C:\`.

    5. Настройте службу `OpenSSH Server`:

       5.1. Создайте файл конфигурации OpenSSH `sshd_config` в директории `C:\ProgramData\ssh\`.

       5.2. Добавьте в файл конфигурацию:

       <details>
         <summary>Файл `sshd_config`</summary>

         ```bash
         # This is the sshd server system-wide configuration file.  See
         # sshd_config(5) for more information.

         # The strategy used for options in the default sshd_config shipped with
         # OpenSSH is to specify options with their default value where
         # possible, but leave them commented.  Uncommented options override the
         # default value.

         #Port 22
         #AddressFamily any
         #ListenAddress 0.0.0.0
         #ListenAddress ::

         #HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
         #HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
         #HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
         #HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key

         # Ciphers and keying
         #RekeyLimit default none

         # Logging
         #SyslogFacility AUTH
         #LogLevel INFO

         # Authentication:

         #LoginGraceTime 2m
         #PermitRootLogin prohibit-password
         #StrictModes yes
         #MaxAuthTries 6
         #MaxSessions 10

         #PubkeyAuthentication yes

         # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
         # but this is overridden so installations will only check .ssh/authorized_keys
         AuthorizedKeysFile      .ssh/authorized_keys

         #AuthorizedPrincipalsFile none

         # For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
         #HostbasedAuthentication no
         # Change to yes if you don't trust ~/.ssh/known_hosts for
         # HostbasedAuthentication
         #IgnoreUserKnownHosts no
         # Don't read the user's ~/.rhosts and ~/.shosts files
         #IgnoreRhosts yes

         # To disable tunneled clear text passwords, change to no here!
         #PasswordAuthentication yes
         #PermitEmptyPasswords no

         # GSSAPI options
         #GSSAPIAuthentication no

         #AllowAgentForwarding yes
         #AllowTcpForwarding yes
         #GatewayPorts no
         #PermitTTY yes
         #PrintMotd yes
         #PrintLastLog yes
         #TCPKeepAlive yes
         #UseLogin no
         #PermitUserEnvironment no
         #ClientAliveInterval 0
         #ClientAliveCountMax 3
         #UseDNS no
         #PidFile /var/run/sshd.pid
         #MaxStartups 10:30:100
         #PermitTunnel no
         #ChrootDirectory none
         #VersionAddendum none

         # no default banner path
         #Banner none

         # override default of no subsystems
         Subsystem       sftp    sftp-server.exe

         # Example of overriding settings on a per-user basis
         #Match User anoncvs
         #       AllowTcpForwarding no
         #       PermitTTY no
         #       ForceCommand cvs server
         ```
       </details>

       5.3. Включите автозапуск OpenSSH при загрузке Windows:

       ```bash
       Set-Service -Name sshd -StartupType 'Automatic'
       ```

       5.4. Разрешите входящие подключения, для этого создайте правило в файрволе Windows:

       ```bash
       # SSH добавлен в firewall
       netsh advfirewall firewall add rule name="SSH server service" dir=in action=allow enable=yes protocol=TCP localport=22
       ```

    6. Чтобы сотрудники Selectel в рамках оказания технической поддержки могли проверить состояние сервера без его перезагрузки, включите поддержку монитора:

       ```bash
       powercfg.exe -x -monitor-timeout-ac 0
       powercfg.exe -x -monitor-timeout-dc 0
       ```

    7. Подготовьте систему к клонированию, для этого удалите уникальные данные из системы:

       ```bash
       C:\Windows\System32\Sysprep\Sysprep.exe /generalize /quiet
       ```

    8. Установите [`Python`](https://www.python.org/ftp/python/) версии `3.12.7` или выше.

    9. Обновите менеджер пакетов `Python` и установите необходимые пакеты:

       ```bash
       python -m ensurepip --upgrade
       python -m pip install --upgrade pip
       python -m pip install pywinauto
       python -m pip install logging
       ```

    10. Очистите кэш:

        10.1. Остановите сервисы обновления:

        ```bash
        net stop wuauserv
        net stop bits
        ```

        10.2. Удалите временные файлы:

        ```bash
        Remove-Item -Path "$env:TEMP\*" -Recurse -Force -ErrorAction SilentlyContinue
        ```

        10.3. Удалите кэш обновлений:

        ```bash
        Remove-Item -Path "C:\Windows\SoftwareDistribution\Download\*" -Recurse -Force -ErrorAction SilentlyContinue
        ```

        10.4. Очистите компонентное хранилище:

        ```bash
        Dism.exe /Online /Cleanup-Image /StartComponentCleanup /ResetBase
        ```

        10.5. Запустите службы обновления:

        ```bash
        net start wuauserv
        net start bits
        ```

    11. Создайте образ ОС в формате `.img`.
        Для создания образа мы рекомендуем использовать ПО, которое поддерживает создание образов дисков, например `Clonezilla`, `Macrium Reflect`, `DiskGenius`, `Acronis`, и не рекомендуем использовать встроенное средство резервного копирования Windows.

    12. Создайте архив с образом ОС:

        ```bash
        tar -czf base.tar.gz <img_name>
        ```

        Укажите `<img_name>` — имя образа ОС в формате `.img`, который вы создали на шаге 11.
  </TabItem>

  <TabItem value="vmware-esxi">
    <TabItemLabel>
      VMware ESXi
    </TabItemLabel>

    1. Опционально: вы можете самостоятельно подготовить файл `setup.tpl` — это скрипт, который применяет сетевые и системные настройки на этапе установки ОС и обеспечивает их сохранение после перезагрузки.

       Для VMware ESXi в механизме автоустановки ОС подготовлен шаблон `setup.tpl`, который будет использован, если вы не загрузите собственный скрипт в хранилище S3 вместе с архивом ISO-образа.

       1.1. На локальном компьютере создайте файл `setup.tpl`.

       1.2. Добавьте в файл текст скрипта:

       <details>
         <summary>Файл `setup.tpl`</summary>

         ```bash
         #!/bin/sh

         esxcli system hostname set --host="{{ userhostname }}"
         esxcli system account set -i root -p "{{ password }}" -c "{{ password }}"

         mkdir -p /etc/ssh/keys-root
         echo "" > /etc/ssh/keys-root/authorized_keys

         {% if user_ssh_key %}
         echo "{{ user_ssh_key }}" > /etc/ssh/keys-root/authorized_keys
         {% endif %}

         esxcli network ip dns server add --server=188.93.17.19
         esxcli network ip dns server add --server=188.93.16.19

         esxcli network ip interface ipv4 set -i vmk0 -I {{ ipv4_address }} -N {{ ipv4_netmask }} -t static
         esxcli network ip route ipv4 add -n default -g {{ ipv4_gateway }}

         cat << 'EOF' > /etc/rc.local.d/local.sh
         #!/bin/sh

         LOG="/var/log/local.sh.log"
         exec >> "$LOG" 2>&1

         echo "====================================================="
         echo "$(date) local.sh START"
         echo "====================================================="

         set -x

         TARGET_MAC="{{ local["boot_mac_address"] }}"
         VSWITCH="vSwitch0"

         TARGET_NIC="$(esxcli network nic list | awk -v mac="$TARGET_MAC" '$0 ~ mac {print $1; exit}')"
         CURRENT_UPLINKS="$(esxcli network vswitch standard list \
             | sed -n "/^${VSWITCH}\$/,/^$/p" \
             | sed -n 's/^[[:space:]]*Uplinks:[[:space:]]*//p' \
             | sed 's/,//g')"

         if [ -n "$TARGET_NIC" ] && { \
             [ "$(echo "$CURRENT_UPLINKS" | awk '{print NF}')" -ne 1 ] || \
             [ "$CURRENT_UPLINKS" != "$TARGET_NIC" ]; \
         }; then
             for nic in $CURRENT_UPLINKS; do
                 esxcli network vswitch standard uplink remove -u $nic -v $VSWITCH
             done
             esxcli network vswitch standard uplink add -u $TARGET_NIC -v $VSWITCH
         fi

         esxcli network nic down -n $TARGET_NIC
         sleep 1
         esxcli network nic up -n $TARGET_NIC
         sleep 1
         esxcli network ip interface set -e false -i vmk0
         sleep 1
         esxcli network ip interface set -e true -i vmk0
         sleep 5
         esxcli network vswitch standard portgroup policy failover set -p "Management Network" -a $TARGET_NIC

         /sbin/auto-backup.sh

         exit 0
         EOF

         /sbin/auto-backup.sh

         esxcli system maintenanceMode set --enable yes
         esxcli system shutdown poweroff -r "Provisioning complete" -d 10
         ```
       </details>

       1.3. Сохраните изменения в файле.

    2. Установите чистую VMware ESXi.
       Рекомендуем установить VMware ESXi в виртуальную машину с виртуальным диском минимально допустимого размера для выбранной версии ESXi, чтобы облегчить создание архива с образом ОС.

    3. Настройте статический IP-адрес на сетевом интерфейсе `vmk0`:

       ```bash
       esxcli network ip interface ipv4 set -i vmk0 -I 192.168.100.2 -N 255.255.255.0 -t static
       ```

       Здесь `192.168.100.2` — служебный IP-адрес для работы механизма автоустановки ОС.
       Убедитесь, что подсеть не используется в вашей инфраструктуре.
       Не изменяйте этот IP-адрес при подготовке образа.

    4. Включите службу SSH:

       ```bash
       vim-cmd hostsvc/enable_ssh
       vim-cmd hostsvc/start_ssh
       ```

    5. Включите консоль ESXi Shell с доступом через `DCUI`:

       ```bash
       vim-cmd hostsvc/enable_esx_shell
       vim-cmd hostsvc/start_esx_shell
       ```

    6. Добавьте публичный SSH-ключ для пользователя `root`:

       6.1. Откройте файл `/etc/ssh/keys-root/authorized_keys` текстовым редактором `vi`:

       ```bash
       vi /etc/ssh/keys-root/authorized_keys
       ```

       6.2. Добавьте в файл публичный SSH-ключ — это служебный ключ, который нужен в процессе развертывания образа для автоматической настройки и передачи `setup.tpl`.
       Не изменяйте этот ключ при подготовке образа.

       ```bash
       ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCQItiaAt3k6jkxglmD8cmWc20vDB2JTE3uonJYP9+6LhpM4m4HwCdLwyNuCzH0wBMA6ysEzdHhKUwC3dk0J8e7jUEQzJ/N70C0YIGEFOcjUeaeEf1DtO9q60eOyYoTFCwbuXx+tDax+Jh0k3OqbBitjW9m9FxQYRc3hmzaMrEhi3dfAtGlzVEkoK33x+kW9HDCMiBSQMI+iI6vwmdnpD9uvj4viYQCyCIT4k/gO6NpncHrY61AMQLD+AiQhqwiFZHAevbfIJ8DFND0QrIgFKhk2kaUka/qe8NvvScV2RfRWgTKtSy5tNFlU1vQtJJI+G7HNz+OhwORGPl/flLeSDri6upoJLKX8ZuQuGFIaJaUFf5Fi1skT6U4aLSq2f5FbNeDT9aerr5b9sLlfW6JiYXdESga3RVv2scyKAKVMro/l10dXf21x6y5E3SCPe3ogjopLMHnlDMkVKbG2A6xFI5G7eoqW9kVzzbYLe9/uEsmrnw7UAE7kQh1Rzm1N+gQCYk= autoinstall
       ```

       6.3. Выйдите из текстового редактора `vi` с сохранением изменений:

       ```bash
       :wq
       ```

    7. Опционально: внесите дополнительные изменения в систему, например установите дополнительное ПО, пакеты или выполните другие необходимые настройки для вашего образа.
       Убедитесь, что внесенные изменения не противоречат предыдущим шагам инструкции.

    8. Создайте архив с образом ОС.
       Например, вы можете сделать это в отдельной виртуальной машине с Linux.
       Для этого подключите системный диск ESXi к ВМ с Linux как блочное устройство.

       8.1. Создайте образ диска в формате `.img`:

       ```bash
       dd if=/dev/<disk_name> of=<img_name> bs=1M status=progress
       ```

       Укажите:

       * `<disk_name>` — имя системного диска ESXi, который подключен к ВМ с Linux;
       * `<img_name>` — имя образа в формате `.img`, например `esxi.img`.

       8.2. Создайте архив с образом ОС:

       ```bash
       tar -czvf base.tar.gz <img_name>
       ```

       Укажите `<img_name>` — имя образа ОС в формате `.img`, который вы создали на шаге 8.1.
  </TabItem>
</Tabs>

## 2. Загрузить образ в хранилище S3 \{#upload-image-to-s3}

Для загрузки архива с образом в хранилище S3 используйте инструкцию [Загрузить объект](/s3/objects/upload-object.mdx).

Если при [создании ISO-образа](#create-image) VMware ESXi вы подготовили файл `setul.tpl`, загрузите его в хранилище вместе с образом.

## 3. Получить ссылку на объект в хранилище \{#obtain-link-to-object}

Для получения ссылки на объект в хранилище S3 используйте инструкцию [Получить ссылку на объект](/s3/objects/obtain-link-to-object.mdx).

## 4. Добавить образ в панель управления \{#add-image-to-panel}

1. В [панели управления](https://my.selectel.ru/servers/default/servers/) в верхнем меню нажмите **Продукты** и выберите **Выделенные серверы**.

2. Перейдите в раздел **Образы**.

3. Нажмите **Добавить образ**.

4. Выберите семейство ОС.

5. Введите имя образа.

6. Добавьте ссылку на образ, который вы [загрузили на этапе 2 в хранилище S3](#upload-image-to-s3).

7. Если на шаге 6 в качестве ссылки вы добавили путь к образу в S3, введите **Access key** и **Secret key**.

8. Нажмите **Создать образ**.

<Formbricks />
