How to Use Quota Support on LXC Containers

Need Hosting? Try ours, it's fast, reliable and feature loaded with support you can depend on. View Plans

Quota support is one of the most important features of LXC. When you want to give multiple users access to a LXC container and control disk space then quota's will be used. You can also use quota's to manage disk space for web hosting servers.

In this post, we will shows you, how to use quota's on lxc container using qemu nbd with a qcow image file on Debian 8.

Requirements

A server running Debian-8 operating system.

A Non-root user account with sudo privilege set up on your server.

Installing Required Packages

First, you will need to install the lxc and qemu utilities. You can simply install it by running the following command:

sudo apt-get install lxc qemu-utils

Once the package is installed, you need to check whether the kernel loop module is loaded or not with the following command:

sudo lsmod | grep '^loop'

If you don't see any output, you can enable the module by running the following command:

sudo modprobe loop

Creating a Virtual Machine

Now, let's start by creating a virtual machine. In this example, we will use Debian Jessie for both the host and the container. But, you can also use any other distro as you wish.

To do this, run the following command:

sudo lxc-create -B loop -t debian -n newdebianvm --fssize=30G -- -r jessie

The -t arguement specifies the main template. The -r specifies name of the release you want to use. The --fssize arguement specifies the size of the had disk and the -n arguement define the nama of the virtual machine.

Also, you need to convert the disk image to the qemu qcow2 format with the following command:

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

Now, create an image file set to make backup handling easier with the following command:

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

Now, delete the original raw image file with the following command:

sudo rm /var/lib/lxc/newdebianvm/rootdev

Configuring the Network Bridge

In order to configure the network bridge, you need to install bridge-utils on your system.

You can install bridge-utils with the following command:

sudo apt-get install bridge-utils

Next, you will need to edit /etc/network/interfaces file:

sudo nano /etc/network/interfaces

Add the following lines:

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

You can replace the IP address and netmask with values for your local network.

Next, activate the network bridge with the following command:

sudo ifup br0

Configuring the Virtual Machine

Before configuring VM, it is recommended to backup the old config file.

sudo mv /var/lib/lxc/newdebianvm/config /var/lib/lxc/newdebianvm/config_bak

Next, create the new config file for the container by running the following command:

sudo nano /var/lib/lxc/newdebianvm/config

Add the following content:

lxc.rootfs = /var/lib/lxc/newdebianvm/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.100/24 lxc.network.ipv4.gateway = 0.0.0.0 # Container specific configuration lxc.mount = /var/lib/lxc/newdebianvm/fstab lxc.utsname = debian8 lxc.arch = amd64 lxc.autodev = 1 lxc.kmsg = 0

Next, you will need to create the prestart script /var/lib/lxc/prestart-nbd.sh.

sudo nano /var/lib/lxc/prestart-nbd.sh

Add the following lines:

#!/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

Save and close the file, and make it executable by running the following command:

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

Also, you will need to create the poststop script file /var/lib/lxc/poststop-nbd.sh.

sudo nano /var/lib/lxc/poststop-nbd.sh

Add the following lines:

#!/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

Save the file, and make it executable with the following command:

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

Now, you can start the container in background mode by running the following command:

sudo lxc-start -n newdebianvm -d

Next, install necessary packages for quota inside the container with the following command:

sudo lxc-attach -n newdebianvm -- apt-get -y update sudo lxc-attach -n newdebianvm -- apt-get -y install quota

You can activate quota using tge lxc-attach command, but you need to run this command every time, when you start container.

So create shell script that is executed on next boot of the container:

sudo nano /var/lib/lxc/newdebianvm/rootfs/opt/actquota.sh

Add the following content:

#!/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

Save the file and make it executable:

sudo chmod 700 /var/lib/lxc/newdebianvm/rootfs/opt/actquota.sh

You will also need to add the call to the vm's rc.local file:

sudo nano /var/lib/lxc/newdebianvm/rootfs/etc/rc.local

Add the following line:

#!/bin/bash if [[ -e "/opt/actquota.sh" ]] ; then /opt/actquota.sh fi

Now all the set-up is completed, you can now restart the container with the following command:

sudo lxc-stop -r -n newdebianvm

You should now check quota whether it is working or not.

First, attach the container with the command:

sudo lxc-attach -n newdebianvm

Now, run the following command inside the container:

sudo repquota -avug

Now, you should see used quota of users and groups.

Deleting the Virtual Machine

If you want to delete the virtual machine, you will need to run the following set of commands.

First, stop the container:

sudo lxc-stop -n newdebianvm

Now, you need to unmount the root fs.

sudo umount /var/lib/lxc/newdebianvm/rootfs

Next, disconnect the nbd with the following command:

sudo qemu-nbd -d /dev/nbd0

That's it...

Enjoy!