Ядро модуля virtualization непосредственно отвечает за работу с виртуальными машинами (ВМ). Ядро основано на проекте KubeVirt. KubeVirt — это Open Source-проект, который позволяет запускать, развёртывать и управлять ВМ с использованием Kubernetes в качестве платформы оркестрации. Он обеспечивает совместную работу традиционных ВМ и контейнерных рабочих нагрузок в одном кластере Kubernetes, предоставляя единую плоскость управления. В модуле virtualization используется форк KubeVirt от компании «Флант».
Для управления ВМ ядро модуля использует кастомные ресурсы следующих API-групп:
internal.virtualization.deckhouse.io— основная группа, аналог API-группыkubevirt.ioоригинального KubeVirt. Включает следующие кастомные ресурсы:- InternalVirtualizationVirtualMachine — описание конфигурации и статуса ВМ;
- InternalVirtualizationVirtualMachineInstance — описание работающей ВМ. После выключения ВМ ресурс InternalVirtualizationVirtualMachineInstance удаляется, но остаётся ресурс InternalVirtualizationVirtualMachine, который управляет жизненным циклом InternalVirtualizationVirtualMachineInstance.
Ресурсами основной группы управляет компонент virt-controller. Ресурс InternalVirtualizationVirtualMachine основной API-группы
internal.virtualization.deckhouse.ioKubeVirt используется в качестве бэкенда для ресурса VirtualMachine API-группыvirtualization.deckhouse.io, управляемой virtualization-controller.Для упрощения для ресурсов InternalVirtualizationVirtualMachine и InternalVirtualizationVirtualMachineInstance далее будут использоваться сокращённые наименования VirtualMachine и VirtualMachineInstance соответственно (из API-группы
kubevirt.ioоригинального KubeVirt).-
subresources.kubevirt.io— группа субресурсов. Субресурсы — это дополнительные операции или действия, которые можно выполнять над основными ресурсами (например, VirtualMachineInstance) через API Kubernetes. Они предоставляют интерфейсы для управления конкретными аспектами ресурсов, не затрагивая весь объект. Вместо привычного для Kubernetes декларативного ресурса они представляют собой эндпоинт для императивных операций. В модулеvirtualizationиспользуются следующие субресурсы KubeVirt:virtualmachines/{name}/addvolume;virtualmachines/{name}/removevolume;virtualmachines/{name}/addresourceclaim;virtualmachines/{name}/removeresourceclaim;virtualmachineinstances/{name}/console;virtualmachineinstances/{name}/vnc;virtualmachineinstances/{name}/portforward;virtualmachineinstances/{name}/freeze;virtualmachineinstances/{name}/unfreeze.
Субресурсами управляет компонент virt-api. Перечисленные выше субресурсы KubeVirt используются в качестве бэкенда для аналогичных ресурсов из
subresources.virtualization.deckhouse.ioAPI-групп, управляемых компонентом virtualization-api.
Архитектура ядра модуля
Для упрощения схемы приняты следующие допущения:
- На схеме контейнеры разных подов показаны как взаимодействующие напрямую. Фактически обмен выполняется через соответствующие сервисы Kubernetes (внутренние балансировщики). Названия сервисов не указываются, если они очевидны из контекста. В остальных случаях название сервиса приводится над стрелкой.
- Поды могут быть запущены в нескольких репликах, однако на схеме каждый под показан в единственном экземпляре.
Архитектура ядра модуля virtualization на уровне 2 модели C4 и его взаимодействия с другими компонентами DKP изображены на следующей диаграмме:

Компоненты ядра модуля
Ядро модуля состоит из следующих компонентов:
-
Virt-api — Kubernetes Extension API Server, обслуживающий запросы к
subresources.kubevirt.ioAPI-группы. Virt-api выполняет валидацию и мутацию кастомных ресурсов изinternal.virtualization.deckhouse.ioAPI-группы с помощью механизма Validating/Mutating Admission Controllers. Запросы проходят через сайдкар-контейнер proxy, который переименовывает метаданные из API-группыinternal.virtualization.deckhouse.ioв API-группуkubevirt.ioи проксирует их на эндпоинт virt-api.Состоит из следующих контейнеров:
- virt-api — основной контейнер, реализующий контроллер и вебхук-сервер;
- proxy (он же kube-api-rewriter) — сайдкар-контейнер, выполняющий модификацию проходящих через него запросов API, а именно переименование метаданных кастомных ресурсов. Это необходимо, поскольку компоненты KubeVirt используют API-группы вида
*.kubevirt.io, а другие компоненты модуляvirtualizationиспользуют аналогичные ресурсы, но с API-группой вида*.virtualization.deckhouse.io. Kube-api-rewriter является шлюзом, проксирующим запросы между контроллерами, управляющими ресурсами из разных API-групп; - kube-rbac-proxy — сайдкар-контейнер с авторизующим прокси на основе Kubernetes RBAC для организации защищённого доступа к метрикам контроллера и сайдкар-контейнера proxy. Является Open Source-проектом.
-
Virt-controller — контроллер, управляющий кастомными ресурсами основной
internal.virtualization.deckhouse.ioAPI-группы и отвечающий за функциональность виртуализации на уровне кластера (cluster wide). Для каждого ресурса VirtualMachineInstance он создаёт отдельный под, в котором запускается ВМ. Virt-controller следит за VirtualMachineInstance ресурсами, обновляет их статус и управляет связанными с ними подами.Состоит из следующих контейнеров:
- virt-controller — основной контейнер;
- proxy (он же kube-api-rewriter) — сайдкар-контейнер, выполняющий модификацию проходящих через него запросов API. Подробно описан выше;
- kube-rbac-proxy — сайдкар-контейнер, обеспечивающий авторизованный доступ к метрикам и состоянию контроллера. Подробно описан выше.
-
Virt-handler (DaemonSet) — отдельный контроллер, запускающийся на всех узлах кластера. Virt-handler выполняет следующие функции:
-
расширяет функционал kubelet, донастраивая окружение пода для запуска ВМ внутри него. На данный момент virt-handler отвечает за создание сетевых интерфейсов, а также используется для проброса
dev/kvmи других устройств с узла внутрь пода. Для проброса устройств virt-handler использует kubelet device plugins; -
как и virt-controller, virt-handler следит за VirtualMachineInstance ресурсами, соответствующими запущенным на узле ВМ. При обнаружении изменений virt-handler отправляет команду процессу virt-launcher, запущенному в контейнере compute пода ВМ. Virt-launcher изменяет состояние ВМ в соответствии с полученной командой. Virt-handler также следит за событиями ВМ, которые возвращает virt-launcher, и синхронизирует состояние соответствующего VirtualMachineInstance ресурса;
-
принимает через
console-portкоманды от компонента virt-api, соответствующие запросам на субресурсы, и пересылает их на исполнение в virt-launcher. Благодаря функционалу субресурсов осуществляется проброс портов до ВМ, а также обычной и VNC-консоли.Virt-handler взаимодействует с virt-launcher по gRPC-протоколу через Unix-сокет.
Состоит из следующих контейнеров:
- virt-launcher — init-контейнер, запускающий через virt-launcher скрипт
node-labeller.sh. Этот скрипт подготавливает данные по характеристикам процессоров, их функциям и типам машин, которые virt-handler будет использовать для установки соответствующих лейблов на ресурсах Node. Эти лейблы в свою очередь будут использоваться для планирования ВМ на узлах, которые поддерживают соответствующие параметры; - virt-handler — основной контейнер;
- virt-launcher-image-holder — служебный сайдкар-контейнер для предварительного скачивания образа virt-launcher. Контейнер стоит на паузе и выполняет только функцию хранения образа;
- pr-helper — QEMU persistent reservation helper, служебный сайдкар-контейнер, создаёт сокет-слушатель, который принимает входящие соединения для коммуникации с QEMU. Это необходимо, поскольку операционная система ограничивает отправку команд SCSI с постоянным резервированием непривилегированным программам, что не позволяет совместно использовать блочные SCSI-устройства несколькими ВМ, например в случае кластеризации. QEMU — Open Source-проект для эмуляции аппаратного обеспечения различных платформ, который используется для запуска ВМ в поде.
-
-
Virt-operator — оператор Kubernetes, управляющий жизненным циклом компонентов KubeVirt при помощи кастомного ресурса InternalVirtualizationKubeVirt. Virt-operator устанавливает в кластере virt-api, virt-controller и virt-handler, а также выполняет их настройку.
Состоит из следующих контейнеров:
- virt-operator — основной контейнер;
- proxy (он же kube-api-rewriter) — сайдкар-контейнер, выполняющий модификацию проходящих через него запросов API. Подробно описан выше.
-
Virt-launcher-[имя VMI] — под, в котором запускается ВМ (точнее VirtualMachineInstance).
Состоит из одного контейнера:
-
compute — контейнер, в котором запускается virt-launcher. Virt-launcher реализует cmd-server (gRPC-сервер для удалённого выполнения команд).
Virt-launcher в зависимости от поступающей от virt-handler команды формирует XML-спецификацию запускаемой или обновляемой ВМ и отправляет её в libvirtd. Libvirtd — это демон серверной части системы управления виртуализацией libvirt. Он работает на хост-серверах и выполняет задачи управления для виртуальных гостевых систем.
Libvirtd в свою очередь запускает ВМ и управляет её жизненным циклом. ВМ запускается при помощи QEMU и KVM. QEMU — свободно разрабатываемый эмулятор, который поддерживает аппаратную виртуализацию и работает в связке с гипервизором KVM.
Фактически libvirtd запускает процесс QEMU, который и есть ВМ (точнее VirtualMachineInstance).
Также virt-handler постоянно следит за состоянием запущенной ВМ, которое возвращает libvirtd через virt-launcher, и обновляет статус VirtualMachineInstance.
-
Взаимодействия ядра модуля
Ядро модуля взаимодействует со следующими компонентами:
-
Kube-apiserver:
- следит за кастомными ресурсами KubeVirt, управляет компонентами KubeVirt;
- следит за VirtualMachineInstance ресурсами, обновляет их статус и управляет связанными с ними подами;
- выполняет авторизацию запросов на получение метрик.
-
CDI (Containerized-Data-Importer) — KubeVirt на основе спецификации диска и ссылки на образ ВМ в секции
DataVolumeTemplateресурса VirtualMachine создаёт DataVolume. CDI импортирует в PVC образ диска из указанного в DataVolume источника. Созданный PVC является диском ВМ, управляемой KubeVirt.
С ядром модуля взаимодействуют следующие внешние компоненты:
-
Kube-apiserver:
- отправляет запросы на валидацию кастомных ресурсов InternalVirtualizationKubeVirt;
- отправляет запросы на валидацию и мутацию кастомных ресурсов из
internal.virtualization.deckhouse.ioAPI-группы.
-
Prometheus-main — собирает метрики компонентов.