
0x03 Docker镜像详解
镜像是什么
镜像是是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
Docker 镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加同时可以将不同目录挂在到同一个虚拟文件系统下(unite serveral 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。
rootfs(root file system),在bootfs之上。包含的就是典型的Linux系统中的/dev、/proc、/bin、/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu、CentOS等。
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以。由此可见对不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用。
分层理解
当我们在下载一个镜像时,发现这个镜像时分层下载的。
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
7d63c13d9b9b: Pull complete
a2c3b174c5ad: Pull complete
283a10257b0f: Pull complete
7a08c63a873a: Pull complete
0531663a7f55: Pull complete
9bf50efb265c: Pull complete
Digest: sha256:a89cb097693dd354de598d279c304a1c73ee550fbfff6d9ee515568e0c749cfe
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
Docker为什么要采用这种分层结构?
最大的好处是资源共享,比入有多个镜像都从相同额Base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过`docker image inspect`命令
docker image inspect redis
所有的Docker镜像都其实于一个基础镜像,当进行修改或增加新的内容是,就会在当前镜像层之上创建新的镜像层。
例如:基于Ubuntu Linux 16.04创建的一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。
在添加额外的镜像层的同时,镜像使用保持是当前所有镜像的组合。
如果在上图的场景中文件5假设为一个APP版本为1.0,然后一个新增的第三层文件7是一个APP,版本为2.0,这种场景下,第三层文件系统的文件7会覆盖掉第二层文件系统的文件5。
在这种情况下,上层镜像中的文件覆盖了底层镜像层中的文件。这样是的文件的更新版本作为新歌新镜像层添加到镜像中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证对外展示为统一的文件系统。
Linux上可以用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,美中存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持Windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW
下图为三层合并后的视图
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们通常说的容器层,容器之下的叫镜像层。# #
commit镜像
docker commit # 提交容器成为一个新的副本
docker commit -m "对本次提交内的描述" -a "作者信息" 容器id 目标镜像名:[TAG版本号]
测试
# 启动一个tomcat
[root@localhost ~]# docker run -itd -p 8080:8080 tomcat /bin/bash
281ad2d97fb8a2a2620588f0377e9b44dad48f168de8c2c04606701485467fb8
# 进入容器,并查看webapps下文件(官方默认镜像webapps下没有文件,测试页面在webapps.dist下)
[root@localhost ~]# docker exec -it 281ad2d97fb8 /bin/bash
root@281ad2d97fb8:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@281ad2d97fb8:/usr/local/tomcat# cd webapps
root@281ad2d97fb8:/usr/local/tomcat/webapps# ls
root@281ad2d97fb8:/usr/local/tomcat/webapps#
# 将webapps.dist下文件复制到webapps下
root@281ad2d97fb8:/usr/local/tomcat# cp -r webapps.dist/* webapps/
root@281ad2d97fb8:/usr/local/tomcat# ls webapps
ROOT docs examples host-manager manager
root@281ad2d97fb8:/usr/local/tomcat#
在浏览器中访问创建好的容器,发现可以正常访问了
# 将修改过的容器通过commit提交成新的镜像
[root@localhost ~]# docker commit -m="add apps" -a="NowSec" 6bea3991a562 nowsectomcat:1.0
sha256:20b3c05f006f2f477cdea81f7c413011005e9cbf1e36b4f643709bb13131b509
# 查看制作好的镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nowsectomcat 1.0 20b3c05f006f 45 seconds ago 684MB
tomcat latest b0e0b0a92cf9 30 hours ago 680MB
redis latest 7faaec683238 10 days ago 113MB
Docker容器数据卷
什么是容器数据卷
当我们使用docker容器的时候,会产生一些数据,这些数据会随着docker容器的关闭而消失,但是有些时候产生的数据我们是希望他能够保存下来的。Docker将应用于运行观景大包成容器发布,我们希望在运行的时候产生的部分数据是可以持久化的,而且容器之间我们希望能够实现数据共享。
> 容器数据卷的特点
1、数据卷可以在入容器之间共享或重用
2、数据卷中的更改可以直接生效
3、数据卷中的更改不会包含在镜像的更新中
4、数据卷的生命周期一直持续到没有容器使用它未知
添加数据卷的方式
1、通过命令行挂载
docker run -it -v 宿主机绝对路径:容器内绝对路径 镜像名
[root@localhost ~]# docker run -itd -v /opt/test:/home centos
cc1255b353d62d0761bedbc29897705985b5811d903c426ee89e79bb6a129640
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc1255b353d6 centos "/bin/bash" 3 seconds ago Up 2 seconds inspiring_leakey
8c9eb507a4b4 portainer/portainer "/portainer" 2 days ago Up 9 hours 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp focused_ishizaka
[root@localhost ~]# ls /opt/
containerd test
2、检查挂载
docker inspect 容器id
"Mounts": [
{
"Type": "bind",
"Source": "/opt/test", # 宿主机路径
"Destination": "/home", # 容器内路径
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}