• Get In Touch
October 9, 2016

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!

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

Share this Article!

Related Posts

Node.js Authentication – A Complete Guide with Passport and JWT

Node.js Authentication – A Complete Guide with Passport and JWT

Truth be told, it’s difficult for a web application that doesn’t have some kind of identification, even if you don’t see it as a security measure in and of itself. The Internet is a kind of lawless land, and even on free services like Google’s, authentication ensures that abuses will be avoided or at least […]

Node.js and MongoDB: How to Connect MongoDB With Node

Node.js and MongoDB: How to Connect MongoDB With Node

MongoDB is a document-oriented NoSQL database, which was born in 2007 in California as a service to be used within a larger project, but which soon became an independent and open-source product. It stores documents in JSON, a format based on JavaScript and simpler than XML, but still with good expressiveness. It is the dominant […]

Using MySQL with Node.js: A Complete Tutorial

Using MySQL with Node.js: A Complete Tutorial

Although data persistence is almost always a fundamental element of applications, Node.js has no native integration with databases. Everything is delegated to third-party libraries to be included manually, in addition to the standard APIs. Although MongoDB and other non-relational databases are the most common choice with Node because if you need to scale an application, […]

Node.Js Vs Django: Which Is the Best for Your Project

Node.Js Vs Django: Which Is the Best for Your Project

Django and NodeJs are two powerful technologies for web development, both have great functionality, versatile applications, and a great user interface. Both are open source and can be used for free. But which one fits your project best? NodeJs is based on JavaScript, while Django is written in Python. These are two equally popular technologies […]

Nodejs Vs PHP:  Which Works Best?

Nodejs Vs PHP: Which Works Best?

Before getting into the “battle” between Node.js and PHP we need to understand why the issue is still ongoing. It all started with the increased demand for smartphone applications, their success forcing developers to adapt to new back-end technologies that could handle a multitude of simultaneous requests. JavaScript has always been identified as a client-side […]