暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

走进Container: UnionFS

ProdanLabs 2019-12-03
237


1

Linux Kernel中的Namespaces解决了进程、网络以及文件系统等资源的隔离,Cgroups实现了CPU、内存的限制,但是在Docker还有一个非常重要的问题需要解决 — 那就是image(镜像


Docker镜像的本质就是一个压缩包,我们可以使用docker export 命令将一个Docker镜像中的文件导出

[root@kube-master01 nginx]
[root@kube-master01 nginx]# docker export $(docker create nginx:1.17.6-alpine) | tar -C ./  -xf - 
[root@kube-master01 nginx]# ls
bin  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@kube-master01 nginx]

可以看到NGINX镜像中的目录结构与Linux操作系统的根目录中并没有太多的区别,Linux之上皆文件,Docker镜像就是一个文件。


2


Union File System简称为UnionFS,在Linux中用于把多个文件(目录)『联合』到同一个挂载点的文件系统服务,这些文件(目录)称为层或分支,整个『联合』的过程被称为联合挂载(Union Mount)

[root@kube-master01 demo]# tree 
.
|-- admin
|   `-- admin.logs
|-- system
|   `-- system.logs
|-- test
|   `-- test.logs
`-- unionfs

4 directories, 3 files
[root@kube-master01 demo]# mount -t overlay -o lowerdir=./system:./admin:./test none ./unionfs  
[root@kube-master01 demo]# df -k
Filesystem     1K-blocks     Used Available Use% Mounted on
devtmpfs          997360        0    997360   0% /dev
tmpfs            1018616       24   1018592   1% /dev/shm
tmpfs            1018616      548   1018068   1% /run
tmpfs            1018616        0   1018616   0% /sys/fs/cgroup
/dev/vda1       51473888 24098560  24737580  50% /
tmpfs             203724        0    203724   0% /run/user/0
none            51473888 24098560  24737580  50% /root/demo/unionfs
[root@kube-master01 demo]# ls -lrt ./unionfs/
total 12
-rw-r--r-- 1 root root 5 Dec  3 00:05 test.logs
-rw-r--r-- 1 root root 5 Dec  3 00:05 system.logs
-rw-r--r-- 1 root root 5 Dec  3 00:05 admin.logs
[root@kube-master01 demo]#

目前overlay2替代AUFS成为Docker推荐的存储驱动程序,本文皆采用overlay2示例


Docker镜像和Docker容器

下层是镜像层做lowerdir,上层容器层叫做upperdir。对外展示的统一视图称作merged。

在Docker中,所有镜像层和容器层的文件都存储在 /var/lib/docker/存储驱动/ 目录中

image目录是专门用来存储元数据(imagedb和layerdb),image由多个layer组合而成的,换句话说layer就是一个资源池,如果有多个image会指向同一个layer,那么这一个layer称为公共层。

[root@kube-master01 ~]# ls /var/lib/docker/image/overlay2/
distribution  imagedb  layerdb  repositories.json
[root@kube-master01 ~]

imagedb/content/sha256/目录下存储所有镜像详情,镜像ID开头进行区分,可以rootfs看到nginx:1.17.6-alpine与nginx:1.17.6-alpine有一层layers是共享的

[root@kube-master01 ~]# docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               1.17.6-alpine       a624d888d69f        12 days ago         21.5MB
nginx               1.17.5-alpine       b6753551581f        5 weeks ago         21.4MB
[root@kube-master01 ~]# ls  /var/lib/docker/image/overlay2/imagedb/content/sha256/a624d888d69f*                                                          
/var/lib/docker/image/overlay2/imagedb/content/sha256/a624d888d69ffdc185ed3b9c9c0645e8eaaac843ce59e89f1fbe45b0581e4ef6
[root@kube-master01 ~]# ls /var/lib/docker/image/overlay2/imagedb/content/sha256/b6753551581f*                                                           
/var/lib/docker/image/overlay2/imagedb/content/sha256/b6753551581f2d2fb976dd502f15764526d423b23cb3f5518c0a34c98451cec9
[root@kube-master01 ~]# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/a624d888d69ffdc185ed3b9c9c0645e8eaaac843ce59e89f1fbe45b0581e4ef6 | jq . | tail -n 10
  ],
  "os""linux",
  "rootfs": {
    "type""layers",
    "diff_ids": [
      "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0",
      "sha256:f4cef7054e837eb301d4c669bf2b58b3f764188d4a8e20dd65fcbfa4d7f688a1"
    ]
  }
}
[root@kube-master01 ~]# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/b6753551581f2d2fb976dd502f15764526d423b23cb3f5518c0a34c98451cec9 | jq . | tail -n 10                      
  ],
  "os""linux",
  "rootfs": {
    "type""layers",
    "diff_ids": [
      "sha256:77cae8ab23bf486355d1b3191259705374f4a11d483b24964d2f729dd8c076a0",
      "sha256:bba7d2385bc1fa532ccca27efa3ce6b5ae200ef720ad7461c9ba9821c34cced1"
    ]
  }
}
[root@kube-master01 ~]


/var/lib/docker/image/overlay2/只是存储元数据,所有镜像层的文件存储在/var/lib/docker/overlay2/,同时该目录包含镜像或容器层的挂载点,最终会被 Docker通过联合的方式进行挂载组装。

[root@kube-master01 ~]#  docker run -d nginx:1.17.6-alpine
fff4041bb9e8cc98a9e5f50876619932ebd0b9e7644ff55d7e96d50b4916ddf5
[root@kube-master01 ~]# cat  /var/lib/docker/image/overlay2/layerdb/mounts/fff4041bb9e8cc98a9e5f50876619932ebd0b9e7644ff55d7e96d50b4916ddf5/init-id 
5d14ebeab22dbd6bee9040188c9cc20c78f01de3f26fd4f707f7c87d9de9bea2-init
[root@kube-master01 ~]# cat  /var/lib/docker/image/overlay2/layerdb/mounts/fff4041bb9e8cc98a9e5f50876619932ebd0b9e7644ff55d7e96d50b4916ddf5/mount-id
5d14ebeab22dbd6bee9040188c9cc20c78f01de3f26fd4f707f7c87d9de9bea2
// 所有初始化的容器层的文件都存储在/var/lib/docker/overlay2/$init-id/diff/目录中
[root@kube-master01 ~]#  ls /var/lib/docker/overlay2/5d14ebeab22dbd6bee9040188c9cc20c78f01de3f26fd4f707f7c87d9de9bea2-init/diff/
dev  etc
// 所有容器运行层的文件存储在/var/lib/docker/overlay2/$mount-id/diff/目录中
[root@kube-master01 ~]#  ls /var/lib/docker/overlay2/5d14ebeab22dbd6bee9040188c9cc20c78f01de3f26fd4f707f7c87d9de9bea2/diff/  
run  var
[root@kube-master01 ~]#


3


我们都知道docker镜像是分层的,Dockerfile中一个命令代表一层,相同的层是共享的,每一个镜像层都是建立在另一个镜像层之上的,同时所有的镜像层都是只读的,所有的容器都建立在Kernel上之上,内核为之提供Namespace、Cgroups、rootfs等支持

当镜像被 docker run 命令创建时就会在镜像的最上层(CMD层之上上)添加一个可写的层,称为容器层,所有对于运行时容器的修改都是对这个该层的修改。所以容器和镜像的区别就在于:所有的镜像都是只读的,而容器在镜像加上一个可读写的层,也就是同一个镜像可以对应多个容器

[root@kube-master01 ~]# docker history nginx:1.17.6-alpine
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
a624d888d69f        12 days ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  
<missing>           12 days ago         /bin/sh -c #(nop)  STOPSIGNAL SIGTERM           0B                  
<missing>           12 days ago         /bin/sh -c #(nop)  EXPOSE 80                    0B                  
<missing>           12 days ago         /bin/sh -c set -x     && addgroup -g 101 -S …   15.9MB              
<missing>           12 days ago         /bin/sh -c #(nop)  ENV PKG_RELEASE=1            0B                  
<missing>           12 days ago         /bin/sh -c #(nop)  ENV NJS_VERSION=0.3.7        0B                  
<missing>           12 days ago         /bin/sh -c #(nop)  ENV NGINX_VERSION=1.17.6     0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop) ADD file:fe1f09249227e2da2…   5.55MB              
[root@kube-master01 ~]



END

1958年的慕尼黑空难让曼联战队瞬间消失在夜空,幸存下来的曼联队的主帅马特·巴斯比用血泪和汗水重建曼联。10年之后,巴斯比带领曼联捧起了欧冠,以告慰故去的亡魂!而这座Holy Trinity雕像也变成了永恒的纪念!

信仰、坚持、重生…希望在前进征途正在不懈拼搏的你,也能够拥有自己的信仰和希望,即便要途径无数沙漠和海洋,也能在经历千帆后柳暗花明!


往期回顾

走进Container: 资源的限制

走进Container: 资源的隔离


文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论