1.镜像含义
镜像是一种轻量级、可执行的独立·软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行库、环境变量和配置文件等。
所有的应用,直接打包docker镜像,就可以直接跑起来
一般通过一些方式获取镜像
-
从远程仓库下载
-
自己制作镜像 Dockerfile
docker镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高兴能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件件系统是docker镜像的基础。
下载镜像看到一层层的就是这个
镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外部看来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。
docker镜像加载原理
docker的镜像实际上由一层层的文件系统组成,这种层级的文件系统就是UnionFS
bootfs(boot file system)主要包含bootloader和kernel,bootloader 主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。
这一层和我们典型的Linux/Unix 系统是一样的,包含boot加载器和内核。
当boot加载完成后整个内核都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
黑屏 ----bootfs–开机进入系统
rootfs(root file system) ,在bootfs 之上,包含的就是典型Linux系统的/dev , /proc /bin , /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等
容器就是一个小的虚拟机环境
对于一个精简的OS,rootfs可以很小,只需要包含基本的命令,工具和程序库就可以了。因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共、公有bootfs。
虚拟机是分钟级的,就是因为启动bootfs很慢
容器不需要启动bootfs,只需要提供rootfs即可,因此是秒级的。
所有的Docker镜像都起始于一个基础镜像层,并进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,加入基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果再该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。
下图一个例子,每个镜像包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中略有区别,主要目的是便于展示文件。
下图展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
这种情况下,上层镜像层的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引起都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了封层COW[1]。
下图展示了与系统现实相同三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点:
Docker镜像都是只读,当容器启动时,一个新的可写层被加载到镜像的顶部
这一层就是我们所说的容器层,容器之下的都叫镜像层
下载tomcat镜像,已经存在的层不用下载
不管层是否存在,都会记录在元数据中。
介绍OverlayFS 存储原理
OverlayFS 结构分为三个层: LowerDir、Upperdir、MergedDir
1、LowerDir (只读)
只读的 image layer,其实就是 rootfs, 在使用 Dockfile 构建镜像的时候, Image Layer
可以分很多层,所以对应的 lowerdir 会很多(源镜像)。
2、Upperdir (读写)
upperdir 则是在 lowerdir 之上的一层, 为读写层。容器在启动的时候会创建, 所有对容 器的修改, 都是在这层。比如容器启动写入的日志文件,或者是应用程序写入的临时 文件。
3、MergedDir (展示)
merged 目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。
LowerDir、Upperdir、MergedDir 关系图:
深人分析镜像结构
1、我们可以通过下面命令获取镜像存储路径
docker inspect ubuntu
"VirtualSize": 72776513,
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/b0893f8b4bcb9d70f1fe5590e36b27681a690b14e9182f741013cdffd8f0c7e6/merged",
"UpperDir": "/var/lib/docker/overlay2/b0893f8b4bcb9d70f1fe5590e36b27681a690b14e9182f741013cdffd8f0c7e6/diff",
"WorkDir": "/var/lib/docker/overlay2/b0893f8b4bcb9d70f1fe5590e36b27681a690b14e9182f741013cdffd8f0c7e6/work"
},
"Name": "overlay2"
2、Lower层
LowerDir 层的存储是不允许创建文件, 此时的LowerDir实际上是其他的镜像的UpperDir层,也就是说在构建镜像的时候,
如果发现构建的内容相同, 那么不会重复的构建目录,而是使用其他镜像的Upper 层来作为本镜像的Lower
3、Upper层
[root@l7 diff]# ll
total 4
lrwxrwxrwx 1 root root 7 Oct 7 00:47 bin -> usr/bin
drwxr-xr-x 2 root root 6 Apr 15 2020 boot
drwxr-xr-x 2 root root 6 Oct 7 00:58 dev
drwxr-xr-x 30 root root 4096 Oct 7 00:58 etc
drwxr-xr-x 2 root root 6 Apr 15 2020 home
lrwxrwxrwx 1 root root 7 Oct 7 00:47 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Oct 7 00:47 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 Oct 7 00:47 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 Oct 7 00:47 libx32 -> usr/libx32
drwxr-xr-x 2 root root 6 Oct 7 00:47 media
drwxr-xr-x 2 root root 6 Oct 7 00:47 mnt
drwxr-xr-x 2 root root 6 Oct 7 00:47 opt
drwxr-xr-x 2 root root 6 Apr 15 2020 proc
drwx------ 2 root root 37 Oct 7 00:58 root
drwxr-xr-x 5 root root 58 Oct 7 00:58 run
lrwxrwxrwx 1 root root 8 Oct 7 00:47 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Oct 7 00:47 srv
drwxr-xr-x 2 root root 6 Apr 15 2020 sys
drwxrwxrwt 2 root root 6 Oct 7 00:58 tmp
drwxr-xr-x 13 root root 145 Oct 7 00:47 usr
drwxr-xr-x 11 root root 139 Oct 7 00:58 var
[root@l7 diff]# pwd
/var/lib/docker/overlay2/b0893f8b4bcb9d70f1fe5590e36b27681a690b14e9182f741013cdffd8f0c7e6/diff
4、Merged层
属于对外展示层,只能在运行中的容器查看,镜像是查看不了的
5、init层
init层是以一个uuid±init结尾表示,放在只读层(Lower)和读写层(upperdir)之间,
作用只是存放/etc/hosts、/etc/resolv.conf 等文件。
init层作用:
-
1、容器在启动以后, 默认情况下lower层是不能够修改内容的, 但是用户有需求需要修改主 机名与域名地址, 那么就需要添加init层中的文件(hostname, resolv.conf), 用于解决此类问 题.
-
2、修改的内容只对当前的容器生效, 而在docker commit提交为镜像时候,并不会将init层提 交。
-
3、init 文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff
2. 提交镜像
命令:
docker commit 提交容器成为新的版本或者副本
docker commit -m “提交的描述信息” -a “作者” 容器id 目标镜像名称:[tag]
启动tomcat,将webapp.dist下的文件复制到webapp中
提交镜像
[root@l4 ~]# docker commit -m “add files in webapp” -a “lidaojing” 3aa06598f3be tomcat:1.1
启动容器进入,发现webapp下已有文件