KVM, Xen или LXC: что именно работает на вашем VPS
Узнайте, какая технология виртуализации используется на вашем VPS. Различия в поддержке собственного ядра, swap, вложенной виртуализации и корректном расчете steal time.
Что на самом деле продает ваш тариф VPS
KVM, Xen и LXC — это три семейства технологий виртуализации, на которых строится VPS. Выбор технологии — это не просто особенность оборудования провайдера. От этого зависит, будет ли у вас собственное ядро. Все, что важно для пользователя, вытекает из этого факта: загрузка модулей, управление swap, запуск вложенной виртуализации, возможность использования /proc для вашего сервера (а не чужого) и возможность измерения steal time.
Полная виртуализация (KVM и Xen HVM) предоставляет каждому арендатору отдельное ядро и виртуальную машину. Паравиртуализированный Xen также предоставляет ядро, но оно «знает», что работает в гостевой среде, и делегирует привилегированные операции гипервизору. Контейнерный тариф (LXC, а также линейки OpenVZ и Virtuozzo) предоставляет файловую систему и набор пространств имен (namespaces) внутри ядра провайдера. Все три варианта продаются под одной и той же аббревиатурой.
KVM против Xen против LXC: собственное ядро или общее
В KVM и Xen uname -r определяет ваше ядро. Вы можете установить другое ядро, загрузить в него модуль и перезагрузиться. Ваши действия внутри виртуальной машины никак не влияют на других арендаторов. В контейнерах uname -r использует ядро хоста, которое является общим для всех контейнеров на этой машине. Вы не можете изменить это ядро, а apt install linux-image-generic распакует файлы, которые никогда не загрузятся.
Это единственное различие важнее любых технических характеристик. Читайте остальную часть руководства, рассматривая её как следствие этого факта.
Полная виртуализация: KVM и Xen HVM
KVM (kernel-based virtual machine) — это модуль ядра Linux, который превращает обычный хост Linux в гипервизор, используя инструкции Intel VT-x или AMD-V, встроенные в процессор. QEMU предоставляет виртуальное оборудование вокруг него: диск, сетевую карту, последовательную консоль. Xen имеет другую архитектуру. Xen является самостоятельным гипервизором и загружается до Linux. Привилегированный домен управления, называемый dom0, запускает стек управления, а каждый арендатор является domU. Xen HVM (hardware virtual machine) использует те же расширения процессора, что и KVM, обычно с паравиртуальными драйверами для диска и сети, так как эмулируемое оборудование работает медленно. Эта комбинация называется PVHVM.
Для арендатора обе технологии ведут себя практически идентично. Вы получаете ядро, загрузчик, реальное блочное устройство, работающий modprobe, полноценный /proc, собственный swap и перезагрузку, которая действительно выполняет загрузку системы. Если провайдер позволяет подключить ISO-образ, вы можете установить дистрибутив, который они никогда не предлагали.
Вы платите за это плотностью размещения. Ваши 4 GB закреплены за вашей машиной и не могут быть переданы соседу, пока вы простаиваете, а каждый гость несет на себе процесс QEMU, собственные таблицы страниц и собственный кэш страниц. Эта стоимость — причина, по которой тариф KVM стоит дороже, чем тариф контейнеров с такими же цифрами.
Паравиртуализация Xen и способы её распознавания
Режим Xen PV появился до того, как процессоры получили аппаратные инструкции для виртуализации. Вместо перехвата привилегированных инструкций ядро гостевой системы модифицируется для прямого обращения к гипервизору. Оно работает без использования VT-x, что и было основной целью в 2005 году. Ядро загружается из вашего образа диска с помощью pygrub или pvgrub, поэтому это ваше собственное ядро, но оно должно быть собрано с поддержкой PV-гостя.
Признаки того, что вы используете этот режим: lscpu сообщает тип виртуализации как para, а не full, файл /sys/hypervisor/type существует и содержит упоминание Xen, а ваши диски имеют обозначение xvda, а не vda или sda. Инструменты, считывающие таблицы SMBIOS или DMI, не находят данных, так как у PV-гостя нет прошивки для их публикации.
Цена этого решения — невозможность использования вложенной виртуализации (nested virtualisation). PV-гостю никогда не предоставляются расширения виртуализации процессора, поэтому внутри него невозможно запустить другой гипервизор. Сам по себе Xen не мертв. Устаревает именно Xen PV, а вектор развития проекта сместился в сторону PVH и HVM. Если в тарифном плане указано «Xen», уточните, какая именно реализация используется. HVM — это обычный современный VPS. PV — это тариф, который должен стоить дешевле.
Контейнерный VPS: LXC и линейка OpenVZ
Контейнерный VPS представляет собой набор пространств имен Linux (изолированные представления идентификаторов процессов, точек монтирования, сетевых интерфейсов, имен хостов и пользователей) в сочетании с cgroups (контрольными группами, механизмом ядра для ограничения ресурсов), работающих на ядре хост-системы. Ваш init является процессом на хосте. Ваш ls выполняется непосредственно на ядре хоста без эмуляции и без участия второго планировщика задач. Именно поэтому контейнеры работают быстро и позволяют достичь высокой плотности размещения.
На страницах заказа встречаются названия LXC, контейнеры Proxmox VE (которые являются LXC), OpenVZ и Virtuozzo. OpenVZ 7 и Virtuozzo — это коммерческие наследники одной и той же концепции.
Для вас меняются четыре аспекта:
- Модули ядра.
modprobeне позволит загружать дополнительные модули. Если WireGuard, ZFS или специфический модуль netfilter отсутствуют в ядре провайдера, вы не сможете их использовать. sysctl. Большая часть/proc/sysдоступна только для чтения. Сеть представляет собой отдельное пространство имен, поэтомуnet.ipv4.ip_forwardи связанные с ним файлы обычно доступны для записи. Глобальные настройки системы, такие какvm.swappinessилиfs.file-max, относятся к хост-системе.- Вложенные контейнеры. Docker внутри контейнера LXC работает только в том случае, если провайдер разрешил вложенность (nesting) и используемый драйвер хранилища поддерживает такую конфигурацию. Проверяйте это до покупки, а не полагайтесь на предположения.
- Версия ядра. Вы зависите от графика обновлений провайдера, включая перезагрузки хост-системы.
Как определить, что именно вы приобрели
Выполните эти команды на сервере и сопоставьте результаты. Единой команды для определения типа системы не существует.
systemd-detect-virt
systemd-detect-virt -c
lscpu | grep -iE 'hypervisor|virtualization'
uname -r
ls /lib/modules/$(uname -r) 2>/dev/null | head -n 3
cat /sys/hypervisor/type 2>/dev/nullsystemd-detect-virt выводит короткий идентификатор из фиксированного набора значений. Для физических серверов это могут быть kvm, qemu, xen, amazon и vmware. Для контейнеров — lxc, lxc-libvirt, openvz, docker и systemd-nspawn. Если система не распознана, утилита выводит none и завершается с ненулевым кодом. Формат -c предназначен только для технологий контейнеризации, поэтому любой ответ, отличный от none, однозначно указывает на контейнер, независимо от описания на странице продажи.
lscpu указывает поставщика гипервизора и тип виртуализации (полная или паравиртуализация), что позволяет отличить Xen HVM от Xen PV. Файл /sys/hypervisor/type существует только в среде Xen.
Проверку /lib/modules часто пропускают, хотя она является наиболее прямой. Если каталог для версии запущенного ядра отсутствует или пуст, хотя система явно работает на этом ядре, значит, ядро не было загружено из вашей файловой системы. Оно предоставлено хостом, а дерево модулей не было установлено в вашем образе. Это контейнер.
Для получения независимого подтверждения используйте sudo apt install -y virt-what && sudo virt-what, которая запускает тесты обнаружения как специализированный инструмент. Утилите требуются права root; на «голом железе» она не выводит ничего.
Почему /proc отображает данные не той машины в контейнере
В гостевой системе KVM или Xen /proc/meminfo — это данные вашего собственного ядра об объеме памяти, выделенной гипервизором. Эти данные верны для вашей машины и ничего не говорят о хосте. В этом и заключается смысл виртуальной машины.
В контейнере нет второго ядра, которое вело бы такой учет, поэтому /proc показывает /proc хоста. LXCFS — это небольшая файловая система, которая переписывает некоторые из этих файлов в соответствии с вашими лимитами cgroup; она охватывает /proc/cpuinfo, /proc/meminfo, /proc/stat, /proc/uptime, /proc/swaps, /proc/diskstats и /sys/devices/system/cpu/online. Proxmox монтирует её по умолчанию. Многие небольшие провайдеры этого не делают, и тогда free -m сообщает общий объем памяти хоста, nproc может показать все ядра машины, а uptime — время работы хоста.
Это не просто косметическая проблема, так как программное обеспечение определяет свои параметры на основе этих файлов. nginx с флагом worker_processes auto подсчитывает количество видимых ядер. make -j$(nproc) на хосте с 64 ядрами и квотой в 2 ядра запустит 64 процесса компиляции. JVM или база данных, выбирающая размер кэша на основе MemTotal, выберет значение, которое ваша cgroup отклонит, и ядро завершит процесс при достижении лимита. Это завершение записывается в журнал ядра хоста, который вы не можете прочитать.
Авторитетные значения находятся в cgroup, а не в /proc:
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/cpu.maxЭто пути cgroup v2, которые используются в современных дистрибутивах. memory.max при чтении max означает, что на этом уровне лимит не задан. cpu.max выводит квоту и период в микросекундах, поэтому 200000 100000 означает два ядра процессорного времени на период. На старых хостах с cgroup v1 те же значения находятся в /sys/fs/cgroup/memory/memory.limit_in_bytes и /sys/fs/cgroup/cpu/cpu.cfs_quota_us.
Swap и кому он на самом деле принадлежит
В KVM и Xen swap принадлежит вам. Это файл или раздел на вашем диске, а подкачку страниц выполняет ваше ядро.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
swapon --showswapon --show теперь должен отображать файл с указанием его размера и приоритета. Если swapon отклоняет файл, создайте его с помощью dd if=/dev/zero of=/swapfile bs=1M count=2048, так как на некоторых файловых системах предварительно выделенные файлы с незаписанными экстентами не принимаются. Добавьте /swapfile none swap sw 0 0 в /etc/fstab, иначе swap исчезнет после следующей перезагрузки.
В контейнере ничего из этого вам не принадлежит. swapon требует привилегий, которыми не обладает непривилегированный контейнер, поэтому создание собственного swap-файла завершается ошибкой доступа и не доходит до диска. То, что в плане называется swap, является настройкой cgroup на хосте, memory.swap.max в cgroup v2, которая опирается на собственные swap-устройства хоста. Старые планы OpenVZ продавали квоту "vswap", которая по поведению была ближе к кредиту на всплеск нагрузки, чем к диску. Вы можете прочитать лимит, но не управляете устройством, которое находится под ним.
Вложенная виртуализация и флаг CPU, который вводит в заблуждение
Вложенная виртуализация означает запуск гипервизора внутри вашего VPS: гостевой системы QEMU, Vagrant box или лаборатории вложенной виртуализации с собственными ВМ. Должны соблюдаться два условия. Провайдер должен включить поддержку вложенности на хосте, а гостевая система должна видеть виртуализационные расширения процессора.
lscpu | grep -i virtualization
ls -l /dev/kvm
sudo apt install -y cpu-checker && sudo kvm-okНа гостевой системе KVM с включенной вложенностью файл /dev/kvm существует, а kvm-ok прямо сообщает, доступно ли ускорение. В Xen HVM это технически возможно, но предлагается редко. В Xen PV это невозможно.
В контейнере проверка завершается неудачей поучительным образом. /proc/cpuinfo — это файл хоста, поэтому флаг vmx или svm присутствует, и это действительно правда: физический процессор под вами действительно обладает этими инструкциями. Однако они вам не принадлежат. В вашем пространстве имен нет /dev/kvm, вы не можете загрузить модуль kvm_intel, а флаг, который вы только что прочитали, описывает машину, на которой вы являетесь гостем, а не машину, которой вы управляете. Это самый наглядный пример общего правила. В контейнере /proc описывает пространство имен и окружающее его оборудование, а не сервер, которым вы владеете.
AES-NI и функции процессора, доступные в вашем тарифе
AES-NI (advanced encryption standard new instructions) — это набор процессорных инструкций, которые ускоряют AES-шифрование в несколько раз по сравнению с программной реализацией. На них опираются TLS termination, шифрование дисков, SSH и конвейеры резервного копирования.
В KVM то, что видит гостевая система, определяется моделью процессора, которую провайдер настроил для QEMU. При использовании host passthrough вы видите реальные флаги. При использовании общей модели, такой как qemu64, или намеренно устаревшего базового профиля, выбранного для миграции между разными хостами, флаг aes может отсутствовать, и OpenSSL незаметно переключится на программную обработку.
lscpu | grep -ow aes | head -n 1
openssl speed -evp aes-128-gcm
env OPENSSL_ia32cap='~0x200000000000000:~0x20000000000:~0x0:~0x0:~0x0' openssl speed -evp aes-128-gcmТретья команда — это пример из руководства OpenSSL по отключению данных инструкций внутри библиотеки: она сбрасывает бит AES-NI и бит VAES, оставляя остальные без изменений. Сравните два показателя пропускной способности. Если они близки, значит, быстрый путь изначально не использовался, и правильная проверка AES-NI на VPS стоит пяти минут вашего времени перед покупкой тарифа.
У контейнера нет модели процессора, скрывающей реальное оборудование, поэтому флаги в /proc/cpuinfo — это реальные флаги хоста, которые применяются к вам. Это реальное преимущество контейнерных тарифов, и это единственный случай в данном руководстве, когда общее ядро работает в вашу пользу.
Откуда берется steal time и почему его нет в контейнерах
Steal time — это время, в течение которого ваш виртуальный процессор был готов к выполнению задач, но простаивал, так как гипервизор в этот момент обслуживал другого клиента. Этот показатель отображается как st в top и vmstat, а также как восьмое поле в строке cpu файла /proc/stat.
Гостевая система не может измерить этот параметр самостоятельно, так как она не исполняет код в моменты, когда время «крадется». Эту информацию предоставляет гипервизор. KVM записывает накопленное значение на страницу, которую гостевая система регистрирует через интерфейс паравиртуальных часов, а Xen для этих целей использует область состояния vCPU. Число, которое вы видите, — это данные самого гипервизора, поэтому они существуют и заслуживают доверия.
Высокий показатель steal означает, что хост переподписан (oversubscribed), а ваши соседи в данный момент активно используют ресурсы. Это наглядный индикатор соотношения проданных vCPU к физическим ядрам, и чтение steal time для выявления «шумного соседа» — единственный способ понять, соответствует ли производительность тарифному плану.
vmstat 1 5
cat /sys/fs/cgroup/cpu.statВ контейнере этот столбец не будет меняться, так как между вами и планировщиком нет гипервизора. Ваши процессы стоят в очереди наравне с процессами других арендаторов как обычные задачи в планировщике CPU самого хоста. Конкуренция за ресурсы проявляется просто как увеличение времени выполнения задач, без счетчика, указывающего на причину. Ближайший аналог — это квотирование (throttling): когда провайдер устанавливает cpu.max, то /sys/fs/cgroup/cpu.stat ведет подсчет nr_throttled периодов и throttled_usec микросекунд, проведенных в ожидании следующего окна квоты. Это учитывает только вашу собственную квоту, но не конкуренцию со стороны соседей. Важное предостережение: если хост, на котором запущен контейнер, сам является виртуальной машиной, значение steal может появиться в /proc/stat, но оно будет относиться к этому хосту, а не к вам.
Оверселлинг и причины низкой стоимости контейнерных тарифов
Честный ответ прост. Контейнерный тариф стоит дешевле, так как провайдер размещает больше пользователей на одной и той же машине.
Разрыв наиболее заметен в использовании оперативной памяти. В KVM-госте память зарезервирована за ним, поэтому на хосте с 256 GB продается примерно 256 GB памяти для гостей за вычетом накладных расходов. Лимит памяти контейнера — это верхняя граница, а не резерв. Память, которую контейнер не использует, сразу доступна другим. Поэтому провайдер может продать лимиты, суммарно превышающие объем физической RAM в несколько раз, и почти всегда это будет работать корректно. Здесь нет обмана. Система работает до тех пор, пока слишком много арендаторов не станут активны одновременно, после чего проблемы возникают у всех.
CPU подвергается оверселлингу на любых тарифах, включая KVM, путем продажи большего количества vCPU, чем имеется физических ядер. Дисковое пространство почти везде предоставляется с использованием thin provisioning. Контейнеры обеспечивают еще большую плотность: одно ядро, один page cache, отсутствие процесса QEMU для каждого гостя, поэтому хост вмещает в несколько раз больше арендаторов.
Вы жертвуете изоляцией, и это реальный инженерный компромисс, а не запугивание. Вы используете общее ядро, поэтому ошибка в ядре становится общей проблемой, а выход из контейнера (container escape) дает прямой доступ к хосту. Для выхода из виртуальной машины требуется ошибка в гипервизоре, что является гораздо более узкой и сложной целью. Вы также зависите от графика обновлений ядра и перезагрузок провайдера. Если что-то из этого для вас важно, прочитайте насколько безопасен VPS-хостинг на самом деле перед тем, как делать выбор, основываясь только на цене.
Что выбрать для покупки
Приобретайте KVM, если вам требуется собственное ядро: модули WireGuard или ZFS, конкретная версия ядра, вложенная виртуализация, реальный контроль над swap или изоляция, которую можно обосновать перед аудитором. Приобретайте контейнерный тариф, если вы запускаете обычные сервисы при ограниченном бюджете, ядро провайдера актуально, а вы убедились, что необходимые вам функции уже скомпилированы в него. Считайте Xen HVM эквивалентом KVM для большинства задач и задавайте уточняющие вопросы перед покупкой чего-либо, что до сих пор продается как Xen PV.
Два формата выходят за рамки этого разделения. Микро-ВМ Firecracker предоставляют каждому арендатору полноценное ядро с временем запуска, близким к контейнерам; именно на них работают serverless-платформы. Системные контейнеры Incus позволяют самостоятельно использовать модель контейнеризации на оборудовании, которое вы контролируете, что отличается от аренды готового контейнера. Если терминология вызывает затруднения, что такое VPS на самом деле и разница между VPS, VM и VPC разъясняют понятия, которые, как предполагает данное руководство, вам уже известны.
FAQ
Как определить, является ли мой VPS KVM или контейнером?
Выполните systemd-detect-virt -c. Любой ответ, отличный от none, означает, что вы находитесь внутри контейнера, независимо от того, как называется ваш тарифный план. Проверьте это еще двумя способами, так как механизмы обнаружения можно обмануть. lscpu указывает поставщика гипервизора и тип виртуализации (полная или паравиртуализация). ls /lib/modules/$(uname -r) отсутствует или пуст в контейнере, так как ядро системы берется с хоста, а дерево модулей ядра не устанавливалось в вашу файловую систему. sudo virt-what дает независимый ответ от утилиты, написанной специально для этой задачи.
Почему free -m показывает гораздо больше памяти, чем предусмотрено моим тарифом?
Вы используете контейнер без смонтированного LXCFS, поэтому /proc/meminfo является файлом хоста, а free корректно отображает память хоста. Ваш реальный лимит определяется cgroup. Прочитайте /sys/fs/cgroup/memory.max для получения информации об ограничении и /sys/fs/cgroup/memory.current для текущего использования, либо /sys/fs/cgroup/memory/memory.limit_in_bytes на старых хостах с cgroup v1. Настраивайте любой сервис, который определяет размер кэша или пула воркеров, исходя из этого значения, а не из free.
Могу ли я запустить Docker или WireGuard на LXC VPS?
Иногда, но это не зависит от того, что вы устанавливаете. Оба решения зависят от ядра провайдера, так как вы не можете загружать в него модули. WireGuard работает, если модуль уже присутствует на хосте и доступен вам; в противном случае используется реализация в пространстве пользователя wireguard-go. Для работы Docker провайдер должен разрешить вложенность (nesting) и предоставить драйвер хранилища, функционирующий внутри контейнера. Уточняйте это до покупки или тестируйте на условиях, позволяющих отказаться от услуги.
Почему мой контейнерный VPS не показывает steal time?
Steal time существует только тогда, когда гипервизор планирует работу виртуального процессора, и этот показатель отображается, так как гипервизор записывает его в страницу памяти, которую считывает ваше ядро. У контейнера нет гипервизора под ним. Ваши процессы — это обычные задачи в планировщике хоста, поэтому конкуренция за ресурсы проявляется в замедлении работы без счетчика, указывающего на причину. Вместо этого изучите /sys/fs/cgroup/cpu.stat: nr_throttled и throttled_usec подсчитывают время, которое ваша cgroup провела в ожидании следующего окна квоты CPU, что является наиболее близким аналогом steal time для контейнера.