1、镜像是什么
镜像是一个轻量级、可执行的独立软件包,用于包装软件运行环境和基于运行环境开发的软件,包括代码、运行、库、环境变量和配置文件。
所有应用程序直接打包docker镜像,可以直接跑!
-
从远程仓库下载
-
自己制作镜像 DockerFile
2、Docker 镜像加载原理
UnionFS( 联合文件系统 )
UnionFS ( 联合文件系统 ): Union文件系统( UnionFS )它是一种分层、轻量级、高性能的文件系统,支持文件系统的修改作为层层叠加,同时,可以将不同的目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。Union文件系统是Docker镜像的基础。基于基础镜像(无父镜像),可以通过分层继承镜像,制作各种具体的应用镜像。
特性︰同时加载多个文件系统,但从外部看,只能看到一个文件系统。联合加载将叠加各级文件系统,使最终文件系统包含所有底层文件和目录
Docker 镜像加载原理
docker镜像实际上是由一层一层的文件系统组成的,这个级别的文件系统UnionFS。
bootfs(boot file system)主要包含 bootloader 和 kernel, bootloader主要是引导加载kernel, Linux启动时会加载 bootfs 文件系统,在Docker镜像的底层是bootfs。这一层和我们是典型的 Linux/Unix 系统是一样的,包括boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs将其转移到内核系统也会卸载bootfs。
rootis (root fle system),在bootfs以上。包含的是典型的 Linux 系统中的/dev、 /proc、 /bin、/etc等标准目录和文件。rootfs 是各种操作系统的发行版,如Ubuntu ,Centos等等。
图片来源:Docker分层原理和内部结构_runner668的博客-CSDN博客_docker分层原理
我们通常安装在虚拟机中CentOS都是好几个G,为什么Docker这里才200M ?
对于精简OS, rootfs 它可以很小,只需要包含最基本的命令、工具和程序库,因为底层直接使用Host的kernel ,你只需要提供rootfs可以。由此可见,不同的linux发行版, bootfs基本一致, rootfs会有差异,所以不同的发行版开使用bootfs。
3、分层理解
分层的镜像
我们可以下载一个镜像,观察下载的日志输出,看到一层一层下载!
我认为最大的好处是资源共享!例如,许多镜像来自同一个镜像Base当镜像构建时,宿主机只需在磁盘上保留一个base镜像只需要在内存中加载一个base镜像可以为所有容器服务,镜像的每一层都可以共享。
通过检查镜像分层,可以查看镜像分层 docker image inspect
命令!
[root@localhost ~]$ docker image inspect redis:latest [ {
...... "RootFS": {
"Type": "layers", "Layers": [ "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f", "sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb", "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1", "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372", "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed", "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952" ] }, ...... } ]
理解
所有的 Docker 镜像始于基本的镜像层。当修改或添加新内容时,将在当前镜像层上创建新的镜像层。
以一个简单的例子为基础 Ubuntu Linux 16.04 创建新的镜像,这是新镜像的第一层; 若将其添加到镜像中 Python 第二个镜像层将在基本镜像层上创建; 如果继续添加安全补丁,将创建第三个镜像层。
目前,该镜像已包含三个镜像层,如下图所示(这只是一个非常简单的演示例子)。
在添加额外的镜像层的同时,镜像始终是所有镜像的组合,理解这一点非常重要。下图中有一个简单的例子,每个镜像层包含三个文件,两个镜像层包含六个文件。
上图中的镜像层与上图中的镜像层略有不同,主要目的是便于显示文件。
下图显示了一个稍微复杂的三层镜像,外部只有6个文件,因为上层的文件7是文件5的更新版本。
在这种情况下,上镜像层中的文件覆盖了底镜像层中的文件。这使得文件的更新版本作为一个新的镜像层添加到镜像中。
Docker镜像层堆栈通过存储引擎(新版本采用快照机制)实现,多镜像层显示为统一的文件系统。
Linux可用的存储引擎有AUFS、Overlay2、Device Maper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持 windowsfilter一种存储引擎,该引擎基于NTFS 文件系统之上实现了分层和CoW[1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
4、Commit 镜像
docker commit # 提交一个容器成为一个新的副本 # 命令和 Git 类似 docker commit -m="提交的描述信息" -a="指定镜像作者" [容器 ID] [指定要创建的目标镜像名]:[Tag
标签]
测试
注意:阿里云里的 tomcat 镜像的 webapps 下没有任何文件
# 阿里云里的 tomcat 的 webapps 下没有任何文件
# 启动 Tomcat 容器
[root@localhost ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 9.0 b8e65a4d736d 6 months ago 680MB
[root@localhost ~]$ docker run -it -p 8080:8080 tomcat:9.0
新终端打开
# 进入容器
[root@localhost ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8398ac52bc49 tomcat:9.0 "catalina.sh run" 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp cool_sutherland
[root@localhost ~]$ docker exec -it 8398ac52bc49 /bin/bash
webapps.dist 目录下的应用拷贝到 为空的 webapps 目录
# 操作容器
# webapps.dist 目录下的应用拷贝到 为空的 webapps 目录
root@8398ac52bc49:/usr/local/tomcat$ cd webapps
root@8398ac52bc49:/usr/local/tomcat/webapps$ ls
root@8398ac52bc49:/usr/local/tomcat/webapps$ cd ../
root@8398ac52bc49:/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
# -r 递归
root@8398ac52bc49:/usr/local/tomcat$ cp -r webapps.dist/* webapps
root@8398ac52bc49:/usr/local/tomcat$ cd webapps
root@8398ac52bc49:/usr/local/tomcat/webapps$ ls
ROOT docs examples host-manager manager
root@8398ac52bc49:/usr/local/tomcat/webapps$ exit
exit
[root@localhost ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8398ac52bc49 tomcat:9.0 "catalina.sh run" 13 minutes ago Up 13 minutes 0.0.0.0:8080->8080/tcp cool_sutherland
[root@localhost ~]$ docker commit -a="mianbao" -m="add webapps app" 8398ac52bc49 mytomcat:1.0
sha256:3b3325451acea4dc8ba89a54f65876a54b80caa337574b5231eb2536fa57b001
[root@localhost ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat 1.0 3b3325451ace 2 minutes ago 685MB
tomcat 9.0 b8e65a4d736d 6 months ago 680MB
如果你想保存当前容器的状态,就可以通过 commit
来提交,获得一个镜像。
就好比虚拟机的 !