docker镜像

三、docker镜像

1-是什么

​ 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
镜像是千层饼一层套一层的花卷
Docker 镜像是由文件系统叠加而成(是一种文件的存储形式)。最底端是一个文件引 导系统,即 bootfs,这很像典型的 Linux/Unix 的引导文件系统。Docker 用户几乎永远不会和 引导系统有什么交互。实际上,当一个容器启动后,它将会被移动到内存中,而引导文件系 统则会被卸载,以留出更多的内存供磁盘镜像使用。Docker 容器启动是需要一些文件的, 而这些文件就可以称为 Docker 镜像。

Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。
1. image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
2.image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成
3.image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用
4.为了方便共享,image 文件制作完成后,可以上传到网上的仓库。

UnionFS联合文件系统)(底层实现)

​ UnionFS(联合文件系统):是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

​ 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

2- 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等等。

平时我们安装进虚拟机的****CentOS都是好几个G,为什么docker这里才200M??

​ 对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。共用内核

2.1分层的镜像

以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载

2.2为什么 Docker 镜像要采用这种分层结构呢?

​ 最大的一个好处就是 - 共享资源

​ 比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,

​ 同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。![tomcat idk8 kernel ]

3、特点

​ Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

4.镜像使用

4.1列出镜像列表

​ docker images

4.2获取一个新的镜像

​ docker pull

4.3查找镜像

​ docker search httpd

​ 4.4拖取镜像

​ docker pull httpd

​ 下载完成后,我们就可以使用这个镜像了。

runoob@runoob:~$ docker run httpd

4.5删除镜像

镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:

$ docker rmi hello-world

4.6创建镜像

​ 1、从已经创建的容器中更新镜像,并且提交这个镜像(对原有镜像的更改)

​ 2、使用 Dockerfile 指令来创建一个新的镜像

4.6.1更新镜像

​ 1.更新镜像之前,我们需要使用镜像来创建一个容器。

​ 2.对镜像进行操作

​ 3.exit镜像

​ 4.commit提交容器成为一个新镜像

​ @@.commit这种操作不建议操作,因为相当于一个黑盒子操作,其他人不知道执行了哪些操作,只有创建人知道。镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础

​ Docker镜像commit操作**

​ docker commit提交容器副本使之成为一个新的镜像

​ docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

案例演示

1.从Hub上下载nginx镜像到本地并成功运行

docker run -it -p 80:80 nginx

​ -p 主机端口:docker容器端口

​ -P 随机分配端口

​ i:交互

​ t:终端

2.故意更改上一步镜像生产nginx容器的默认页面

3.在浏览器查看

4.docker diff mynginx查看具体改动

5.commit

docker commit --author "Wang QH" --message "修改了默认页面" mynginx nginx:1.0

6.docker history nginx:1.0 查看镜像内的历史,比较nginx:latest的历史记录

7.运行新的镜像nginx:1.0

8.以上已经完成了镜像的更新,但是慎用docker commit 。我手动给旧的镜像添加了新的一层,形成新的镜像,再提交。但是发现commit后的镜像,我仅仅修改了一个HTML页面,但是其镜像的文件很多都被修改了,而其他人不知道我做了什么更改,这对工作十分不便。镜像使用的分层存储的概念,除了当前层外的每一层都不会改变,那么用commit制作的话,则每次修改的都会让镜像臃肿一次,上一层的东西不会丢失,会跟随着镜像,这对轻量级的docker来说是不便的。

所以可以采用第二种dockerfile定制镜像,写在一个脚本中进行定制。

posted on 2019-12-03 08:07  不浮泛  阅读(381)  评论(0编辑  收藏  举报

导航