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!