在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. 你不知道的DIV+CSS的命名规则

    搜索引擎优化(seo)有很多工作要做,其中对代码的优化是一个很关键的步骤.为了更加符合SEO的规范,下面是目前比较好的CSS+DIV的命名规则 1DIV CLASS或者ID 页头:header 登录条 ...

  2. 树莓派apt报错:E: '\Release' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行

    E: '\jessie' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行 开始尝试了各种方法, 换apt源, 改/etc/apt/apt.conf.d/10d ...

  3. SpringMVC重点知识总结

    SpringMVC总结 1. SpringMVC简介 MVC即模型-视图-控制器(Model-View-Controller) Spring Web MVC是一种基于Java的实现了Web MVC设计 ...

  4. Fiddler抓包工具的基本操作

    Fiddler ——位于客户端和服务器端的HTTP代理 代理:客户端所有请求都先经过fiddler,然后转发到相应服务器 服务器端所有相应都先经过fiddler,然后发送到客户端 1. 常用的HTTP ...

  5. OptimalSolution(4)--字符串问题(2)进阶

    一.将整数字符串转成整数值 二.判断字符数组中是否所有的字符都只出现过一次 三.在有序但含有空的数组中查找字符串 四.数组中两个字符串的最小距离 五.添加最少字符使字符串整体都是回文字符串 六.括号字 ...

  6. unity text实现鼠标光标

    由于项目需求,需要在text上实现鼠标的cursor,并且随着点击位置cursor移动.实现方法: 1)新建一个光标的prefab(简单为之,直接在image中添加一个竖线spirte),增加脚本控制 ...

  7. 【ASP.NET Core学习】Razor页面

    准备工作 初始化空的项目(终端输入:dotnet new web -n=Razor) Nuget添加Microsoft.EntityFrameworkCore.SqlServer 和 Microsof ...

  8. fenby C语言

    P1框架 1#include <stdio.h> 2 3int main(){ 4    printf(“C语言我来了”); 5    return 0; 6} P2main()门 P3计 ...

  9. (Java) byte[] 和 base64 字符串之间的转换

    import org.apache.commons.codec.binary.Base64; public class UtilHelper { //base64字符串转byte[] public s ...

  10. 明解C语言 入门篇 第一章答案

    练习1-1 #include <stdio.h> int main() { int a; a = 15; int b; b = 37; int c; c = a - b; printf(& ...