LXC-контейнери (Linux Containers) у Proxmox використовують ядро хост-системи, що робить їх значно легшими та швидшими за повноцінні VM. Контейнер запускається за секунди і споживає мінімум ресурсів за того ж рівня ізоляції для більшості задач, де не потрібне окреме ядро чи чужа операційна система.
VM проти 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, але лише переконавшись, що операція справді зависла.
Привілейовані проти непривілейованих контейнерів
Рекомендація: завжди використовуйте --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, тому ризик впливу на сусідів лишається низьким навіть при помилці всередині самого контейнера.