Предварительная версия. Функциональность может измениться, но основные возможности сохранятся. Совместимость с будущими версиями может потребовать ручных действий по миграции.

Введение

Данное руководство предназначено для пользователей Deckhouse Virtualization Platform и описывает порядок создания и изменения ресурсов, которые доступны для создания в проектах и пространствах имен кластера.

Быстрый старт по созданию ВМ

Пример создания виртуальной машины с Ubuntu 22.04.

  1. Создайте образ виртуальной машины из внешнего источника:

    1d8 k apply -f - <<EOF
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualImage
    4metadata:
    5  name: ubuntu
    6spec:
    7  storage: ContainerRegistry
    8  dataSource:
    9    type: HTTP
    10    http:
    11      url: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
    12EOF
    
  2. Создайте диск виртуальной машины из образа, созданного на предыдущем шаге (Внимание: перед созданием убедитесь, что в системе присутствует StorageClass по умолчанию):

    1d8 k apply -f - <<EOF
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualDisk
    4metadata:
    5  name: linux-disk
    6spec:
    7  dataSource:
    8    type: ObjectRef
    9    objectRef:
    10      kind: VirtualImage
    11      name: ubuntu
    12EOF
    
  3. Создайте виртуальную машину:

    В примере используется cloud-init-сценарий для создания пользователя cloud с паролем cloud, сгенерированный следующим образом:

    1mkpasswd --method=SHA-512 --rounds=4096
    

    Изменить имя пользователя и пароль можно в этой секции:

    1users:
    2  - name: cloud
    3    passwd: $6$rounds=4096$G5VKZ1CVH5Ltj4wo$g.O5RgxYz64ScD5Ach5jeHS.Nm/SRys1JayngA269wjs/LrEJJAZXCIkc1010PZqhuOaQlANDVpIoeabvKK4j1
    

    Создайте виртуальную машину из следующей спецификации:

    1d8 k apply -f - <<"EOF"
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualMachine
    4metadata:
    5  name: linux-vm
    6spec:
    7  virtualMachineClassName: host
    8  cpu:
    9    cores: 1
    10  memory:
    11    size: 1Gi
    12  provisioning:
    13    type: UserData
    14    userData: |
    15      #cloud-config
    16      ssh_pwauth: True
    17      users:
    18      - name: cloud
    19        passwd: '$6$rounds=4096$saltsalt$fPmUsbjAuA7mnQNTajQM6ClhesyG0.yyQhvahas02ejfMAq1ykBo1RquzS0R6GgdIDlvS.kbUwDablGZKZcTP/'
    20        shell: /bin/bash
    21        sudo: ALL=(ALL) NOPASSWD:ALL
    22        lock_passwd: False
    23  blockDeviceRefs:
    24    - kind: VirtualDisk
    25      name: linux-disk
    26EOF
    

    Полезные ссылки:

  4. Проверьте с помощью команды, что образ и диск созданы, а виртуальная машина - запущена. Ресурсы создаются не мгновенно, поэтому прежде чем они придут в готовое состояние потребуется подождать какое-то время.

    1d8 k  get vi,vd,vm
    

    Пример вывода:

    1NAME                                                 PHASE   CDROM   PROGRESS   AGE
    2virtualimage.virtualization.deckhouse.io/ubuntu      Ready   false   100%
    3#
    4NAME                                                 PHASE   CAPACITY   AGE
    5virtualdisk.virtualization.deckhouse.io/linux-disk   Ready   300Mi      7h40m
    6#
    7NAME                                                 PHASE     NODE           IPADDRESS     AGE
    8virtualmachine.virtualization.deckhouse.io/linux-vm  Running   virtlab-pt-2   10.66.10.2    7h46m
    
  5. Подключитесь с помощью консоли к виртуальной машине (для выхода из консоли необходимо нажать Ctrl+]):

    1d8 v console linux-vm
    

    Пример вывода:

    1Successfully connected to linux-vm console. The escape sequence is ^]
    2#
    3linux-vm login: cloud
    4Password: cloud
    5...
    6cloud@linux-vm:~$
    
  6. Для удаления созданных ранее ресурсов используйте следующие команды:

    1d8 k delete vm linux-vm
    2d8 k delete vd linux-disk
    3d8 k delete vi ubuntu
    

Образы

Ресурс VirtualImage предназначен для загрузки образов виртуальных машин и их последующего использования для создания дисков виртуальных машин. Данный ресурс доступен только в неймспейсе или проекте в котором он был создан.

При подключении к виртуальной машине доступ к образу предоставляется в режиме «только чтение».

Процесс создания образа включает следующие шаги:

  • Пользователь создаёт ресурс VirtualImage.
  • После создания образ автоматически загружается из указанного в спецификации источника в хранилище (DVCR).
  • После завершения загрузки, ресурс становится доступным для создания дисков.

Существуют различные типы образов:

  • ISO-образ — установочный образ, используемый для начальной установки операционной системы. Такие образы выпускаются производителями ОС и используются для установки на физические и виртуальные серверы.
  • Образ диска с предустановленной системой — содержит уже установленную и настроенную операционную систему, готовую к использованию после создания виртуальной машины. Готовые образы можно получить на ресурсах разработчиков дистрибутива, либо создать самостоятельно.

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

Поддерживаются следующие форматы образов с предустановленной системой:

  • qcow2
  • raw
  • vmdk
  • vdi

Также файлы образов могут быть сжаты одним из следующих алгоритмов сжатия: gz, xz.

После создания ресурса, тип и размер образа определяются автоматически и эта информация отражается в статусе ресурса.

Образы могут быть загружены из различных источников, таких как HTTP-серверы, где расположены файлы образов, или контейнерные реестры. Также доступна возможность загрузки образов напрямую из командной строки с использованием утилиты curl.

Образы могут быть созданы из других образов и дисков виртуальных машин.

Проектный образ поддерживает два варианта хранения:

  • ContainerRegistry - тип по умолчанию, при котором образ хранится в DVCR.
  • PersistentVolumeClaim - тип, при котором в качестве хранилища для образа используется PVC. Этот вариант предпочтителен, если используется хранилище с поддержкой быстрого клонирования PVC, что позволяет быстрее создавать диски из образов.

С полным описанием параметров конфигурации ресурса VirtualImage можно ознакомиться в документации к ресурсу.

Создание образа с HTTP-сервера

Рассмотрим вариант создания образа с вариантом хранения в DVCR.

  1. Выполните следующую команду для создания VirtualImage:

    1d8 k apply -f - <<EOF
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualImage
    4metadata:
    5  name: ubuntu-22-04
    6spec:
    7  # Сохраним образ в DVCR.
    8  storage: ContainerRegistry
    9  # Источник для создания образа.
    10  dataSource:
    11    type: HTTP
    12    http:
    13      url: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
    14EOF
    
  2. Проверьте результат создания VirtualImage:

    1d8 k get virtualimage ubuntu-22-04
    2# или более короткий вариант
    3d8 k get vi ubuntu-22-04
    

    Пример вывода:

    1NAME           PHASE   CDROM   PROGRESS   AGE
    2ubuntu-22-04   Ready   false   100%       23h
    

После создания ресурс VirtualImage может находиться в следующих состояниях (фазах):

  • Pending - ожидание готовности всех зависимых ресурсов, требующихся для создания образа.
  • WaitForUserUpload - ожидание загрузки образа пользователем (фаза присутствует только для type=Upload).
  • Provisioning - идет процесс создания образа.
  • Ready - образ создан и готов для использования.
  • Failed - произошла ошибка в процессе создания образа.
  • Terminating - идет процесс удаления Образа. Образ может «зависнуть» в данном состоянии, если он еще подключен к виртуальной машине.

До тех пор пока образ не перешёл в фазу Ready, содержимое всего блока .spec допускается изменять. При изменении процесс создании диска запустится заново. После перехода в фазу Ready содержимое блока .spec менять нельзя!

Диагностика проблем с ресурсом осуществляется путем анализа информации в блоке .status.conditions.

Отследить процесс создания образа можно путем добавления ключа -w к предыдущей команде:

1d8 k get vi ubuntu-22-04 -w

Пример вывода:

1NAME           PHASE          CDROM   PROGRESS   AGE
2ubuntu-22-04   Provisioning   false              4s
3ubuntu-22-04   Provisioning   false   0.0%       4s
4ubuntu-22-04   Provisioning   false   28.2%      6s
5ubuntu-22-04   Provisioning   false   66.5%      8s
6ubuntu-22-04   Provisioning   false   100.0%     10s
7ubuntu-22-04   Provisioning   false   100.0%     16s
8ubuntu-22-04   Ready          false   100%       18s

В описание ресурса VirtualImage можно получить дополнительную информацию о скачанном образе:

1d8 k describe vi ubuntu-22-04

Теперь рассмотрим пример создания образа с хранением его в PVC:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualImage
4metadata:
5  name: ubuntu-22-04-pvc
6spec:
7  # Настройки хранения проектного образа.
8  storage: PersistentVolumeClaim
9  persistentVolumeClaim:
10    # Подставьте ваше название StorageClass.
11    storageClassName: i-sds-replicated-thin-r2
12  # Источник для создания образа.
13  dataSource:
14    type: HTTP
15    http:
16      url: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
17EOF

Проверьте результат создания VirtualImage:

1d8 k get vi ubuntu-22-04-pvc

Пример вывода:

1NAME              PHASE   CDROM   PROGRESS   AGE
2ubuntu-22-04-pvc  Ready   false   100%       23h

Если параметр .spec.persistentVolumeClaim.storageClassName не указан, то будет использован StorageClass по умолчанию на уровне кластера, либо для образов, если он указан в настройках модуля.

Создание образа из Container Registry

Образ, хранящийся в Container Registry, имеет определенный формат. Рассмотрим на примере:

  1. Загрузите образ локально:

    1curl -L https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img -o ubuntu2204.img
    
  2. Создайте Dockerfile со следующим содержимым:

    1FROM scratch
    2COPY ubuntu2204.img /disk/ubuntu2204.img
    
  3. Соберите образ и загрузите его в container registry. В качестве container registry в примере ниже использован docker.io. Для выполнения необходимо иметь учетную запись сервиса и настроенное окружение.

    1docker build -t docker.io/<username>/ubuntu2204:latest
    

    где username — имя пользователя, указанное при регистрации в docker.io.

  4. Загрузите созданный образ в container registry:

    1docker push docker.io/<username>/ubuntu2204:latest
    
  5. Чтобы использовать этот образ, создайте в качестве примера ресурс:

    1d8 k apply -f - <<EOF
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualImage
    4metadata:
    5  name: ubuntu-2204
    6spec:
    7  storage: ContainerRegistry
    8  dataSource:
    9    type: ContainerImage
    10    containerImage:
    11      image: docker.io/<username>/ubuntu2204:latest
    12EOF
    

Загрузка образа из командной строки

Чтобы загрузить образ из командной строки, предварительно создайте ресурс, как представлено ниже на примере VirtualImage:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualImage
4metadata:
5  name: some-image
6spec:
7  # Настройки хранения проектного образа.
8  storage: ContainerRegistry
9  # Настройки источника образа.
10  dataSource:
11    type: Upload
12EOF

После создания, ресурс перейдет в фазу WaitForUserUpload, а это значит, что он готов для загрузки образа.

Доступно два варианта загрузки с узла кластера и с произвольного узла за пределами кластера:

1d8 k get vi some-image -o jsonpath="{.status.imageUploadURLs}"  | jq

Пример вывода:

1{
2  "external":"https://virtualization.example.com/upload/g2OuLgRhdAWqlJsCMyNvcdt4o5ERIwmm",
3  "inCluster":"http://10.222.165.239/upload"
4}

В качестве примера загрузите образ Cirros:

1curl -L http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img -o cirros.img

Выполните загрузку образа с использование следующей команды

1curl https://virtualization.example.com/upload/g2OuLgRhdAWqlJsCMyNvcdt4o5ERIwmm --progress-bar -T cirros.img | cat

После завершения загрузки образ должен быть создан и перейти в фазу Ready

1d8 k get vi some-image

Пример вывода:

1NAME         PHASE   CDROM   PROGRESS   AGE
2some-image   Ready   false   100%       1m

Создание образа из диска

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

  • Диск не подключен ни к одной из виртуальных машин.
  • Виртуальная машина, к которой подключен диск, находится в выключенном состоянии.

Пример создания образа из диска:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualImage
4metadata:
5  name: linux-vm-root
6spec:
7  storage: ContainerRegistry
8  dataSource:
9    type: ObjectRef
10    objectRef:
11      kind: VirtualDisk
12      name: linux-vm-root
13EOF

Создание образа из снимка диска

Можно создать образ из снимка. Для этого необходимо чтобы снимок диска находился в фазе готовности.

Пример создания образа из моментального снимка диска:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualImage
4metadata:
5  name: linux-vm-root
6spec:
7  storage: ContainerRegistry
8  dataSource:
9    type: ObjectRef
10    objectRef:
11      kind: VirtualDiskSnapshot
12      name: linux-vm-root-snapshot
13EOF

Диски

Диски в виртуальных машинах необходимы для записи и хранения данных, они обеспечивают полноценное функционирование приложений и операционных систем. Хранилище для этих дисков предоставляет платформа.

В зависимости от свойств хранилища, поведение дисков при создании и виртуальных машин в процессе эксплуатации может отличаться:

Свойство VolumeBindingMode:

Immediate - Диск создается сразу после создания ресурса (предполагается, что диск будет доступен для подключения к виртуальной машине на любом узле кластера).

WaitForFirstConsumer - Диск создается только после того как будет подключен к виртуальной машине и будет создан на том узле, на котором будет запущена виртуальная машина.

Режим доступа AccessMode:

  • ReadWriteOnce (RWO) - доступ к диску предоставляется только одному экземпляру виртуальной машины. Живая миграция виртуальных машин с такими дисками невозможна.
  • ReadWriteMany (RWX) - множественный доступ к диску. Живая миграция виртуальных машин с такими дисками возможна.

При создании диска контроллер самостоятельно определит наиболее оптимальные параметры поддерживаемые хранилищем.

Внимание: Создать диски из iso-образов - нельзя!

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

1d8 k  get storageclass

Пример вывода:

1NAME                                 PROVISIONER                           RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
2i-sds-replicated-thin-r1 (default)   replicated.csi.storage.deckhouse.io   Delete          Immediate              true                   48d
3i-sds-replicated-thin-r2             replicated.csi.storage.deckhouse.io   Delete          Immediate              true                   48d
4i-sds-replicated-thin-r3             replicated.csi.storage.deckhouse.io   Delete          Immediate              true                   48d
5sds-replicated-thin-r1               replicated.csi.storage.deckhouse.io   Delete          WaitForFirstConsumer   true                   48d
6sds-replicated-thin-r2               replicated.csi.storage.deckhouse.io   Delete          WaitForFirstConsumer   true                   48d
7sds-replicated-thin-r3               replicated.csi.storage.deckhouse.io   Delete          WaitForFirstConsumer   true                   48d
8nfs-4-1-wffc                         nfs.csi.k8s.io                        Delete          WaitForFirstConsumer   true                   30d

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

Создание пустого диска

Пустые диски обычно используются для установки на них ОС, либо для хранения каких-либо данных.

Создайте диск:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualDisk
4metadata:
5  name: blank-disk
6spec:
7  # Настройки параметров хранения диска.
8  persistentVolumeClaim:
9    # Подставьте ваше название StorageClass.
10    storageClassName: i-sds-replicated-thin-r2
11    size: 100Mi
12EOF

После создания ресурс VirtualDisk может находиться в следующих состояниях (фазах):

  • Pending - ожидание готовности всех зависимых ресурсов, требующихся для создания диска.
  • Provisioning - идет процесс создания диска.
  • Resizing - идет процесс изменения размера диска.
  • WaitForFirstConsumer - диск ожидает создания виртуальной машины, которая будет его использовать.
  • WaitForUserUpload - диск ожидает от пользователя загрузки образа (type: Upload).
  • Ready - диск создан и готов для использования.
  • Failed - произошла ошибка в процессе создания.
  • PVCLost - системная ошибка, PVC с данными утерян.
  • Terminating - идет процесс удаления диска. Диск может «зависнуть» в данном состоянии, если он еще подключен к виртуальной машине.

До тех пор пока диск не перешёл в фазу Ready содержимое всего блока .spec допускается изменять. При изменении процесс создании диска запустится заново.

Диагностика проблем с ресурсом осуществляется путем анализа информации в блоке .status.conditions.

Если параметр .spec.persistentVolumeClaim.storageClassName не указан, то будет использован StorageClass по умолчанию на уровне кластера, либо для образов, если он указан в настройках модуля.

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

1d8 k get vd blank-disk

Пример вывода:

1NAME       PHASE   CAPACITY   AGE
2blank-disk   Ready   100Mi      1m2s

Создание диска из образа

Диск также можно создавать и заполнять данными из ранее созданных образов ClusterVirtualImage и VirtualImage.

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

На примере ранее созданного проектного образа VirtualImage, рассмотрим команду позволяющую определить размер распакованного образа:

1d8 k get cvi ubuntu-22-04 -o wide

Пример вывода:

1NAME           PHASE   CDROM   PROGRESS   STOREDSIZE   UNPACKEDSIZE   REGISTRY URL                                                                       AGE
2ubuntu-22-04   Ready   false   100%       285.9Mi      2.5Gi          dvcr.d8-virtualization.svc/cvi/ubuntu-22-04:eac95605-7e0b-4a32-bb50-cc7284fd89d0   122m

Искомый размер указан в колонке UNPACKEDSIZE и равен 2.5Gi.

Создадим диск из этого образа:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualDisk
4metadata:
5  name: linux-vm-root
6spec:
7  # Настройки параметров хранения диска.
8  persistentVolumeClaim:
9    # Укажем размер больше чем значение распакованного образа.
10    size: 10Gi
11    # Подставьте ваше название StorageClass.
12    storageClassName: i-sds-replicated-thin-r2
13  # Источник из которого создается диск.
14  dataSource:
15    type: ObjectRef
16    objectRef:
17      kind: VirtualImage
18      name: ubuntu-22-04
19EOF

А теперь создайте диск, без явного указания размера:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualDisk
4metadata:
5  name: linux-vm-root-2
6spec:
7  # Настройки параметров хранения диска.
8  persistentVolumeClaim:
9    # Подставьте ваше название StorageClass.
10    storageClassName: i-sds-replicated-thin-r2
11  # Источник из которого создается диск.
12  dataSource:
13    type: ObjectRef
14    objectRef:
15      kind: VirtualImage
16      name: ubuntu-22-04
17EOF

Проверьте состояние дисков после создания:

1d8 k get vd

Пример вывода:

1NAME           PHASE   CAPACITY   AGE
2linux-vm-root    Ready   10Gi       7m52s
3linux-vm-root-2  Ready   2590Mi     7m15s

Изменение размера диска

Размер дисков можно увеличивать, даже если они уже подключены к работающей виртуальной машине. Для этого отредактируйте поле spec.persistentVolumeClaim.size:

Проверьте размер до изменения:

1d8 k get vd linux-vm-root

Пример вывода:

1NAME          PHASE   CAPACITY   AGE
2linux-vm-root   Ready   10Gi       10m

Примените изменения:

1d8 k patch vd linux-vm-root --type merge -p '{"spec":{"persistentVolumeClaim":{"size":"11Gi"}}}'

Проверьте размер после изменения:

1d8 k get vd linux-vm-root

Пример вывода:

1NAME          PHASE   CAPACITY   AGE
2linux-vm-root   Ready   11Gi       12m

Виртуальные машины

Для создания виртуальной машины используется ресурс VirtualMachine. Его параметры позволяют сконфигурировать:

  • класс виртуальной машины
  • ресурсы, требуемые для работы виртуальной машины (процессор, память, диски и образы);
  • правила размещения виртуальной машины на узлах кластера;
  • настройки загрузчика и оптимальные параметры для гостевой ОС;
  • политику запуска виртуальной машины и политику применения изменений;
  • сценарии начальной конфигурации (cloud-init);
  • перечень блочных устройств.

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

Создание виртуальной машины

Ниже представлен пример конфигурации виртуальной машины, запускающей ОС Ubuntu 22.04. В примере используется сценарий первичной инициализации виртуальной машины (cloud-init), который устанавливает гостевого агента qemu-guest-agent и сервис nginx, а также создает пользователя cloud с паролем cloud:

Пароль в примере был сгенерирован с использованием команды mkpasswd --method=SHA-512 --rounds=4096 -S saltsalt и при необходимости вы можете его поменять на свой:

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

1d8 k apply -f - <<"EOF"
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachine
4metadata:
5  name: linux-vm
6spec:
7  # Название класса ВМ.
8  virtualMachineClassName: host
9  # Блок скриптов первичной инициализации ВМ.
10  provisioning:
11    type: UserData
12    # Пример cloud-init-сценария для создания пользователя cloud с паролем cloud и установки сервиса агента qemu-guest-agent и сервиса nginx.
13    userData: |
14      #cloud-config
15      package_update: true
16      packages:
17        - nginx
18        - qemu-guest-agent
19      run_cmd:
20        - systemctl daemon-reload
21        - systemctl enable --now nginx.service
22        - systemctl enable --now qemu-guest-agent.service
23      ssh_pwauth: True
24      users:
25      - name: cloud
26        passwd: '$6$rounds=4096$saltsalt$fPmUsbjAuA7mnQNTajQM6ClhesyG0.yyQhvahas02ejfMAq1ykBo1RquzS0R6GgdIDlvS.kbUwDablGZKZcTP/'
27        shell: /bin/bash
28        sudo: ALL=(ALL) NOPASSWD:ALL
29        lock_passwd: False
30      final_message: "The system is finally up, after $UPTIME seconds"
31  # Настройки ресурсов ВМ.
32  cpu:
33    # Количество ядер ЦП.
34    cores: 1
35    # Запросить 10% процессорного времени одного физического ядра.
36    coreFraction: 10%
37  memory:
38    # Объем оперативной памяти.
39    size: 1Gi
40  # Список дисков и образов, используемых в ВМ.
41  blockDeviceRefs:
42    # Порядок дисков и образов в данном блоке определяет приоритет загрузки.
43    - kind: VirtualDisk
44      name: linux-vm-root
45EOF

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

1d8 k get vm linux-vm

Пример вывода:

1NAME        PHASE     NODE           IPADDRESS     AGE
2linux-vm   Running   virtlab-pt-2   10.66.10.12   11m

После создания виртуальная машина автоматически получит IP-адрес из диапазона, указанного в настройках модуля (блок virtualMachineCIDRs).

Жизненный цикл виртуальной машины

Виртуальная машина (ВМ) проходит через несколько этапов своего существования — от создания до удаления. Эти этапы называются фазами и отражают текущее состояние ВМ. Чтобы понять, что происходит с ВМ, нужно проверить её статус (поле .status.phase), а для более детальной информации — блок .status.conditions. Ниже описаны все основные фазы жизненного цикла ВМ, их значение и особенности.

  • Pending - ожидание готовности ресурсов

    ВМ только что создана, перезапущена или запущена после остановки и ожидает готовности необходимых ресурсов (дисков, образов, ip-адресов и т.д.).

    • Возможные проблемы:

      • не готовы зависимые ресурсы: диски, образы, классы ВМ, секрет со сценарием начальной конфигурации и пр.
    • Диагностика: В .status.conditions стоит обратить внимание на условия *Ready. По ним можно определить, что блокирует переход к следующей фазе, например, ожидание готовности дисков (BlockDevicesReady) или класса ВМ (VirtualMachineClassReady).

      1d8 k get vm <vm-name> -o json | jq '.status.conditions[] | select(.type | test(".*Ready"))'
      
  • Starting - запуск виртуальной машины

    Все зависимые ресурсы ВМ - готовы, и система пытается запустить ВМ на одном из узлов кластера.

    • Возможные проблемы:

      • Нет подходящего узла для запуска.
      • На подходящих узлах недостаточно CPU или памяти.
      • Превышены квоты неймспейса или проекта.
    • Диагностика:

      • Если запуск затягивается, проверьте .status.conditions, условие type: Running
      1d8 k get vm <vm-name> -o json | jq '.status.conditions[] | select(.type=="Running")'
      
  • Running - виртуальная машина запущена

    ВМ успешно запущена и работает.

    • Особенности:

      • При установленном в гостевой системе qemu-guest-agent, условие AgentReady будет истинно,а в .status.guestOSInfo будет отображена информация о запущенной гостевой ОС.
      • Условие type: FirmwareUpToDate, status: False информирует о том, что прошивку ВМ требуется обновить.
      • Условие type: ConfigurationApplied, status: False информирует о том, что конфигурация ВМ не применена для запущенной ВМ.
      • Условие type: AwaitingRestartToApplyConfiguration, status: True отображает информацию о необходимости выполнить вручную перезагрузку ВМ, т.к. некоторые изменения конфигурации невозможно применить без перезагрузки ВМ.
    • Возможные проблемы:

      • Внутренний сбой в работе ВМ или гипервизора.
    • Диагностика:

      • Проверьте .status.conditions, условие type: Running
      1d8 k get vm <vm-name> -o json | jq '.status.conditions[] | select(.type=="Running")'
      
  • Stopping - ВМ останавливается или перезагружается

  • Stopped - ВМ остановлена и не потребляет вычислительные ресурсы

  • Terminating - ВМ удаляется.

    Данная фаза необратима. Все связанные с ВМ ресурсы освобождаются, но не удаляются автоматически.

  • Migrating - живая миграция ВМ

    ВМ переносится на другой узел кластера (живая миграция).

    • Особенности:
      • Миграция ВМ поддерживается только для нелокальных дисков, условие type: Migratable отображает информацию о том может ли ВМ мигрировать или нет.
    • Возможные проблемы:
      • Несовместимость процессорных инструкций (при использовании типов процессоров host или host-passthrough).
      • Различие версиях ядер на узлах гипервизоров.
      • На подходящих узлах недостаточно CPU или памяти.
      • Превышены квоты неймспейса или проекта.
    • Диагностика:
      • Проверьте .status.conditions условие type: Migrating, а также блок .status.migrationState
    1d8 k get vm <vm-name> -o json | jq '.status | {condition: .conditions[] | select(.type=="Migrating"), migrationState}'
    

Условие type: SizingPolicyMatched, status: False отображает несоответствие конфигурации ресурсов политике сайзинга используемого VirtualMachineClass. При нарушении политики сохранить параметры ВМ без приведения ресурсов в соответствие политике - невозможно.

Условия отображают информацию о состоянии ВМ, а также на возникающие проблемы. Понять, что не так с ВМ можно путем их анализа:

1d8 k get vm fedora -o json | jq '.status.conditions[] | select(.message != "")'

Агент гостевой ОС

Для повышения эффективности управления ВМ рекомендуется установить QEMU Guest Agent — инструмент, который обеспечивает взаимодействие между гипервизором и операционной системой внутри ВМ.

Чем поможет агент?

  • Обеспечит создание консистентных снимков дисков и ВМ.

  • Позволит получать информацию о работающей ОС, которая будет отражена в статусе ВМ. Пример:

    1status:
    2  guestOSInfo:
    3    id: fedora
    4    kernelRelease: 6.11.4-301.fc41.x86_64
    5    kernelVersion: '#1 SMP PREEMPT_DYNAMIC Sun Oct 20 15:02:33 UTC 2024'
    6    machine: x86_64
    7    name: Fedora Linux
    8    prettyName: Fedora Linux 41 (Cloud Edition)
    9    version: 41 (Cloud Edition)
    10    versionId: "41"
    
  • Позволит отслеживать, что ОС действительно загрузилась:

    1d8 k get vm -o wide
    

    Пример вывода (колонка AGENT):

    1NAME     PHASE     CORES   COREFRACTION   MEMORY   NEED RESTART   AGENT   MIGRATABLE   NODE           IPADDRESS    AGE
    2fedora   Running   6       5%             8000Mi   False          True    True         virtlab-pt-1   10.66.10.1   5d21h
    

Как установить QEMU Guest Agent:

Для Debian-based ОС:

1sudo apt install qemu-guest-agent

Для Centos-based ОС:

1sudo yum install qemu-guest-agent

Запуск службы агента:

1sudo systemctl enable --now qemu-guest-agent

Автоматическая конфигурация топологии CPU

Топология CPU виртуальной машины (ВМ) определяет, как ядра процессора распределяются по сокетам. Это важно для обеспечения оптимальной производительности и совместимости с приложениями, которые могут зависеть от конфигурации процессора. В конфигурации ВМ вы задаете только общее количество ядер процессора, а топология (количество сокетов и ядер в каждом сокете) рассчитывается автоматически на основе этого значения.

Количество ядер процессора указывается в конфигурации ВМ следующим образом:

1spec:
2  cpu:
3    cores: 1

Далее система автоматически определяет топологию в зависимости от заданного числа ядер. Правила расчета зависят от диапазона количества ядер и описаны ниже.

  • Если количество ядер от 1 до 16 (1 ≤ .spec.cpu.cores ≤ 16):
    • Используется 1 сокет.
    • Количество ядер в сокете равно заданному значению.
    • Шаг изменения: 1 (можно увеличивать или уменьшать количество ядер по одному).
    • Допустимые значения: любое целое число от 1 до 16 включительно.
    • Пример: Если задано .spec.cpu.cores = 8, то топология: 1 сокет с 8 ядрами.
  • Если количество ядер от 17 до 32 (16 < .spec.cpu.cores ≤ 32):
    • Используется 2 сокета.
    • Ядра равномерно распределяются между сокетами (количество ядер в каждом сокете одинаковое).
    • Шаг изменения: 2 (общее количество ядер должно быть четным).
    • Допустимые значения: 18, 20, 22, 24, 26, 28, 30, 32.
    • Ограничения: минимум 9 ядер в сокете, максимум 16 ядер в сокете.
    • Пример: Если задано .spec.cpu.cores = 20, то топология: 2 сокета по 10 ядер каждый.
  • Если количество ядер от 33 до 64 (32 < .spec.cpu.cores ≤ 64):
    • Используется 4 сокета.
    • Ядра равномерно распределяются между сокетами.
    • Шаг изменения: 4 (общее количество ядер должно быть кратно 4).
    • Допустимые значения: 36, 40, 44, 48, 52, 56, 60, 64.
    • Ограничения: минимум 9 ядер в сокете, максимум 16 ядер в сокете.
    • Пример: Если задано .spec.cpu.cores = 40, то топология: 4 сокета по 10 ядер каждый.
  • Если количество ядер больше 64 (.spec.cpu.cores > 64):
    • Используется 8 сокетов.
    • Ядра равномерно распределяются между сокетами.
    • Шаг изменения: 8 (общее количество ядер должно быть кратно 8).
    • Допустимые значения: 72, 80, 88, 96 и так далее до 248
    • Ограничения: минимум 9 ядер в сокете.
    • Пример: Если задано .spec.cpu.cores = 80, то топология: 8 сокетов по 10 ядер каждый.

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

Максимально возможное количество ядер - 248.

Текущая топология ВМ (количество сокетов и ядер в каждом сокете) отображается в статусе ВМ в следующем формате:

1status:
2  resources:
3    cpu:
4      coreFraction: 10%
5      cores: 1
6      requestedCores: "1"
7      runtimeOverhead: "0"
8      topology:
9        sockets: 1
10        coresPerSocket: 1

Подключение к виртуальной машине

Для подключения к виртуальной машине доступны следующие способы:

  • протокол удаленного управления (например SSH), который должен быть предварительно настроен на виртуальной машине.
  • серийная консоль (serial console).
  • протокол VNC.

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

1d8 v console linux-vm

Пример вывода:

1Successfully connected to linux-vm console. The escape sequence is ^]
2linux-vm login: cloud
3Password: cloud

Нажмите Ctrl+] для завершения работы с серийной консолью.

Пример команды для подключения по VNC:

1d8 v vnc linux-vm

Пример команды для подключения по SSH:

1d8 v ssh cloud@linux-vm --local-ssh

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

Политика запуска виртуальной машины предназначена для автоматизированного управления состоянием виртуальной машины. Определяется она в виде параметра .spec.runPolicy в спецификации виртуальной машины. Поддерживаются следующие политики:

  • AlwaysOnUnlessStoppedManually - (по умолчанию) после создания ВМ всегда находится в запущенном состоянии. В случае сбоев работа ВМ восстанавливается автоматически. Остановка ВМ возможно только путем вызова команды d8 v stop или создания соответствующей операции.
  • AlwaysOn - после создания ВМ всегда находится в работающем состоянии, даже в случае ее выключения средствами ОС. В случае сбоев работа ВМ восстанавливается автоматически.
  • Manual - после создания состоянием ВМ управляет пользователь вручную с использованием команд или операций.
  • AlwaysOff - после создания ВМ всегда находится в выключенном состоянии. Возможность включения ВМ через команды\операции - отсутствует.

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

  • Создание ресурса VirtualMachineOperation (vmop).
  • Использование утилиты d8 с соответствующей подкомандой.

Ресурс VirtualMachineOperation декларативно определяет императивное действие, которое должно быть выполнено на виртуальной машине. Это действие применяется к виртуальной машине сразу после создания соответствующего vmop. Действие применяется к виртуальной машине один раз.

Пример операции для выполнения перезагрузки виртуальной машины с именем linux-vm:

1d8 k create -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineOperation
4metadata:
5  generateName: restart-linux-vm-
6spec:
7  virtualMachineName: linux-vm
8  # Тип применяемой операции = применяемая операция.
9  type: Restart
10EOF

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

1d8 k get virtualmachineoperation
2# или
3d8 k get vmop

Аналогичное действие можно выполнить с использованием утилиты d8:

1d8 v restart linux-vm

Перечень возможных операций приведен в таблице ниже:

d8 vmop type Действие
d8 v stop Stop Остановить ВМ
d8 v start Start Запустить ВМ
d8 v restart Restart Перезапустить ВМ
d8 v evict Evict Мигрировать ВМ на другой узел

Изменение конфигурации виртуальной машины

Конфигурацию виртуальной машины можно изменять в любое время после создания ресурса VirtualMachine. Однако то, как эти изменения будут применены, зависит от текущей фазы виртуальной машины и характера внесённых изменений.

Изменения в конфигурацию виртуальной машины можно внести с использованием следующей команды:

1d8 k edit vm linux-vm

Если виртуальная машина находится в выключенном состоянии (.status.phase: Stopped), внесённые изменения вступят в силу сразу после её запуска.

Если виртуальная машина работает (.status.phase: Running), то способ применения изменений зависит от их типа:

Блок конфигурации Как применяется
.metadata.labels Сразу
.metadata.annotations Сразу
.spec.liveMigrationPolicy Сразу
.spec.runPolicy Сразу
.spec.disruptions.restartApprovalMode Сразу
.spec.affinity EE, SE+ : Сразу, CE: Требуется перезапуск ВМ
.spec.nodeSelector EE, SE+ : Сразу, CE: Требуется перезапуск ВМ
.spec.* Требуется перезапуск ВМ

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

Предположим, мы хотим изменить количество ядер процессора. В данный момент виртуальная машина запущена и использует одно ядро, что можно подтвердить, подключившись к ней через серийную консоль и выполнив команду nproc.

1d8 v ssh cloud@linux-vm --local-ssh --command "nproc"

Пример вывода:

11

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

1d8 k patch vm linux-vm --type merge -p '{"spec":{"cpu":{"cores":2}}}'

Пример вывода:

1# virtualmachine.virtualization.deckhouse.io/linux-vm patched

Изменения в конфигурации внесены, но ещё не применены к виртуальной машине. Проверьте это, повторно выполнив:

1d8 v ssh cloud@linux-vm --local-ssh --command "nproc"

Пример вывода:

11

Для применения этого изменения необходим перезапуск виртуальной машины. Выполните следующую команду, чтобы увидеть изменения, ожидающие применения (требующие перезапуска):

1d8 k get vm linux-vm -o jsonpath="{.status.restartAwaitingChanges}" | jq .

Пример вывода:

1[
2  {
3    "currentValue": 1,
4    "desiredValue": 2,
5    "operation": "replace",
6    "path": "cpu.cores"
7  }
8]

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

1d8 k get vm linux-vm -o wide

Пример вывода:

1NAME        PHASE     CORES   COREFRACTION   MEMORY   NEED RESTART   AGENT   MIGRATABLE   NODE           IPADDRESS     AGE
2linux-vm    Running   2       100%           1Gi      True           True    True         virtlab-pt-1   10.66.10.13   5m16s

В колонке NEED RESTART мы видим значение True, а это значит что для применения изменений требуется перезагрузка.

Выполните перезагрузку виртуальной машины:

1d8 v restart linux-vm

После перезагрузки изменения будут применены и блок .status.restartAwaitingChanges будет пустой.

Выполните команду для проверки:

1d8 v ssh cloud@linux-vm --local-ssh --command "nproc"

Пример вывода:

12

Порядок применения изменений виртуальной машины через «ручной» рестарт является поведением по умолчанию. Если есть необходимость применять внесенные изменения сразу и автоматически, для этого нужно изменить политику применения изменений:

1spec:
2  disruptions:
3    restartApprovalMode: Automatic

Сценарии начальной инициализации

Сценарии начальной инициализации предназначены для первичной конфигурации виртуальной машины при её запуске.

В качестве сценариев начальной инициализации поддерживаются:

Сценарий CloudInit можно встраивать непосредственно в спецификацию виртуальной машины, но этот сценарий ограничен максимальной длиной в 2048 байт:

1spec:
2  provisioning:
3    type: UserData
4    userData: |
5      #cloud-config
6      package_update: true
7      ...

При более длинных сценариях и/или наличия приватных данных, сценарий начальной инициализации виртуальной машины может быть создан в ресурсе Secret. Пример ресурса Secret со сценарием CloudInit приведен ниже:

1apiVersion: v1
2kind: Secret
3metadata:
4  name: cloud-init-example
5data:
6  userData: <base64 data>
7type: provisioning.virtualization.deckhouse.io/cloud-init

фрагмент конфигурации виртуальной машины с при использовании скрипта начальной инициализации CloudInit хранящегося в ресурсе Secret:

1spec:
2  provisioning:
3    type: UserDataRef
4    userDataRef:
5      kind: Secret
6      name: cloud-init-example

Примечание: Значение поля .data.userData должно быть закодировано в формате Base64.

Для конфигурирования виртуальных машин под управлением ОС Windows с использованием Sysprep, поддерживается только вариант с ресурсом Secret.

Пример ресурса Secret с сценарием Sysprep приведен ниже:

1apiVersion: v1
2kind: Secret
3metadata:
4  name: sysprep-example
5data:
6  unattend.xml: <base64 data>
7type: provisioning.virtualization.deckhouse.io/sysprep

Примечание: Значение поля .data.unattend.xml должно быть закодировано в формате Base64.

фрагмент конфигурации виртуальной машины с использованием скрипта начальной инициализации Sysprep в ресурсе Secret:

1spec:
2  provisioning:
3    type: SysprepRef
4    sysprepRef:
5      kind: Secret
6      name: sysprep-example

Размещение ВМ по узлам

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

  • Простое связывание по меткам (nodeSelector).
  • Предпочтительное связывание (Affinity).
  • Избежание совместного размещения (AntiAffinity).

Параметры размещения виртуальных машин можно изменить в реальном времени (доступно только в Enterprise-редакции). Однако, если новые параметры размещения не совпадают с текущими, виртуальная машина будет перемещена на узлы, соответствующие новым требованиям.

Простое связывание по меткам (nodeSelector)

nodeSelector — это простейший способ контролировать размещение виртуальных машин, используя набор меток. Он позволяет задать, на каких узлах могут запускаться виртуальные машины, выбирая узлы с необходимыми метками.

1spec:
2  nodeSelector:
3    disktype: ssd

В этом примере виртуальная машина будет размещена только на узлах, которые имеют метку disktype со значением ssd.

Предпочтительное связывание (Affinity)

Affinity предоставляет более гибкие и мощные инструменты по сравнению с nodeSelector. Он позволяет задавать «предпочтения» и «обязательности» для размещения виртуальных машин. Affinity поддерживает два вида: nodeAffinity и virtualMachineAndPodAffinity.

nodeAffinity позволяет определять на каких узлах может быть запущена виртуальная машина с помощью выражений меток и может быть мягким (preferred) или жестким (required).

Пример использования nodeAffinity:

1spec:
2  affinity:
3    nodeAffinity:
4      requiredDuringSchedulingIgnoredDuringExecution:
5        nodeSelectorTerms:
6          - matchExpressions:
7              - key: disktype
8                operator: In
9                values:
10                  - ssd

В этом примере виртуальная машина будет размещена только на узлах, которые имеют метку disktype со значением ssd.

virtualMachineAndPodAffinity управляет размещением виртуальных машин относительно других виртуальных машин. Он позволяет задавать предпочтение размещения виртуальных машин на тех же узлах, где уже запущены определенные виртуальные машины.

Пример:

1spec:
2  affinity:
3    virtualMachineAndPodAffinity:
4      preferredDuringSchedulingIgnoredDuringExecution:
5        - weight: 1
6          podAffinityTerm:
7            labelSelector:
8              matchLabels:
9                server: database
10            topologyKey: "kubernetes.io/hostname"

В этом примере виртуальная машина будет размещена, если будет такая возможность (тк используется preferred) только на узлах на которых присутствует виртуальная машина с меткой server и значением database.

Избежание совместного размещения (AntiAffinity)

AntiAffinity — это противоположность Affinity, которая позволяет задавать требования для избегания размещения виртуальных машин на одних и тех же узлах. Это полезно для распределения нагрузки или обеспечения отказоустойчивости.

Термины Affinity и AntiAffinity применимы только к отношению между виртуальными машинами. Для узлов используемые привязки называются nodeAffinity. В nodeAffinity нет отдельного антитеза, как в случае с virtualMachineAndPodAffinity, но можно создать противоположные условия, задав отрицательные операторы в выражениях меток: чтобы акцентировать внимание на исключении определенных узлов, можно воспользоваться nodeAffinity с оператором, таким как NotIn.

Пример использования virtualMachineAndPodAntiAffinity:

1spec:
2  affinity:
3    virtualMachineAndPodAntiAffinity:
4      requiredDuringSchedulingIgnoredDuringExecution:
5        - labelSelector:
6            matchLabels:
7              server: database
8          topologyKey: "kubernetes.io/hostname"

В данном примере создаваемая виртуальная машина не будет размещена на одном узле с виртуальной машиной с меткой server: database.

Статические и динамические блочные устройства

Блочные устройства можно разделить на два типа по способу их подключения: статические и динамические (hotplug).

Блочные устройства и их особенности представлены в таблице:

Тип блочного устройства Комментарий
VirtualImage подключается в режиме для чтения, или как cdrom для iso-образов
ClusterVirtualImage подключается в режиме для чтения, или как cdrom для iso-образов
VirtualDisk подключается в режиме для чтения и записи

Статические блочные устройства

Статические блочные устройства указываются в спецификации виртуальной машины в блоке .spec.blockDeviceRefs в виде списка. Порядок устройств в этом списке определяет последовательность их загрузки. Таким образом, если диск или образ указан первым, загрузчик сначала попробует загрузиться с него. Если это не удастся, система перейдет к следующему устройству в списке и попытается загрузиться с него. И так далее до момента обнаружения первого загрузчика.

Изменение состава и порядка устройств в блоке .spec.blockDeviceRefs возможно только с перезагрузкой виртуальной машины.

Фрагмент конфигурации VirtualMachine со статически подключенными диском и проектным образом:

1spec:
2  blockDeviceRefs:
3    - kind: VirtualDisk
4      name: <virtual-disk-name>
5    - kind: VirtualImage
6      name: <virtual-image-name>

Динамические блочные устройства

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

Для подключения динамических блочных устройств используется ресурс VirtualMachineBlockDeviceAttachment (vmbda).

Создайте ресурс, который подключит пустой диск blank-disk к виртуальной машине linux-vm:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineBlockDeviceAttachment
4metadata:
5  name: attach-blank-disk
6spec:
7  blockDeviceRef:
8    kind: VirtualDisk
9    name: blank-disk
10  virtualMachineName: linux-vm
11EOF

После создания VirtualMachineBlockDeviceAttachment может находиться в следующих состояниях (фазах):

  • Pending - ожидание готовности всех зависимых ресурсов.
  • InProgress - идет процесс подключения устройства.
  • Attached - устройство подключено.

Диагностика проблем с ресурсом осуществляется путем анализа информации в блоке .status.conditions.

Проверьте состояние вашего ресурса:

1d8 k get vmbda attach-blank-disk

Пример вывода:

1NAME                PHASE      VIRTUAL MACHINE NAME   AGE
2attach-blank-disk   Attached   linux-vm              3m7s

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

1d8 v ssh cloud@linux-vm --local-ssh --command "lsblk"

Пример вывода:

1NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
2sda       8:0    0   10G  0 disk <--- статично подключенный диск linux-vm-root
3|-sda1    8:1    0  9.9G  0 part /
4|-sda14   8:14   0    4M  0 part
5`-sda15   8:15   0  106M  0 part /boot/efi
6sdb       8:16   0    1M  0 disk <--- cloudinit
7sdc       8:32   0 95.9M  0 disk <--- динамически подключенный диск blank-disk

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

1d8 k delete vmbda attach-blank-disk

Подключение образов, осуществляется по аналогии. Для этого в качестве kind указать VirtualImage или ClusterVirtualImage и имя образа:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineBlockDeviceAttachment
4metadata:
5  name: attach-ubuntu-iso
6spec:
7  blockDeviceRef:
8    kind: VirtualImage # или ClusterVirtualImage
9    name: ubuntu-iso
10  virtualMachineName: linux-vm
11EOF

Публикация виртуальных машин с использованием сервисов

Достаточно часто возникает необходимость сделать так, чтобы доступ к этим виртуальным машинам был возможен извне, например, для публикации каких-либо сервисов или удалённого администрирования. Для этих целей мы можем использовать сервисы, которые обеспечивают маршрутизацию трафика из внешней сети к внутренним ресурсам кластера. Рассмотрим несколько вариантов.

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

1d8 k label vm linux-vm app=nginx

Пример вывода:

1virtualmachine.virtualization.deckhouse.io/linux-vm labeled

Публикация сервисов виртуальной машины с использованием сервиса с типом NodePort

Сервис NodePort открывает определённый порт на всех узлах кластера, перенаправляя трафик на заданный внутренний порт сервиса.

Создайте следующий сервис:

1d8 k apply -f - <<EOF
2apiVersion: v1
3kind: Service
4metadata:
5  name: linux-vm-nginx-nodeport
6spec:
7  type: NodePort
8  selector:
9    # Лейбл по которому сервис определяет на какую виртуальную машину направлять трафик.
10    app: nginx
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 80
15      nodePort: 31880
16EOF

В данном примере будет создан сервис с типом NodePort, который открывает внешний порт 31880 на всех узлах вашего кластера. Этот порт будет направлять входящий трафик на внутренний порт 80 виртуальной машины, где запущено приложение Nginx.

Публикация сервисов виртуальной машины с использованием сервиса с типом LoadBalancer

При использовании типа сервиса LoadBalancer кластер создаёт внешний балансировщик нагрузки, который распределит входящий трафик по всем экземплярам вашей виртуальной машины.

1d8 k apply -f - <<EOF
2apiVersion: v1
3kind: Service
4metadata:
5  name: linux-vm-nginx-lb
6spec:
7  type: LoadBalancer
8  selector:
9    # Лейбл по которому сервис определяет на какую виртуальную машину направлять трафик
10    app: nginx
11  ports:
12    - protocol: TCP
13      port: 80
14      targetPort: 80
15EOF

Публикация сервисов виртуальной машины с использованием Ingress

Ingress позволяет управлять входящими HTTP/HTTPS запросами и маршрутизировать их к различным серверам в рамках вашего кластера. Это наиболее подходящий метод, если вы хотите использовать доменные имена и SSL-терминацию для доступа к вашим виртуальным машинам.

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

Внутренний сервис для связки с Ingress. Пример:

1d8 k apply -f - <<EOF
2apiVersion: v1
3kind: Service
4metadata:
5  name: linux-vm-nginx
6spec:
7  selector:
8    # лейбл по которому сервис определяет на какую виртуальную машину направлять трафик
9    app: nginx
10  ports:
11    - protocol: TCP
12      port: 80
13      targetPort: 80
14EOF

И ресурс Ingress для публикации. Пример:

1d8 k apply -f - <<EOF
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5  name: linux-vm
6spec:
7  rules:
8    - host: linux-vm.example.com
9      http:
10        paths:
11          - path: /
12            pathType: Prefix
13            backend:
14              service:
15                name: linux-vm-nginx
16                port:
17                  number: 80
18EOF

Живая миграция виртуальной машины

Живая миграция виртуальных машин (ВМ) — это процесс перемещения работающей ВМ с одного физического узла на другой без её отключения. Эта функция играет ключевую роль в управлении виртуализованной инфраструктурой, обеспечивая непрерывность работы приложений во время технического обслуживания, балансировки нагрузки или обновлений.

Как работает живая миграция

Процесс живой миграции включает несколько этапов:

  1. Создание нового экземпляра ВМ

    На целевом узле создаётся новая ВМ в приостановленном состоянии. Её конфигурация (процессор, диски, сеть) копируется с исходного узла.

  2. Первичная передача памяти

    Вся оперативная память ВМ копируется на целевой узел по сети. Это называется первичной передачей.

  3. Отслеживание изменений (Dirty Pages)

    Пока память передаётся, ВМ продолжает работать на исходном узле и может изменять некоторые страницы памяти. Такие страницы называются «грязными» (dirty pages), и гипервизор их помечает.

  4. Итеративная синхронизация

    После первичной передачи начинается повторная отправка только изменённых страниц. Этот процесс повторяется в несколько циклов:

    • Чем выше нагрузка на ВМ, тем больше «грязных» страниц появляется, и тем дольше длится миграция.
    • При хорошей пропускной способности сети объём несинхронизированных данных постепенно уменьшается.
  5. Финальная синхронизация и переключение

    Когда количество «грязных» страниц становится минимальным, ВМ на исходном узле приостанавливается (обычно на 100 миллисекунд):

    • Оставшиеся изменения памяти передаются на целевой узел.
    • Состояние процессора, устройств и открытых соединений синхронизируется.
    • ВМ запускается на новом узле, а исходная копия удаляется.

Cкорость сети играет важную роль. Если пропускная способность низкая, итераций становится больше, а время простоя ВМ может увеличиться. В худшем случае миграция может вообще не завершиться.

Механизм AutoConverge

Если сеть не справляется с передачей данных, а количество «грязных» страниц продолжает расти, будет полезен механизм AutoConverge. Он помогает завершить миграцию даже при низкой пропускной способности сети.

Принципы работы механизма AutoConverge:

  1. Замедление процессора ВМ

    Гипервизор постепенно снижает частоту процессора исходной ВМ. Это уменьшает скорость появления новых «грязных» страниц. Чем выше нагрузка на ВМ, тем сильнее замедление.

  2. Ускорение синхронизации

    Как только скорость передачи данных превышает скорость изменения памяти, запускается финальная синхронизация, и ВМ переключается на новый узел.

  3. Автоматическое завершение

    Финальная синхронизация запускается, когда скорость передачи данных превышает скорость изменения памяти.

AutoConverge — это своего рода «страховка», которая гарантирует, что миграция завершится, даже если сеть не справляется с передачей данных. Однако замедление процессора может повлиять на производительность приложений, работающих на ВМ, поэтому его использование нужно контролировать.

Настройка политики миграции

Для настройки поведения миграции используйте параметр .spec.liveMigrationPolicy в конфигурации ВМ. Допустимые значения параметра:

  • AlwaysSafe — Миграция всегда выполняется без замедления процессора (AutoConverge не используется). Подходит для случаев, когда важна максимальная производительность ВМ, но требует высокой пропускной способности сети.
  • PreferSafe — (используется в качестве политики по умолчанию) Миграция выполняется без замедления процессора (AutoConverge не используется). Однако можно запустить миграцию с замедлением процессора, используя ресурс VirtualMachineOperation с параметрами type=Evict и force=true.
  • AlwaysForced — Миграция всегда использует AutoConverge, то есть процессор замедляется при необходимости. Это гарантирует завершение миграции даже при плохой сети, но может снизить производительность ВМ.
  • PreferForced — Миграция использует AutoConverge, то есть процессор замедляется при необходимости. Однако можно запустить миграцию без замедления процессора, используя ресурс VirtualMachineOperation с параметрами type=Evict и force=false.

Виды миграции

Миграция может осуществляться пользователем вручную, либо автоматически при следующих системных событиях:

  • Обновлении «прошивки» виртуальной машины.
  • Перераспределение нагрузки в кластере.
  • Перевод узла в режим технического обслуживания (Drain узла)
  • При изменении параметров размещения ВМ (не доступно в Community-редакции).

Триггером к живой миграции является появление ресурса VirtualMachineOperations с типом Evict.

В таблице приведены префиксы названия ресурса VirtualMachineOperations с типом Evict, создаваемые для живых миграций вызванных системными событиями:

Вид системного события Префикс имени ресурса
Обновлении «прошивки» firmware-update-*
Перераспределение нагрузки evacuation-*
Drain узла evacuation-*
Изменение параметров размещения nodeplacement-update-*

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

  • Pending - ожидается выполнение операции.
  • InProgress - живая миграция выполняется.
  • Completed - живая миграция виртуальной машины завершилась успешно.
  • Failed - живая миграция виртуальной машины завершилась неуспешно.

Посмотреть активные операции можно с использованием команды:

1d8 k get vmop

Пример вывода:

1NAME                    PHASE       TYPE    VIRTUALMACHINE      AGE
2firmware-update-fnbk2   Completed   Evict   linux-vm            1m

Прервать любую живую миграцию пока она находится в фазе Pending, InProgress можно удалив соответствующий ресурс VirtualMachineOperations.

Как выполнить живую миграцию виртуальной машины с использованием VirtualMachineOperations.

Рассмотрим пример. Перед запуском миграции посмотрите текущий статус виртуальной машины:

1d8 k get vm

Пример вывода:

1NAME                                   PHASE     NODE           IPADDRESS     AGE
2linux-vm                               Running   virtlab-pt-1   10.66.10.14   79m

Мы видим что на данный момент она запущена на узле virtlab-pt-1.

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

1d8 v evict -n <namespace> <vm-name>

Выполнение данной команды приводит к созданию ресурса VirtualMachineOperations.

Запустить миграцию можно также создав ресурс VirtualMachineOperations (vmop) с типом Evict вручную:

1d8 k create -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineOperation
4metadata:
5  generateName: evict-linux-vm-
6spec:
7  # Имя виртуальной машины.
8  virtualMachineName: linux-vm
9  # Операция для миграции.
10  type: Evict
11  # Разрешить замедление процессора механизмом AutoConverge, для гарантии, что миграция выполнится.
12  force: true
13EOF

Для отслеживания миграции виртуальной машины сразу после создания ресурса vmop, выполните команду:

1d8 k get vm -w

Пример вывода:

1NAME                                  PHASE       NODE           IPADDRESS     AGE
2linux-vm                              Running     virtlab-pt-1   10.66.10.14   79m
3linux-vm                              Migrating   virtlab-pt-1   10.66.10.14   79m
4linux-vm                              Migrating   virtlab-pt-1   10.66.10.14   79m
5linux-vm                              Running     virtlab-pt-2   10.66.10.14   79m

Живая миграция виртуальной машины при изменении параметров размещения (недоступно в CE редакции)

Рассмотрим механизм миграции на примере кластера с двумя группами узлов (NodeGroups): green и blue . Допустим, виртуальная машина (ВМ) изначально запущена на узле группы green , а её конфигурация не содержит ограничений на размещение.

Шаг 1. Добавление параметра размещения Укажем в спецификации ВМ требование к размещению в группе green :

1spec:
2  nodeSelector:
3    node.deckhouse.io/group: green

После сохранения изменений ВМ продолжит работать на текущем узле, так как условие nodeSelector уже выполняется.

Шаг 2. Изменение группы размещения Изменим требование на размещение в группе blue :

1spec:
2  nodeSelector:
3    node.deckhouse.io/group: blue

Теперь текущий узел (группы green) не соответствует новым условиям. Система автоматически создаст объект VirtualMachineOperations типа Evict, что инициирует живую миграцию ВМ на доступный узел группы blue.

Пример вывода ресурса

1NAME                         PHASE       TYPE    VIRTUALMACHINE      AGE
2nodeplacement-update-dabk4   Completed   Evict   linux-vm            1m

IP-адреса виртуальных машин

Блок .spec.settings.virtualMachineCIDRs в конфигурации модуля virtualization задает список подсетей для назначения ip-адресов виртуальным машинам (общий пул ip-адресов). Все адреса в этих подсетях доступны для использования, за исключением первого (адрес сети) и последнего (широковещательный адрес).

Ресурс VirtualMachineIPAddressLease (vmipl): кластерный ресурс, который управляет арендой IP-адресов из общего пула, указанного в virtualMachineCIDRs.

Чтобы посмотреть список аренд IP-адресов (vmipl), используйте команду:

1d8 k get vmipl

Пример вывода:

1NAME             VIRTUALMACHINEIPADDRESS                             STATUS   AGE
2ip-10-66-10-14   {"name":"linux-vm-7prpx","namespace":"default"}     Bound    12h

Ресурс VirtualMachineIPAddress (vmip): проектный/неймспейсный ресурс, который отвечает за резервирование арендованных IP-адресов и их привязку к виртуальным машинам. IP-адреса могут выделяться автоматически или по явному запросу.

Чтобы посмотреть список vmip, используйте команду:

1d8 k get vmipl

Пример вывода:

1NAME             VIRTUALMACHINEIPADDRESS                             STATUS   AGE
2ip-10-66-10-14   {"name":"linux-vm-7prpx","namespace":"default"}     Bound    12h

По умолчанию IP-адрес виртуальной машине назначается автоматически из подсетей, определенных в модуле и закрепляется за ней до её удаления. Проверить назначенный IP-адрес можно с помощью команды:

1k get vmip

Пример вывода:

1NAME             ADDRESS       STATUS     VM         AGE
2linux-vm-7prpx   10.66.10.14   Attached   linux-vm   12h

Алгоритм автоматического присвоения IP-адреса виртуальной машине выглядит следующим образом:

  • Пользователь создает виртуальную машину с именем <vmname>.
  • Контроллер модуля автоматически создает ресурс vmip с именем <vmname>-<hash>, чтобы запросить IP-адрес и связать его с виртуальной машиной.
  • Для этого vmip создается ресурс аренды vmipl, который выбирает случайный IP-адрес из общего пула.
  • Как только ресурс vmip создан, виртуальная машина получает назначенный IP-адрес.

IP-адрес виртуальной машине назначается автоматически из подсетей, определенных в модуле, и остается закрепленным за машиной до её удаления. После удаления виртуальной машины ресурс vmip также удаляется, но IP-адрес временно остается закрепленным за проектом/неймспейсом и может быть повторно запрошен явно.

С полным описанием параметров конфигурации ресурсов vmip и vmipl машин можно ознакомиться по ссылкам:

Как запросить требуемый ip-адрес?

  1. Создайте ресурс vmip:

    1d8 k apply -f - <<EOF
    2apiVersion: virtualization.deckhouse.io/v1alpha2
    3kind: VirtualMachineIPAddress
    4metadata:
    5  name: linux-vm-custom-ip
    6spec:
    7  staticIP: 10.66.20.77
    8  type: Static
    9EOF
    
  2. Создайте новую или измените существующую виртуальную машину и в спецификации укажите требуемый ресурс vmip явно:

    1spec:
    2  virtualMachineIPAddressName: linux-vm-custom-ip
    

Как сохранить присвоенный виртуальной машине ip-адрес?

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

Получите название ресурса vmip для заданной виртуальной машины:

1d8 k get vm linux-vm -o jsonpath="{.status.virtualMachineIPAddressName}"

Пример вывода:

1linux-vm-7prpx

Удалите блоки .metadata.ownerReferences из найденного ресурса:

1d8 k patch vmip linux-vm-7prpx --type=merge --patch '{"metadata":{"ownerReferences":null}}'

После удаления виртуальной машины, ресурс vmip сохранится и его можно будет переиспользовать снова во вновь созданной виртуальной машине:

1spec:
2  virtualMachineIPAddressName: linux-vm-7prpx

Даже если ресурс vmip будет удален. Он остаётся арендованным для текущего проекта/неймспейса еще 10 минут. Поэтому существует возможность вновь его занять по запросу:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineIPAddress
4metadata:
5  name: linux-vm-custom-ip
6spec:
7  staticIP: 10.66.20.77
8  type: Static
9EOF

Снимки

Снимки предназначены для сохранения состояния ресурса в конкретный момент времени. На данный момент времени поддерживаются снимки дисков и снимки виртуальных машин.

Создание снимков дисков

Для создания снимков виртуальных дисков используется ресурс VirtualDiskSnapshot . Эти снимки могут служить источником данных при создании новых дисков, например, для клонирования или восстановления информации.

Чтобы гарантировать целостность данных, снимок диска можно создать в следующих случаях:

  • Диск не подключен ни к одной виртуальной машине.
  • ВМ выключена.
  • ВМ запущена, но yстановлен qemu-guest-agent в гостевой ОС. Файловая система успешно “заморожена” (операция fsfreeze).

Если консистентность данных не требуется (например, для тестовых сценариев), снимок можно создать:

  • На работающей ВМ без “заморозки” файловой системы.
  • Даже если диск подключен к активной ВМ.

Для этого в манифесте VirtualDiskSnapshot укажите:

1spec:
2  requiredConsistency: false

При создании снимка требуется указать названия класса снимка томов VolumeSnapshotClasses, который будет использоваться для создания снимка.

Для получения списка поддерживаемых ресурсов VolumeSnapshotClasses выполните команду:

1d8 k get volumesnapshotclasses

Пример вывода:

1NAME                     DRIVER                                DELETIONPOLICY   AGE
2csi-nfs-snapshot-class   nfs.csi.k8s.io                        Delete           34d
3sds-replicated-volume    replicated.csi.storage.deckhouse.io   Delete           39d

Пример манифеста для создания снимка диска:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualDiskSnapshot
4metadata:
5  name: linux-vm-root-snapshot
6spec:
7  requiredConsistency: true
8  virtualDiskName: linux-vm-root
9  volumeSnapshotClassName: sds-replicated-volume
10EOF

Для просмотра списка снимков дисков, выполните следующую команду:

1d k get vdsnapshot

Пример вывода:

1NAME                   PHASE     CONSISTENT   AGE
2linux-vm-root-snapshot Ready     true         3m2s

После создания VirtualDiskSnapshot может находиться в следующих состояниях (фазах):

  • Pending - ожидание готовности всех зависимых ресурсов, требующихся для создания снимка.
  • InProgress — идет процесс создания снимка виртуального диска.
  • Ready — создание снимка успешно завершено, и снимок виртуального диска доступен для использования.
  • Failed — произошла ошибка во время процесса создания снимка виртуального диска.
  • Terminating — ресурс находится в процессе удаления.

Диагностика проблем с ресурсом осуществляется путем анализа информации в блоке .status.conditions.

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

Восстановление дисков из снимков

Для того чтобы восстановить диск из ранее созданного снимка диска, необходимо в качестве dataSource указать соответствующий объект:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualDisk
4metadata:
5  name: linux-vm-root
6spec:
7  # Настройки параметров хранения диска.
8  persistentVolumeClaim:
9    # Укажем размер больше чем значение .
10    size: 10Gi
11    # Подставьте ваше название StorageClass.
12    storageClassName: i-sds-replicated-thin-r2
13  # Источник из которого создается диск.
14  dataSource:
15    type: ObjectRef
16    objectRef:
17      kind: VirtualDiskSnapshot
18      name: linux-vm-root-snapshot
19EOF

Создание снимков виртуальных машин

Для создания снимков виртуальных машин используется ресурс VirtualMachineSnapshot.

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

Если снимок планируется использовать как шаблон, перед его созданием выполните в гостевой ОС:

  • Удаление персональных данных (файлы, пароли, история команд).
  • Установку критических обновлений ОС.
  • Очистку системных журналов.
  • Сброс сетевых настроек.
  • Удаление уникальных идентификаторов (например, через sysprep для Windows).
  • Оптимизацию дискового пространства.
  • Сброс конфигураций инициализации (cloud-init clean).

Снимок содержит конфигурацию виртуальной машины и снимки всех её дисков.

Восстановление снимка предполагает полное восстановление виртуальной машины на моммент создания её снимка.

Снимок будет создан успешно, если:

  • ВМ выключена
  • Установлен qemu-guest-agent и файловая система успешно “заморожена”.

Если целостность данных не критична, снимок можно создать на работающей ВМ без заморозки ФС. Для этого укажите в спецификации:

1spec:
2  requiredConsistency: false

При создании снимка необходимо указать названия классов снимков томов VolumeSnapshotClass, которые будут использованы для создания снимков дисков, подключенных к виртуальной машине.

Чтобы получить список поддерживаемых ресурсов VolumeSnapshotClasses, выполните команду:

1d8 k get volumesnapshotclasses

Пример вывода:

1NAME                     DRIVER                                DELETIONPOLICY   AGE
2csi-nfs-snapshot-class   nfs.csi.k8s.io                        Delete           34d
3sds-replicated-volume    replicated.csi.storage.deckhouse.io   Delete           39d

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

  • не все зависимые устройства виртуальной машины готовы;
  • есть изменения, ожидающие перезапуска виртуальной машины;
  • среди зависимых устройств есть диск, находящийся в процессе изменения размера.

При создании снимка динамический IP-адрес ВМ автоматически преобразуется в статический и сохраняется для восстановления.

Если не требуется преобразование и использование старого IP-адреса виртуальной машины, можно установить соответствующую политику в значение Never. В этом случае будет использован тип адреса без преобразования (Auto или Static).

1spec:
2  keepIPAddress: Never

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

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineSnapshot
4metadata:
5  name: linux-vm-snapshot
6spec:
7  virtualMachineName: linux-vm
8  volumeSnapshotClasses:
9    - storageClassName: i-sds-replicated-thin-r2 # Подставьте ваше название StorageClass.
10      volumeSnapshotClassName: sds-replicated-volume # Подставьте ваше название VolumeSnapshotClass.
11  requiredConsistency: true
12  keepIPAddress: Never
13EOF

Восстановление из снимков

Для восстановления виртуальной машины из снимка используется ресурс VirtualMachineRestore . В процессе восстановления в кластере автоматически создаются следующие объекты:

  • VirtualMachine — основной ресурс ВМ с конфигурацией из снимка.
  • VirtualDisk — диски, подключенные к ВМ на момент создания снимка.
  • VirtualBlockDeviceAttachment — связи дисков с ВМ (если они существовали в исходной конфигурации).
  • Secret — секреты с настройками cloud-init или sysprep (если они были задействованы в оригинальной ВМ).

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

Восстановление виртуальной машины

Чтобы восстановить виртуальную машину, необходимо удалить её текущую конфигурацию и все связанные диски. Это связано с тем, что процесс восстановления возвращает виртуальную машину и её диски к состоянию, зафиксированному в момент создания резервного снимка.

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

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineRestore
4metadata:
5  name: <restore name>
6spec:
7  virtualMachineSnapshotName: <virtual machine snapshot name>
8EOF

Создание клона ВМ / Использование снимка как шаблона для создания ВМ

Снимок виртуальной машины может использоваться как для создания её точной копии (клона), так и в качестве шаблона для развёртывания новых ВМ с аналогичной конфигурацией.

Для этого требуется создать ресурс VirtualMachineRestore и задать параметры переименования в блоке .spec.nameReplacements, чтобы избежать конфликтов имён.

Пример манифеста для восстановления ВМ из снимка:

1d8 k apply -f - <<EOF
2apiVersion: virtualization.deckhouse.io/v1alpha2
3kind: VirtualMachineRestore
4metadata:
5  name: <name>
6spec:
7  virtualMachineSnapshotName: <virtual machine snapshot name>
8  nameReplacements:
9    - from:
10        kind: VirtualMachine
11        name: <old vm name>
12      to: <new vm name>
13    - from:
14        kind: VirtualDisk
15        name: <old disk name>
16      to: <new disk name>
17    - from:
18        kind: VirtualDisk
19        name: <old secondary disk name>
20      to: <new secondary disk name>
21    - from:
22        kind: VirtualMachineBlockDeviceAttachment
23        name: <old attachment name>
24      to: <new attachment name>
25EOF

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

  1. Если ресурс VirtualMachineIPAddress уже существует в кластере, он не должен быть назначен другой ВМ .
  2. Для статических IP-адресов (type: Static) значение должно полностью совпадать с тем, что было зафиксировано в снимке.
  3. Секреты, связанные с автоматизацией (например, конфигурация cloud-init или sysprep), должны точно соответствовать восстанавливаемой конфигурации.

Несоблюдение этих требований приведёт к ошибке восстановления . Это связано с тем, что система проверяет целостность конфигурации и уникальность ресурсов для предотвращения конфликтов в кластере.