LXC-контейнеры (Linux Containers) в Proxmox используют ядро хост-системы, что делает их значительно легче и быстрее, чем полные VM. Контейнер запускается за секунды и потребляет минимум ресурсов при том же уровне изоляции для большинства задач, где не требуется отдельное ядро или чужая операционная система.
VM vs LXC: когда что использовать
Если задача требует полноценной VM, порядок создания описан в статье создание виртуальной машины в Proxmox VE.
| Критерий | VM (KVM) | LXC-контейнер |
|---|---|---|
| Время запуска | 30–60 секунд | 1–3 секунды |
| Потребление RAM | Больше (собственное ядро) | Меньше (общее ядро) |
| Изоляция | Полная (аппаратная) | Частичная (пространства имён) |
| ОС | Любая (Windows, Linux, BSD) | Только Linux |
| Производительность I/O | Небольшие потери | Почти нативная |
| Поддержка Docker | Полная | Ограниченная (нужен nesting) |
Шаг 1: загрузка шаблона контейнера
# Обновить список шаблонов
pveam update
# Показать доступные шаблоны
pveam available | grep -E "debian|ubuntu|alpine"
# Скачать шаблон
pveam download local debian-12-standard_12.7-1_amd64.tar.zst
Или через веб-интерфейс: local → CT Templates → Templates → выбрать и скачать.
Шаг 2: создание контейнера
# Создать непривилегированный контейнер с ID 200
pct create 200 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
--hostname mycontainer \
--rootfs local-lvm:8 \
--memory 512 --swap 512 --cores 1 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--password SecurePass123 \
--unprivileged 1 --onboot 1
# Запустить контейнер
pct start 200
# Открыть консоль
pct enter 200
Разбор типичных ошибок
- unable to create CT 200 - unable to parse value of 'rootfs' - storage 'local-lvm' does not exist — на хосте настроен другой storage backend (например, ZFS или каталог); подставьте реальное имя из
pvesm status, а не значение из чужого примера. - startup for container '200' failed в логе после
pct start— чаще всего конфликт по IP или занятый мостvmbr0, который ещё не поднят на хосте; проверьтеip aи наличие моста до создания контейнера. - lxc-start: 200: ... Permission denied - Failed to mount — попытка примонтировать в непривилегированном контейнере устройство или файловую систему, требующую root на хосте; либо снимите ограничение точечно, либо переключитесь на привилегированный контейнер только для этой задачи.
- CT is locked (snapshot) при попытке изменить конфигурацию — не завершилась предыдущая операция со снапшотом; снять блокировку можно командой
pct unlock 200, но только убедившись, что операция действительно зависла.
Привилегированные vs непривилегированные контейнеры
Рекомендация: всегда используйте --unprivileged 1 (по умолчанию). Непривилегированные контейнеры более безопасны — процессы внутри работают от UID/GID, смещённых на 100000, что исключает эскалацию привилегий на хост даже при компрометации процесса внутри контейнера.
Привилегированные контейнеры нужны только для специфических задач: работа с устройствами, NFS-монтирование, некоторые сетевые функции, которые требуют реального root на хосте.
Монтирование bind mounts
# Примонтировать директорию хоста в контейнер
pct set 200 --mp0 /data/shared,mp=/mnt/shared,backup=0
# Примонтировать через конфигурационный файл
cat /etc/pve/lxc/200.conf
# mp0: /data/shared,mp=/mnt/shared
Включение Docker в LXC
Для запуска Docker внутри LXC-контейнера нужны дополнительные настройки:
# Добавить в /etc/pve/lxc/200.conf на хосте Proxmox
features: keyctl=1,nesting=1
# Перезапустить контейнер
pct stop 200 && pct start 200
# Внутри контейнера установить Docker
curl -fsSL https://get.docker.com | bash
Безопасность: Docker в LXC с nesting=1 снижает изоляцию. Для продакшн-нагрузок рекомендуется Docker внутри полной VM.
Сравнение хранилищ для rootfs контейнера
Подробности по каждому типу хранилища — в статье хранилища в Proxmox VE.
| Storage | Снапшоты | Скорость | Когда использовать |
|---|---|---|---|
| local-lvm (thin) | Да | Высокая | По умолчанию для большинства нод |
| ZFS | Да, мгновенные | Высокая | Нужны частые снапшоты и репликация |
| Каталог (directory) | Нет | Средняя | Тестовые окружения, простая настройка |
Когда LXC не подходит
- Нужна не-Linux система (Windows, FreeBSD) — LXC делит ядро с хостом и физически не может запустить чужую ОС; здесь нужна полноценная VM на KVM.
- Приложению нужен собственный сетевой стек с изменением параметров ядра (например, свой набор sysctl для маршрутизации) — общее ядро хоста ограничивает такие настройки на уровне контейнера.
- Требуется гарантированная жёсткая изоляция для мультитенантной среды с недоверенными пользователями — пространства имён LXC исторически имели больше эскейп-уязвимостей, чем аппаратная виртуализация KVM.
Полезные команды pct
# Список контейнеров
pct list
# Статус контейнера
pct status 200
# Остановить
pct stop 200
# Снапшот
pct snapshot 200 backup1
# Клонировать контейнер
pct clone 200 201 --full --hostname container2
# Удалить
pct destroy 200
Как проверить, что контейнер работает корректно
# Контейнер запущен и без ошибок в конфиге
pct status 200
pct config 200
# Сеть внутри контейнера поднялась
pct exec 200 -- ip a
pct exec 200 -- ping -c 3 8.8.8.8
# Использование ресурсов в реальном времени
pct exec 200 -- free -m
Если pct status показывает running, у контейнера есть IP-адрес и он отвечает на пинг, а free -m показывает ожидаемый объём памяти — контейнер настроен и работает штатно.
Частые вопросы
Можно ли позже перенести уже работающий LXC-контейнер в полноценную VM, если нагрузка выросла?
Прямого автоматического преобразования контейнера в виртуальную машину в Proxmox нет: LXC и VM используют разные механизмы хранения и загрузки. На практике переносят содержимое — файлы, базы данных, конфигурацию приложения — внутрь новой VM вручную или через резервную копию, а сам контейнер после переноса можно остановить и удалить.
Безопасно ли держать продакшн-базу данных внутри LXC-контейнера?
Технически да, но с оговоркой: непривилегированный контейнер со свежим ядром хоста и правильно настроенным хранилищем (ZFS или LVM-thin) выдерживает базу данных не хуже VM. Риск появляется, если нужна гарантированная жёсткая изоляция от других контейнеров на том же хосте — тогда для критичной базы разумнее выделить отдельную VM или даже физический сервер.
Можно ли создать несколько контейнеров из одного и того же шаблона без конфликтов между ними?
Да, несколько контейнеров из одного шаблона создаются без конфликтов, если у каждого свой числовой ID, своё имя хоста и свой сетевой адрес. Конфликт возникает только тогда, когда два контейнера случайно получают одинаковый IP через DHCP или одинаковое имя хоста в общей сети — это стандартная сетевая проблема, а не ограничение самого LXC.
Видит ли непривилегированный контейнер процессы и ресурсы других контейнеров на том же хосте?
Нет, пространства имён изолируют процессы и ресурсы каждого контейнера друг от друга: изнутри одного контейнера не видно процессов соседнего, даже если оба запущены на одном хосте. Для непривилегированного контейнера эта изоляция дополнительно усилена смещением UID/GID, что снижает риск повлиять на соседей даже при ошибке в самом контейнере.