在HOST上面,一个LXC container包含一个config文件和一个rootfs目录。

早期我们在交叉编译系统上编译出container的rootfs之后,直接在编译系统上将其用tar压缩打包。然后下载到目标系统上解压到container的根文件系统“rootfs”里面。但是这样的话有几个问题:
1. image过于庞大,导致下载到目标系统时间较长。
2. 在目标系统上安装时解压时间过长,且会占用大量flash空间。
3. 当container运行起来后,动态生成的文件跟原有的文件混在一起,不方便管理。例如如果要将container恢复到安装时的状态,这时就无从知道删除哪些文件了。
4. 卸载container时需要删除整个rootfs,耗时较长。
5. 无法防止运行过程中对原始文件系统的修改。

基于以上的缺陷,我们做了以下改良:
1. 在编译系统上压缩打包时,我们将rootfs打包成squashfs文件系统并压缩,这种方式压缩比更高,这样可以减少最后生成的image的大小。

$ sudo -n -- mksquashfs $rootfs_dir $squashfs_image_path -noappend -comp xz

这样就生成了“rootfs_base.img”,然后再跟其他配置文件和脚本文件一起压缩打包生成最后的image
2.在目标系统上,直接将"rootfs_base.img" 挂载到文件系统目录上,这样就减少了解压的过程,注意在mount时,我们以readonly的方式mount,这样就防止原始的文件系统被篡改。

mount -nt squashfs -o ro $LXC_DIR/rootfs_base.img $LXC_DIR/lowerdir || error_exit "Cannot mount rootfs base image"

3.我们将目标系统上的rootfs设计成overlay文件系统,将原始的rootfs_base部分放在lower layer,然后将系统运行时产生的文件系统的变动放在upper layer。这样就可以将原始文件和运行时文件进行了隔离。
4.为了限制运行时文件系统大小,我们在安装container时,创建了一个固定大小的类型为ex2的image "rootfs_overlay.img",然后将这个image挂载在一个loop文件系统上:

$ rm -f $LXC_DIR/rootfs_overlay.img

$ dd if=/dev/zero of=$LXC_DIR/rootfs_overlay.img bs=1K count=$size
$ mkfs.ext2 -E root_owner="$uid:$gid" $LXC_DIR/rootfs_overlay.img
$ mount -nt ext4 -o loop,nouser_xattr,noacl,nodelalloc,nobarrier,noblock_validity,noatime,sync $LXC_DIR/rootfs_overlay.img $LXC_DIR/overlay || error_exit "Cannot mount overlay rootfs image"

这样,对$LXC_DIR/overlay的写入就受到"rootfs_overlay.img"的大小的限制了。
5.最后我们最终的runtime rootfs是如下组成:


$ mkdir -p $LXC_DIR/overlay/upperdir $LXC_DIR/overlay/workdir 
$ mount -nt overlay overlay -o "noatime,lowerdir=$LXC_DIR/lowerdir,upperdir=$LXC_DIR/overlay/upperdir,workdir=$LXC_DIR/overlay/workdir" "$LXC_ROOTFS_PATH"

6.在stop container的时候,只需要umount相关的文件系统。

$ umount --lazy "$LXC_DIR/overlay"
$ umount --lazy "$LXC_DIR/lowerdir"
$ umount --lazy "$LXC_DIR/basedir"

在uninstall container的时候,只需要删除相应的image和目录即可。如果需要恢复原始状态,只需要清空upper layer的部分。

如果是特权“priv”模式:

mount -nt squashfs -o ro $LXC_DIR/rootfs_base.img $LXC_DIR/lowerdir || error_exit "Cannot mount rootfs base image"
mount -nt ext4 -o loop,nouser_xattr,noacl,nodelalloc,nobarrier,noblock_validity,noatime,sync $LXC_DIR/rootfs_overlay.img $LXC_DIR/overlay || error_exit "Cannot mount overlay rootfs image"
mkdir -p $LXC_DIR/overlay/upperdir $LXC_DIR/overlay/workdir
mount -nt overlay overlay -o "noatime,lowerdir=$LXC_DIR/lowerdir,upperdir=$LXC_DIR/overlay/upperdir,workdir=$LXC_DIR/overlay/workdir" "$LXC_ROOTFS_PATH"

如果是unpriv模式:

mount -nt squashfs -o ro $LXC_DIR/{{ base_image }} $LXC_DIR/basedir || error_exit "Cannot mount rootfs base image"
bindfs -r --uid-offset=$LXC_UID --gid-offset=$LXC_GID $LXC_DIR/basedir $LXC_DIR/lowerdir || error_exit "Cannot mount base rootfs with UID offset"
mkdir -p $LXC_DIR/overlay/upperdir $LXC_DIR/overlay/workdir
mount -nt overlay overlay -o "noatime,lowerdir=$LXC_DIR/lowerdir,upperdir=$LXC_DIR/overlay/upperdir,workdir=$LXC_DIR/overlay/workdir" "$LXC_ROOTFS_PATH"

LXC容器文件系统设计优化的更多相关文章

  1. LXC容器

    1.    LXC简述 Linux container是一种资源隔离机制而非虚拟化技术.VMM(VMM Virtual Machine Monitor)或者叫Hypervisor是标准的虚拟化技术,这 ...

  2. Hadoop HDFS分布式文件系统设计要点与架构

      Hadoop HDFS分布式文件系统设计要点与架构     Hadoop简介:一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群 ...

  3. lxc 容器基础配置篇

    一, 首先配置lxc需要的网卡断 吧eth0复制一份变为br0 配置br0 配置eth0 重启网卡   /etc/init.d/network restart 安装lxc软件 需要epel源--- y ...

  4. 生成Alpine LXC容器的根文件系统

    一个Alpine LXC容器的文件系统内容包括以下内容 根文件系统 应用程序,库文件以及配置文件 根文件系统主要包含alpine linux最小系统所需要的组件.下面主要讲一下制作根文件系统的方法. ...

  5. Java读取Level-1行情dbf文件极致优化(3)

    最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...

  6. Java读取Level-1行情dbf文件极致优化(2)

    最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...

  7. Linux文件系统性能优化 (转)

    http://blog.chinaunix.net/uid-7530389-id-2050116.html 由于各种的I/O负载情形各异,Linux系统中文件系统的缺省配置一般来说都比较中庸,强调普遍 ...

  8. 如何在Ubuntu上创建及管理LXC容器?

    将LXC安装到Ubuntu上 $ sudo apt-get install lxc 安装完毕之后,运行lxc-checkconifg工具,检查当前Linux内核支持LXC的情况.要是一切都已被启用,内 ...

  9. Django中静态文件引用优化

    静态文件引用优化 在html文件中是用django的静态文件路径时,一般会这么写: <script type="text/javascript" src="/sta ...

随机推荐

  1. Java基础(九)反射(reflection)

    1.反射库(reflection library)提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵Java代码的程序. 能够分析类能力的程序称为反射(reflection).反射机制的功能极 ...

  2. MySql悲观锁与乐观锁区别及使用场景

    一.概念上的区别 乐观锁( Optimistic Locking):顾名思义,对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,"乐观"的认为加锁一定会成功的,在 ...

  3. 死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  4. SpringCloud之Feign和Ribbon的选择(五)

    Ribbon Ribbon 是一个基于 HTTP 和 TCP 客户端的负载均衡器它可以在客户端配置 ribbonServerList(服务端列表),然后轮询请求以实现均衡负载它在联合 Eureka 使 ...

  5. Python+requests+unittest+excel实现接口自动化测试框架(转

    一.框架结构:工程目录 二.Case文件设计三.基础包 base 3.1 封装get/post请求(runmethon.py) import requests import json class Ru ...

  6. ASP_MVC项目设计技巧规则

    对于上述这种类型的前台页面,属于典型的List型的页面,那么,对于model的设计,要考虑前台人员的负担,尽量简洁: model: Name : 对应产品名称,如FMOS_WPF.FMOS_Tun.. ...

  7. 【原创】(十)Linux内存管理 - zoned page frame allocator - 5

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  8. [git]将代码上传到github

    1.右键你的项目,如果你之前安装git成功的话,右键会出现两个新选项,分别为Git Gui Here,Git Bash Here,这里我们选择Git Bash Here,进入如下界面 2.接下来输入如 ...

  9. [考试反思]1109csp-s模拟测试107:低能

    诶一看这不是水题AK场吗?然后80分钟就拿到了285分. 然后,对拍?还是卡T2常数?还是想T2正解? 于是上述三项我依次进行了. 前两项让我的分数丝毫不变但是吃掉了我一个多小时的时间. 卡常卡的也不 ...

  10. php ffmpeg视频和序列帧转化

    php ffmpeg视频和序列帧转化 <pre>$cmd=shell_exec("ffmpeg -i ".__DIR__ . "/shipin1.mp4 -r ...