本文来自依云'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 脚本。
Feb 20, 2014 03:16:36 AM
为啥不直接用 docker……
Feb 20, 2014 12:49:47 PM
docker 不是需要从网上下 tar 包么?
Feb 20, 2014 01:59:31 PM
也能自己做的……应该比 LXC 简单。
Feb 20, 2014 06:12:43 PM
如果用private网络,可以挂iptables masquerade让客户机上网么?
想创建一个隔绝外界的网络环境。
Feb 20, 2014 08:22:55 PM
systemd-nspawn 的那个 --private-network 根本就没网络设备啊,你怎么弄 iptables?
Feb 20, 2014 08:41:22 PM
那为什么要叫 private network?
直接叫 no network 不好了……
Feb 22, 2014 08:20:22 PM 好麻烦,试试docker,就可以腾出时间泡妞了
Feb 26, 2014 11:38:27 AM
现在内部在推docker,我试试仙子你这个方法,再用docker 搞一个试试
Feb 26, 2014 12:06:33 PM
试完记得把心得发出来哦~
我就看到 docker 官方介绍下各种镜像,于是不想搞了。而且我当前在 Aufs 上弄 LXC 本来就是为了达到零流量建立一个隔离环境来着。
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 還是討厭
Apr 06, 2014 11:23:58 PM
aufs 是联合文件系统——把多个目录的内容合并到一起。类似的还有 unionfs 和 overlayfs。
May 21, 2014 07:46:19 PM
我看了 systemd-nspawn 的 manpage。--network-veth 可以用来创建一个主机到容器的网络,或者 --network-macvlan 可以共享主机的网络设备。
May 21, 2014 09:00:51 PM
咦,什么时候加上的……
Mar 13, 2015 06:22:45 PM
我觉得overlay补充下, 毕竟overlay是自带亲儿子
Mar 13, 2015 06:23:43 PM
mount -t overlay overlay -olowerdir=/,upperdir=/lxc/upper,workdir=/lxc/work /mnt/merged\
Mar 13, 2015 06:44:35 PM
它出生迟啦。你不用 modprobe overlay 的么?
Mar 14, 2015 12:52:22 AM
你说啥?
我只是发一下overlay的mount用法,好让你补充。 overlayfs我这边还得编译模块才能用呢
Mar 14, 2015 02:38:55 PM
补充完毕~