浅谈docker文件系统分层与隔离

[attach]224[/attach]        Docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚。下面就聊一下我对docker文件系统的理解       Docker 使用的支持的文件系统有以下几种: aufs、devicemapper、btrfs  Vfs 我们先来介绍一下aufs

一、  Aufs(advanced multi layered unification filesystem)

    Aufs直译过来就是高级分层统一文件系统。做为一种Union FS 它支持将不同的目录挂载到同一个虚拟文件系统下. 这个怎么理解呢。通过一条命令我们来看一下吧。
mount -t aufs -o br=/tmp/dir1=ro:/tmp/dir2=rw none /tmp/newfs
    []-o 指定mount传递给文件系统的参数[/][]br 指定需要挂载的文件夹,这里包括dir1和dir2[/][]ro/rw 指定文件的权限只读和可读写[/][]none 这里没有设备,用none表示[/]
    这个结果是什么样子的呢。 就是把/tmp/dir1 t和/tmp/dir2  合并之后挂载到/tmp/newfs ,如果这时在/tmp/dir1 下创建一个文件a  /tmp/dir2下创建一个文件b 则  在/tmp/newfs 会看到a,b 这两个文件,并且a 是只读的, 如果有相同的文件则以先挂载的为准,后面挂载的操作会被忽略掉      通过对Aufs的理解,大家可以想像一下docker所谓的“layer”的概念。还是实际的例子说明一下。     一个镜像通过docker save  保存之后 会被打成一个tar 包,我们来看下这个tar包里都有些什么?
docker save cloud_jiankongbao:01.tar cloud_jiankongbao:01
    通过上面的语句我们把镜像保存出下来。可以看到,保存下来的是tar 包。 不是.iso文件^_^,镜像解压之后是什么呢?
ls . 
a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329
d9bde94c518a16a886514758b6b4431200145ecd58e30c5633ac3c0256544d77
f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f
repositories
    出现了四个目录文件,再通过
docker images --tree
└─f1b10cd84249 Virtual Size: 0 B
  └─fb9cc58bde0c Virtual Size: 203.1 MB
    └─a005304e4e74 Virtual Size: 203.1 MB
      └─d9bde94c518a Virtual Size: 1.957 GB Tags: cloud_jiankongbao:01
    大家可以看到,4个目录其实分别是4个ID(注每次使用docker commit 提供对docker的修改之后就会产生一个新的id,就是通过这个ID可以实现对镜像的回滚)。每个目录下有json  layer.tar  VERSION 这三个文件。我们再看一下layer.tar 
cd fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f;tar -xf layer.tar;ls
   
ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/
bin  etc   json       lib    lost+found  mnt  proc  sbin     srv  tmp  var
dev  home  layer.tar  lib64  media       opt  root  selinux  sys  usr  VERSION
    这里存放的系统文件。     我们再看一下镜像的4个不同ID的系统。     f1b10cd84249 这个镜像是初始镜像,大小为0, fb9cc58bde0c 这个镜像是在f1b10cd84249基础上创建新的镜像,a005304e4e74是以fb9cc58bde0c为基础创建新的镜像。是树状继承的关系。我们再看下bin目录下的文件
ls a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329/bin/
gtar  tar
ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/bin/
arch      cpio           egrep    gunzip              logger  mountpoint     raw       sleep       true
awk       cut            env      gzip                login   mv             readlink  sort        umount
basename  date           ex       hostname            ls      netstat        rm        stty        uname
bash      dd             false    ipcalc              lsblk   nice           rmdir     su          unlink
cat       df             fgrep    iptables-xml        mkdir   nisdomainname  rpm       sync        usleep
chgrp     dmesg          find     iptables-xml-1.4.7  mknod   ping           rvi       taskset     vi
chmod     dnsdomainname  findmnt  kill                mktemp  ping6          rview     touch       view
chown     domainname     gawk     link                more    ps             sed       tracepath   ypdomainname
cp        echo           grep     ln                  mount   pwd            sh        tracepath6  zcat
    a005304e4e74 只有两个文件 fb9cc58bde0c包括了大部分bin下的文件,这就是Aufs,理解起来感觉有点像增量备份。

二、简单的说一下devicemapper 

    devicemapper是利用了Snapshot 和Thinly-Provisioned Snapshot两种原理。将多个快照挂在同一个卷下从而实现文件系统的分层。不过使用devicemapper 的话一个container的大小最大只能是10G。       在启动docker daemon时用参数-s 指定:  docker -d -s devicemapper       关于隔离是怎么实现的呢,当容器基于镜像启动之后,每个容器都会获得自己的写读可写的文件系统层。原镜像的那部分文件系统是只读的,从而实现每个容器的在文件系统上的离隔。      平时大家都在说dokcer 是弱隔离的,为什么呢?因为他没有隔离的很彻底,比如内核,内核是跟大家共用的,跟宿主机共用同一个内核,SELinux、 Cgroups以及/sys、/proc/sys、/dev/sd*等目录下的资源是与宿主机共用的。    如果要隔离的彻底那就是VM了,而且如果dockers要想实现这些隔离就必然要牺牲一下现在轻量级的特性。那还不如直接用虚拟机好了! 文章转载出处

0 个评论

要回复文章请先登录注册