Гид по технологиям

Квоты в LXC через qemu-nbd на Debian 8

• 6 min read • DevOps • Обновлено 25 Nov 2025
Квоты в LXC через qemu‑nbd на Debian 8
Квоты в LXC через qemu‑nbd на Debian 8

Важно: везде заменяйте имя контейнера mydebianvm и IP-адреса на значения вашей среды. Соблюдайте порядок остановки, отмонтирования и отключения nbd — иначе возможны повреждения данных.

О чём эта инструкция

Квоты (filesystem quota) полезны, когда нескольким пользователям или виртуальным хостам нужно ограничить использование дискового пространства. Это критично для хостинга (например, ISPConfig) и многопользовательских окружений. В руководстве показан рабочий способ: использовать lxc с образом qcow2, подключаемым через qemu-nbd, и включить файловые квоты внутри контейнера.

Краткие определения: LXC — лёгкая виртуализация на уровне контейнеров; qemu-nbd — утилита, подключающая qcow2-образ как сетевой блочный девайс /dev/nbd*; qcow2 — формат образа диска qemu; quota, aquota — механизмы учёта и ограничения использования диска.

Сопутствующие варианты решения

  • Использовать LVM с квотами на уровне файловой системы (если доступно) — проще для прямых блочных устройств, но сложнее для переносимости.
  • Прямое использование raw-образов с loop-модулями и включением quota — возможный путь, но меньше гибкости снимков (snapshots).
  • Использовать overlayfs или bind-монты и ограничивать пространство с помощью cgroups v2 (контрольно-ограничивающие механизмы) — альтернативная модель контроля ресурсов.

Основные шаги (микрометодология)

  1. Установить зависимости (lxc, qemu-utils, bridge-utils).
  2. Создать контейнер lxc с образом (loop-backed).
  3. Конвертировать raw в qcow2 и создать слой live-образа для коммитов/бэкапов.
  4. Настроить сетевой бридж br0 на хосте.
  5. Подготовить конфигурацию контейнера + скрипты prestart/poststop для подключения qemu-nbd и монтирования.
  6. Запустить контейнер, установить пакеты quota внутри и активировать квоты через одноразовый скрипт на старте.
  7. Проверить работоспособность и настроить процедуру бэкапа/удаления.

Предварительные требования

Для работы потребуются утилиты qemu и пакет lxc. Установите их командой:

apt-get install lxc qemu-utils

Инсталлятор запросит директорию для образов LXC (по умолчанию /var/lib/lxc). Выберите раздел с достаточным свободным местом. Если выбрали нестандартный путь — корректируйте его во всех командах и конфигурациях ниже.

Подготовка модуля loop

Проверьте, загружен ли модуль loop:

lsmod | grep '^loop'

Если результат пуст, загрузите модуль:

modprobe loop

Создание виртуальной машины

Я использую Debian Jessie/jessie для хоста и контейнера, но можно выбирать другие шаблоны lxc.

lxc-create -B loop -t debian -n mydebianvm --fssize=20G -- -r jessie
  • -t выбирает шаблон, -r — релиз.
  • Для установки размера виртуального диска измените –fssize (например –fssize=50G).
  • -n задаёт имя VM; в примерах дальше используется mydebianvm — замените его на своё имя.

Чтобы работать с квотами и удобными бэкапами, конвертируем raw-образ в qcow2:

qemu-img convert -O qcow2 /var/lib/lxc/mydebianvm/rootdev /var/lib/lxc/mydebianvm/rootdev.qcow2

Создаём «live» слой, записывающий изменения в отдельный файл (удобно для коммитов и бэкапа):

qemu-img create -f qcow2 -b /var/lib/lxc/mydebianvm/rootdev.qcow2 /var/lib/lxc/mydebianvm/rootdev-live.qcow2

Оригинальный raw-файл можно удалить:

rm /var/lib/lxc/mydebianvm/rootdev

Настройка сетевого бриджа на хосте

Установите bridge-utils:

apt-get install bridge-utils

Откройте /etc/network/interfaces и добавьте (или скорректируйте) настройки бриджа:

vim /etc/network/interfaces

Добавьте следующий фрагмент (замените address и netmask на значения вашей сети):

auto br0   
iface br0 inet static   
      address 192.168.1.254   
      netmask 255.255.255.0   
      bridge_ports eth0   
      bridge_stp off   
      bridge_fd 2   
      bridge_maxwait 20

Активируйте бридж:

ifup br0

Конфигурация контейнера

Сделайте резервную копию старого файла конфигурации:

mv /var/lib/lxc/mydebianvm/config /var/lib/lxc/mydebianvm/config_bak

Создайте новый конфиг:

vim /var/lib/lxc/mydebianvm/config

Вставьте следующее содержимое (замените IP-адрес контейнера на свободный в вашей сети):

lxc.rootfs = /var/lib/lxc/mydebianvm/rootfs  
lxc.rootfs.options = usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0  
  
lxc.hook.pre-start = /var/lib/lxc/prestart-nbd.sh  
lxc.hook.post-stop = /var/lib/lxc/poststop-nbd.sh  
   
# Common configuration  
lxc.include = /usr/share/lxc/config/debian.common.conf  
   
# only if bridge is set up (or use other method)  
lxc.network.type = veth   
lxc.network.name = veth0   
lxc.network.flags = up   
lxc.network.link = br0   
lxc.network.ipv4 = 192.168.1.101/24   
lxc.network.ipv4.gateway = 0.0.0.0  
   
# Container specific configuration  
lxc.mount = /var/lib/lxc/mydebianvm/fstab  
lxc.utsname = debian8  
lxc.arch = amd64  
lxc.autodev = 1  
lxc.kmsg = 0

Скрипт prestart-nbd.sh

Создайте файл /var/lib/lxc/prestart-nbd.sh:

vim /var/lib/lxc/prestart-nbd.sh

Содержимое (без изменений):

#!/bin/bash  
CHK=$(lsmod | grep '^nbd');  
if [[ "$CHK" == "" ]] ; then  
 modprobe nbd nbds_max=64 max_part=8  
fi  
DEV=""  
  
for D in /dev/nbd* ; do  
F=$(basename $D)  
if [[ $(lsblk | grep "^${F} ") == "" ]] ; then  
DEV="$D"  
break;  
fi  
done  
  
echo "Next free NBD is $DEV";  
  
CHK=$(lsof /var/lib/lxc/${LXC_NAME}/rootdev-live.qcow2 | grep 'qemu-nbd' | awk '{ print $2 }');  
if [[ "$CHK" == "" ]] ; then  
if [[ "$DEV" == "" ]] ; then  
print "No free nbd device found";  
exit 1;  
fi  
echo "Connecting $DEV to /var/lib/lxc/${LXC_NAME}/rootdev-live.qcow2"  
qemu-nbd -c ${DEV} -n --aio=native /var/lib/lxc/${LXC_NAME}/rootdev-live.qcow2  
else  
NBD=$(lsof -p ${CHK} | grep '/dev/nbd' | awk '{ print $9 }');  
if [[ "$NBD" != "" ]] ; then  
echo "/var/lib/lxc/${LXC_NAME}/rootdev-live.qcow2 is already connected to $NBD"  
DEV="$NBD";  
else  
echo "/var/lib/lxc/${LXC_NAME}/rootdev-live.qcow2 is used by suspicious PID";  
exit 1;  
fi  
fi  
  
CHK=$(mount | grep " /var/lib/lxc/${LXC_NAME}/rootfs ")  
if [[ "$CHK" == "" ]] ; then  
 echo "/var/lib/lxc/${LXC_NAME}/rootfs not mounted";  
 echo "Mounting ${DEV} to /var/lib/lxc/${LXC_NAME}/rootfs"  
 mount ${DEV} /var/lib/lxc/${LXC_NAME}/rootfs  
fi  
echo "${DEV} ${DEV:1} none bind,create=file,optional 0 0" > /var/lib/lxc/${LXC_NAME}/fstab

Сделайте скрипт исполняемым:

chmod +x /var/lib/lxc/prestart-nbd.sh

Скрипт poststop-nbd.sh

Создайте /var/lib/lxc/poststop-nbd.sh:

vim /var/lib/lxc/poststop-nbd.sh

Содержимое:

#!/bin/bash  
CHK=$(mount | grep " /var/lib/lxc/${LXC_NAME}/rootfs " | awk '{ print $1 }')  
if [[ "$CHK" != "" ]] ; then  
 echo "Unmounting ${CHK} from /var/lib/lxc/${LXC_NAME}/rootfs"  
 echo "Disconnecting ${CHK}"  
 umount /var/lib/lxc/${LXC_NAME}/rootfs && qemu-nbd -d ${CHK}  
fi

Сделайте исполняемым:

chmod +x /var/lib/lxc/poststop-nbd.sh

Запуск контейнера и настройка квот

Запустите контейнер в фоне:

lxc-start -n mydebianvm -d

Установите пакеты quota внутри контейнера без интерактивного входа, с помощью lxc-attach:

lxc-attach -n mydebianvm -- apt-get -y update  
lxc-attach -n mydebianvm -- apt-get -y install quota

Активировать квоты сразу через lxc-attach нельзя, поэтому создаём одноразовый скрипт, который выполнится при следующей загрузке контейнера.

Создайте файл /var/lib/lxc/mydebianvm/rootfs/opt/actquota.sh:

vim /var/lib/lxc/mydebianvm/rootfs/opt/actquota.sh

Содержимое:

#!/bin/bash  
mount -o remount,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0 /  
touch /aquota.user /aquota.group  
chmod 0600 /aquota.*  
quotacheck -cmug /  
quotaon -avug  
echo '#!/bin/sh -e  
exit 0' > /etc/rc.local  
rm -f /opt/actquota.sh

Скрипт удаляет сам себя и очищает /etc/rc.local контейнера после выполнения.

Сделайте его исполняемым:

chmod 700 /var/lib/lxc/mydebianvm/rootfs/opt/actquota.sh

Добавьте вызов в rc.local контейнера, чтобы скрипт запустился при старте:

echo '#!/bin/bash  
if [[ -e "/opt/actquota.sh" ]] ; then  
/opt/actquota.sh  
fi' > /var/lib/lxc/mydebianvm/rootfs/etc/rc.local

Перезапустите контейнер, чтобы активировать квоты:

lxc-stop -r -n mydebianvm

Проверка результата

Подключитесь в контейнер:

lxc-attach -n mydebianvm

Внутри выполните:

repquota -avug

Вы должны увидеть используемые квоты для пользователей и групп.

Удаление контейнера и безопасное отключение nbd

Очень важно соблюдать порядок действий. Остановите контейнер:

lxc-stop -n mydebianvm

Отмонтируйте rootfs контейнера на хосте:

umount /var/lib/lxc/mydebianvm/rootfs

Только после отмонтирования отключайте nbd (выберите корректный /dev/nbdX):

qemu-nbd -d /dev/nbd0

NEVER отключать nbd до отмонтирования — это может привести к повреждению данных и потребует перезагрузки хоста.

Резервное копирование образа

Поскольку мы использовали два файла (базовый rootdev.qcow2 и live-образ rootdev-live.qcow2), перед бэкапом надо зафиксировать изменения из live-слоя в базовый:

qemu-img commit /var/lib/lxc/mydebianvm/rootdev-live.qcow2

Теперь файл /var/lib/lxc/mydebianvm/rootdev.qcow2 содержит текущее состояние диска и его можно копировать для бэкапа.

Когда это может не сработать

  • Модуль nbd не загружен или не поддерживается в ядре.
  • Нет свободных /dev/nbd* устройств.
  • Неправильный порядок остановки/отмонтирования перед отключением nbd приведёт к повреждению.
  • Повреждён qcow2-образ или диск переполнен.
  • В контейнере не установлены пакеты quota или команда quotacheck не выполняется из-за ошибок в файловой системе.

Альтернативные подходы и когда их выбрать

  • LVM-контейнеры: если инфраструктура использует LVM, проще выделять тома и включать квоты на файловой системе хоста.
  • cgroups v2: для контроля общего потребления ресурсов (IO, память), но не замещает файловые квоты.
  • ZFS или btrfs с квотами и снимками: если нужна расширенная функциональность снимков и дедупликации.

Безопасность и рекомендации

  • Ограничьте доступ к файлам образов на хосте (правильные права доступа).
  • Не оставляйте исполняемые скрипты с глобальным доступом.
  • Контролируйте, кто может запускать lxc-* команды и подключать образ через qemu-nbd.
  • Регулярно тестируйте процедуру восстановления и бэкапов.

Контроль качества и критерии приёмки

  • Контейнер стартует и получает назначенный IP.
  • Файл /aquota.user и /aquota.group созданы и имеют права 0600.
  • repquota -avug показывает квоты для пользователей/групп.
  • Возможность выполнить qemu-img commit и получить корректный бэкап типа qcow2.
  • При остановке контейнера rootfs отмонтирован, затем nbd отключён без ошибок.

Роль‑ориентированные контрольные списки

  • Администратор хоста: установка qemu-utils/lxc/bridge-utils, конфигурация br0, создание qcow2 и live-образа, скрипты prestart/poststop, права на файлы образов.
  • Администратор контейнера: установка quota, проверка quotacheck/quoton, проверка repquota.
  • Оператор бэкапов: выполнение qemu-img commit, копирование rootdev.qcow2, проверка целостности бэкапа.

Быстрый справочник команд (cheat sheet)

  • Установить пакеты: apt-get install lxc qemu-utils bridge-utils
  • Создать контейнер: lxc-create -B loop -t debian -n mydebianvm –fssize=20G – -r jessie
  • Конвертировать в qcow2: qemu-img convert -O qcow2 /var/lib/lxc/mydebianvm/rootdev /var/lib/lxc/mydebianvm/rootdev.qcow2
  • Создать live-образ: qemu-img create -f qcow2 -b /var/lib/lxc/mydebianvm/rootdev.qcow2 /var/lib/lxc/mydebianvm/rootdev-live.qcow2
  • Запустить контейнер: lxc-start -n mydebianvm -d
  • Установить quota внутри: lxc-attach -n mydebianvm – apt-get -y install quota
  • Активировать квоты (один раз): создать /opt/actquota.sh и добавить вызов в /etc/rc.local
  • Проверить: repquota -avug
  • Commit изменений live-образа: qemu-img commit /var/lib/lxc/mydebianvm/rootdev-live.qcow2
  • Отключить nbd: qemu-nbd -d /dev/nbd0

Короткий глоссарий

  • LXC — контейнерная виртуализация на уровне ОС.
  • qemu-nbd — утилита для подключения qcow2 как /dev/nbd*.
  • qcow2 — формат образа диска qemu с поддержкой снапшотов.
  • quota — механизм контроля использования диска пользователями/группами.
  • repquota — утилита для отображения текущих квот.

Итог

Это испытанная схема для включения файловых квот в LXC с использованием qemu-nbd и qcow2: она даёт гибкость снимков и упрощает бэкап. Следуйте аккуратно порядку запуска/остановки и проверяйте квоты после первого старта контейнера.

Примечание: если в вашей среде используются другие инструменты управления контейнерами или хранилищем (LVM, ZFS, btrfs), рассмотрите альтернативные подходы, описанные выше.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро