如何在Debian 8上使用LXC和配额支持设置虚拟容器

配额支持是lxc中经常要求的功能。 如果要给予多个用户访问容器并希望控制一个用户没有使用所有磁盘空间,则需要Linux文件系统配额。 出于同样的原因,网络托管服务器也需要配额,例如使用ISPConfig 3:一个网站不能填满整个磁盘。 这个howto向你展示了如何在Debian 8上使用qemu nbd和qcow镜像文件将lxc与硬盘配额一起使用。

先决条件

要使用lxc,您需要qemu实用程序和lxc程序包本身。 通过调用来安装它们:

apt-get install lxc qemu-utils

安装程序将要求您选择稍后安装lxc虚拟机映像的目录。 这个目录应该在一个有很多可用空间的分区上。 如果/ var中有足够的空间,那么接受默认的/ var / lib / lxc,否则,选择最大分区上的一个空闲目录。 当您使用非默认路径时,请确保在以下所有命令和配置文件中更改路径。

准备

检查内核循环模块是否加载:

lsmod | grep '^loop'

如果没有得到结果,您可以通过运行以下命令来启用该模块

modprobe loop

创建虚拟机

现在我们可以开始创建虚拟机了。 在本教程中,我将在主机和容器中使用Debian Jessie,但是当然可以使用其他lxc模板,例如Debian wheezy或ubuntu。

lxc-create -B loop -t debian -n mydebianvm --fssize=20G -- -r jessie

-t参数选择主模板, -r决定要使用哪个版本。 要设置虚拟机的硬盘大小,可以更改--fssize参数。 假设您要创建一个50 GB的磁盘,您可以将参数更改为--fssize = 50G
参数-n设置vm的名称。 我在本教程中使用了mydebianvm 。 请根据您所选择的所有以下命令更改名称。

由于我们不想使用原始图像文件,因此我们需要将磁盘映像转换为qemu qcow2格式。 这是通过以下命令完成的

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

为了使备份处理更容易,稍后,我们创建一个映像文件集,即记录设备所有更改的第二个文件。

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

您现在可以删除原始的原始图像文件:

rm /var/lib/lxc/mydebianvm/rootdev

配置网桥

安装bridge-utils:

apt-get install bridge-utils

在编辑器中打开Debian网络配置文件/ etc / network / interfaces

vim /etc/network/interfaces

并添加以下行:

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

并在文件中添加以下内容:

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

用网络中的免费IP替换IP地址192.168.1.101。

添加preart脚本/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脚本/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

安装配额的必需包。 我们不必为此进入容器。 使用lxc-attach我们可以从容器外部运行命令。

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

无法通过lxc-attach激活配额。 所以我们创建一个bash脚本,这是在下一次启动容器时执行的

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清空。
现在确保bash脚本是可执行的,并在启动时调用:

使其可执行:

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

将调用添加到vm的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

之后,您必须卸载根fs。

umount /var/lib/lxc/mydebianvm/rootfs

最后一步是断开nbd。 确保选择正确的设备号码。
在卸载rootfs之前, 不要断开nbd。 这将导致很多问题,需要完全强制重启主机。

qemu-nbd -d /dev/nbd0

备份虚拟机

因为在为容器创建映像文件时已经创建了两个文件,所以我们可以轻松备份,而不会停止vm。 首先,我们需要将发生的更改提交到基本文件。

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

现在,/ var/lib/lxc/mydebianvm/rootdev.qcow2包含vm硬盘的当前状态,因此可以备份此文件。

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏