Смешанные нагрузки в едином VPC: объединяем контейнеры и виртуальные машины в microsrv


Инженерам часто предлагают ложный выбор: либо строить всё вокруг Kubernetes и мириться с его сложностью и ограничениями при сборке контейнеров, либо разворачивать классические виртуальные машины и переплачивать за простой ресурсов.
На практике большинству проектов нужен не монолитный выбор, а гетерогенная инфраструктура, где каждый компонент живёт в подходящей ему среде:
- Легковесные веб-сервисы и базы данных работают в контейнерах, стартуют за пару секунд и почти не потребляют RAM в простое.
- Сборочные пайплайны, тесты и системные утилиты требуют полноценных виртуальных машин с доступом к ядру и эмуляторам.
В microsrv контейнеры и виртуальные машины — равноправные жители одной платформы. Они живут в общей приватной сети (VPC), используют одинаковые блочные диски и общаются на скорости eBPF.
Коротко: в microsrv контейнеры и виртуальные машины равноправны в одном приватном VPC. База и веб-сервис в контейнерах, CI/CD-раннер в ВМ, общение через eBPF-сеть без публичных IP.
Покажем всю связку на живом примере: собственная автономная платформа Git и CI/CD.
1. Архитектурный сценарий: собственный DevStack
Задача: команде нужен собственный независимый сервис исходного кода и непрерывной интеграции (CI/CD). Классический состав такого решения:
- Веб-интерфейс Git (Gitea / Forgejo) отдаёт страницы, вебхуки и обрабатывает запросы разработчиков.
- База данных (PostgreSQL) хранит пользователей, метаданные репозиториев, задачи и журнал аудита.
- Сборочный агент (Gitea Actions Runner) запускает пайплайны, собирает Docker-образы (
docker build), выполняет тесты и деплоит релизы.
Запустить всё это только на контейнерах или только на ВМ — значит пойти на компромиссы. Посмотрим, какие именно и как их снимает microsrv.
2. Контейнеры: скорость и постоянный диск для сервисов
Для веб-сервиса Gitea и базы данных PostgreSQL контейнеры — естественный выбор. Отдельное виртуальное ядро не нужно, старт занимает секунду.
Но в классическом Kubernetes базы данных в контейнерах — постоянная головная боль из-за эфемерности дисков: любая перезагрузка пода требует настройки сетевых CSI-драйверов, иначе данные исчезают.
В microsrv контейнеры работают на базе технологии Stateful OverlayFS:
- Неизменяемый базовый образ: слои официального образа PostgreSQL или Gitea кэшируются на вычислительных узлах.
- Персистентный рабочий слой: все изменения файлов, таблицы PostgreSQL и репозитории пишутся напрямую на подключённый реплицируемый NVMe-диск.
Даже если контейнер базы данных перезапустится или переедет на другой хост, все данные сохранятся. Настраивать Persistent Volume Claims не нужно: постоянство данных гарантировано на уровне платформы.
3. Виртуальная машина KVM: свобода и честный root для CI/CD
Если веб-сервису и базе данных хорошо в контейнерах, то сборочный раннер — полная их противоположность.
Сборка контейнеров внутри контейнера (Docker-in-Docker) в обычной контейнерной среде — это постоянная борьба с ограничениями безопасности:
- требуются небезопасные флаги
--privileged, открывающие доступ к хостовому ядру; - не работают низкоуровневые средства виртуализации (KVM, QEMU,
cgroups v2); - сложно изолировать сторонний недоверенный код от окружения сборки.
В microsrv раннеру выделяется полноценная виртуальная машина на базе KVM.
Внутри ВМ — настоящий Linux:
- доступен демон Docker и сокет
/var/run/docker.sockдля быстрой сборки и пуша образов; - можно ставить любые версии ядра, системные демоны (
systemd), сетевые эмуляторы и запускать вложенные виртуальные машины; - ошибки и зависшие процессы сборки изолированы аппаратной виртуализацией и не задевают соседние сервисы.
4. Единый приватный контур: безопасность без белых IP
Главная сила гибридного подхода в microsrv — сетевая связность:
+-----------------------------------------------------------------------+
| VPC: 10.42.0.0/24 (Приватная сеть проекта) |
| |
| Gitea (Контейнер) Postgres (Контейнер) Runner (ВМ KVM) |
| IP: 10.42.0.11 IP: 10.42.0.10 IP: 10.42.0.20 |
| Порт: 3000 Порт: 5432 eBPF Mesh |
+-----------------------------------------------------------------------+
- База данных защищена по умолчанию. PostgreSQL слушает порт
5432только на внутреннем IP10.42.0.10. У базы нет внешнего адреса, из публичного интернета она недоступна и принимает запросы исключительно от Gitea по приватному интерфейсу. - Нулевые сетевые задержки. Трафик между контейнерами и ВМ внутри VPC идёт через eBPF ядра Linux без лишних прокси и накладных расходов.
- Безопасная публикация наружу:
- Веб-интерфейс Gitea публикуется через HTTPS-шлюз с автоматическим сертификатом на домене
git.msrv.space. - Административный доступ к виртуальной машине раннера идёт через SSH-шлюз по ключу Ed25519 (
ssh -A runner@msrv.space).
- Веб-интерфейс Gitea публикуется через HTTPS-шлюз с автоматическим сертификатом на домене
Ни одному из компонентов не нужен выделенный публичный IPv4-адрес: экономия на адресации плюс меньше поверхность атаки.
5. Экономика Spot и прозрачная живая миграция
У такой архитектуры приятная себестоимость (как считать реальную экономию с учётом прерываний — в статье Spot и On-Demand).
Все три компонента — веб-интерфейс, база данных и сборочная ВМ — разворачиваются на прерываемых (Spot) ресурсах со скидкой до 25%, без отказа от удобств обычного облака.
В обычных облаках база данных или сборочный агент на Spot-инстансах — это постоянные сбои: провайдер отзывает сервер, сборка падает, соединения к базе обрываются.
В microsrv работает автоматическая живая миграция:
- Для контейнеров: оркестратор переносит память песочницы и атомарно обновляет сокеты в eBPF. Запросы разработчиков к Git-репозиторию не сбрасываются.
- Для виртуальной машины: память ВМ плавно переезжает на резервный хост, а долгая компиляция или сборка тяжёлого образа в CI продолжается без перезапуска.
Итоги
Сочетание контейнеров и виртуальных машин в одном VPC microsrv выглядит так:
| Задача | Решение в microsrv | Почему это удобно |
|---|---|---|
| Веб-сервис (Gitea) | Контейнер microsrv | Секундный запуск, низкое потребление RAM, надёжная изоляция |
| База данных (PostgreSQL) | Контейнер microsrv + Stateful OverlayFS | Диск NVMe сохраняет все данные без настройки внешних PV |
| Сборочный раннер | Виртуальная машина KVM | Честный Docker-in-Docker, root-доступ, отсутствие ограничений |
| Сетевая связность | Приватная VPC (eBPF) | 0 публичных IP, защищённый периметр, доступ через шлюзы |
| Отказоустойчивость | Live Migration на Spot | Скидка на мощности без прерывания сессий и задач сборки |
Контейнеры нужны там, где важна скорость, а виртуальные машины — там, где важна свобода. Оба варианта живут в одном облаке microsrv.
Источники и что почитать дальше
- gVisor — документация gVisor (userspace-ядро для контейнеров)
- KVM — документация KVM
- OCI — Image Specification
- Ключевые технологии microsrv: живая миграция, репликация томов, eBPF-сеть и модель стоимости
Как тестировали: Gitea + PostgreSQL как gVisor-контейнеры (Persistent OverlayFS на реплицируемом NVMe-томе) + KVM-раннер, всё в одном VPC
10.42.0.0/24;10.42.0.10(Postgres) только в VPC, Gitea через HTTPS-шлюз<vm>.msrv.space, раннер черезssh -A runner@msrv.space. Миграция сохраняет всех трёх участников в одной подсети.
FAQ
Почему не запустить раннер в контейнере? Docker-in-Docker требует --privileged и ломает cgroups v2/вложенную виртуализацию; KVM-ВМ даёт честный /var/run/docker.sock и железную изоляцию.
Нужен ли публичный IP? Нет. Исходящий NAT для pull’ов, HTTPS/SSH-шлюзы для входа и WireGuard для подключения рабочего ноутбука к VPC.
Запускайте виртуальные машины в недорогом облаке для разработчиков
microsrv автоматически управляет прерываемыми ресурсами облаков: переносит ВМ до отзыва хоста, сохраняя диски, IP-адреса и открытые соединения.