2
19
2014
18

利用 Aufs 和 LXC 快速建立一个用于测试的系统副本

本文来自依云's Blog,转载请注明。

起因是,我偶尔看到 MediaWiki 导出时可以把图片也包含在 XML 文件中,但是不确定能不能顺利地导入回去。本来是准备拿虚拟机测试的,但是得在虚拟机里安装整套环境,麻烦呀。于是,结合前段时间折腾 Aufs 和 LXC 的经验,把当前正在运行的系统利用 Aufs 搞了一份只读挂载。当然还要弄个空目录来放可写分支:

mkdir -p root data
sudo mount -t aufs -o br:$PWD/data=rw:/=ro aufs $PWD/root

其实这个样子就已经可以 chroot 进去跑 httpd 了。不过,得先改一下监听的端口,因为 chroot 环境与主系统只有文件系统是隔离的,网络空间还是共享的。chroot 中 PID 空间也是共享的,所以在里边杀进程时不小心把 PID 写错的话,是可能会把外边的进程给杀掉的……(而 LXC 中,主系统是可以杀容器中的进程,但是反过来不行,因为主系统中的进程在容器中根本没分配 PID。)

于是就来玩玩 LXC 啦。要注意把 fstab 删掉,不然 systemd 会不高兴。日志文件不能共享,否则 journald 会不高兴。因为把 mknod 权限给禁掉了,所以在容器里 loop 设备是没法创建的。如果需要,在主系统里 losetup 之后像注释里那样写一条挂载信息就好。

sudo rm root/etc/fstab
sudo rm -r root/var/log/journal
sudo mkdir root/var/log/journal
sudo chgrp systemd-journal root/var/log/journal
sudo brctl addbr br0
sudo ifconfig br0 192.168.10.1

cat > lxc.conf <<EOF
lxc.utsname = arch2
lxc.autodev = 1
lxc.tty = 1
lxc.pts = 1024
lxc.rootfs = ${PWD}/root
lxc.mount.entry = sysfs sys sysfs ro,defaults 0 0
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = /proc/sys ${PWD}/root/proc/sys none ro,bind 0 0
lxc.cap.drop = mknod sys_module mac_admin mac_override
# loop mount
# lxc.mount.entry = /dev/loop1 /home/lilydjwg/tmpfs/root/var/lib/pacman ext4 rw 0 0
#networking
lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
lxc.network.ipv4 = 192.168.10.3
lxc.network.name = eth0
#cgroups
lxc.cgroup.devices.deny = a
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 1:7 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 136:* rwm
EOF
sudo lxc-start -n arch-dup -f lxc.conf

当然网络和 DNS 还要进去再设置一下:

route del -net 192.0.0.0/8
route add -net 192.168.0.0/16 eth0
route add -net default gw 192.168.10.1
echo 'nameserver 192.168.10.1' > /etc/resolve.conf

LXC 挺有点复杂的。systemd 的开发者也是这么认为的,所以他们搞了个操作便捷性类似于 chroot 但是功能类似于 LXC 的东东——systemd-nspawn!比如上边那个新系统可以这么启动:

sudo systemd-nspawn -b --private-network -D root

不过很遗憾的是,要么加--private-network让新启动的容器没有网络,要么不加,和 chroot 一样与主系统共享网络。毕竟是他们用来测试 systemd 的东东嘛。调试系统的第一个进程可不容易,但是当它在另一个系统中只是一个普通进程、可以连 gdb 和 strace 时情况就大不一样啦 =w=

PS: 在 systemd-nspawn 的 manpage 中(上边那个 freedesktop.org 的链接),Arch 和 Fedora 以及 Debian 并列作为示例了呢 =w=


2015年3月14日更新:使用 Linux 3.18 及以上版本的内核,也可以使用 overlayfs 取代 aufs 来挂载,挂载命令示例如下:

modprobe overlay
mount -t overlay -o lowerdir=/,upperdir=$PWD/.lxc-data,workdir=$PWD/.lxc-root overlayfs $PWD/.lxc-root

lowerdir是只读的目录(其中的数据不会被修改),upperdir是用于记录修改的可写目录,workdir是工作目录,其必要性我也不理解,需要和upperdir同一文件系统。我习惯上指定为挂载目标目录。

overlayfs 某些操作的效率似乎比 aufs 高不少。这里是我自己用来创建这个系统副本的 Shell 脚本。

Category: Linux | Tags: linux systemd lxc aufs | Read Count: 14542
Iven 说:
Feb 20, 2014 03:16:36 AM

为啥不直接用 docker……

Avatar_small
依云 说:
Feb 20, 2014 12:49:47 PM

docker 不是需要从网上下 tar 包么?

Iven 说:
Feb 20, 2014 01:59:31 PM

也能自己做的……应该比 LXC 简单。

Star Brilliant 说:
Feb 20, 2014 06:12:43 PM

如果用private网络,可以挂iptables masquerade让客户机上网么?
想创建一个隔绝外界的网络环境。

Avatar_small
依云 说:
Feb 20, 2014 08:22:55 PM

systemd-nspawn 的那个 --private-network 根本就没网络设备啊,你怎么弄 iptables?

Star Brilliant 说:
Feb 20, 2014 08:41:22 PM

那为什么要叫 private network?
直接叫 no network 不好了……

z 说:
Feb 22, 2014 08:20:22 PM 好麻烦,试试docker,就可以腾出时间泡妞了
jack 说:
Feb 26, 2014 11:38:27 AM

现在内部在推docker,我试试仙子你这个方法,再用docker 搞一个试试

Avatar_small
依云 说:
Feb 26, 2014 12:06:33 PM

试完记得把心得发出来哦~

我就看到 docker 官方介绍下各种镜像,于是不想搞了。而且我当前在 Aufs 上弄 LXC 本来就是为了达到零流量建立一个隔离环境来着。

MaskRay 说:
Apr 06, 2014 10:13:24 PM

aufs 要給內核打補丁好麻煩的樣子……我前天試了下 fuse 的 bindfs,能做 readonly bind 的 mount……aufs 還有啥特別的功能?https://www.stgraber.org/2014/02/09/lxc-1-0-gui-in-containers/ 果然開發者就是 paranoid..... 瀏覽器什麼都在 lxc 裏運行,不過可能挺對的。我想用 lxc 結合 qemu-user-static 玩些 arm/mips 什麼的,但 qemu-user-static 不支持 ptrace 還是討厭

Avatar_small
依云 说:
Apr 06, 2014 11:23:58 PM

aufs 是联合文件系统——把多个目录的内容合并到一起。类似的还有 unionfs 和 overlayfs。

StarBrilliant 说:
May 21, 2014 07:46:19 PM

我看了 systemd-nspawn 的 manpage。--network-veth 可以用来创建一个主机到容器的网络,或者 --network-macvlan 可以共享主机的网络设备。

Avatar_small
依云 说:
May 21, 2014 09:00:51 PM

咦,什么时候加上的……

atmouse 说:
Mar 13, 2015 06:22:45 PM

我觉得overlay补充下, 毕竟overlay是自带亲儿子

atmouse 说:
Mar 13, 2015 06:23:43 PM

mount -t overlay overlay -olowerdir=/,upperdir=/lxc/upper,workdir=/lxc/work /mnt/merged\

Avatar_small
依云 说:
Mar 13, 2015 06:44:35 PM

它出生迟啦。你不用 modprobe overlay 的么?

atmouse 说:
Mar 14, 2015 12:52:22 AM

你说啥?
我只是发一下overlay的mount用法,好让你补充。 overlayfs我这边还得编译模块才能用呢


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com