Docker 四种制作镜像方式
Docker 镜像的构建原理和方式
Docker构建镜像的方式有多种,先介绍下最常用的两种
- 通过
docker commit
命令,基于一个已存在的容器构建出镜像。 - 编写
Dockerfile
文件,并使用docker build
命令来构建镜像。
上面这两种方法中,镜像构建的底层原理是相同的,都是通过下面 3 个步骤来构建镜像:
- 基于原镜像,启动一个 Docker 容器。在容器中进行一些操作,例如执行命令、安装文件等。
- 由这些操作产生的文件变更都会被记录在容器的存储层中。
- 将容器存储层的变更 commit 到新的镜像层中,并添加到原镜像上。
下面,具体了解这两种构建 Docker 镜像的方式。
通过docker commit
命令,基于一个已存在的容器构建出镜像
通过docker commit来构建一个镜像,命令的格式为docker commit [选项] [<仓库名>[:<标签>]]。
具体步骤如下:
- 执行
docker ps
获取需要构建镜像的容器 ID08cd43c7e50d
。 - 执行
docker pause 08cd43c7e50d
暂停08cd43c7e50d
容器的运行。 - 执行
docker commit 08cd43c7e50d redis:test
,基于容器 ID08cd43c7e50d
构建 Docker 镜像。 - 执行
docker images redis:test
,查看镜像是否成功构建。
这种镜像构建方式通常用在下面两个场景中:
- 构建临时的测试镜像;
- 容器被入侵后,使用docker commit,基于被入侵的容器构建镜像,从而保留现场,方便以后追溯。
除了这两种场景,不建议你使用docker commit来构建生产现网环境的镜像。
主要原因有两个:
- 使用docker commit构建的镜像包含了编译构建、安装软件,以及程序运行产生的大量无用文件,这会导致镜像体积很大,非常臃肿。
- 使用docker commit构建的镜像会丢失掉所有对该镜像的操作历史,无法还原镜像的构建过程,不利于镜像的维护。
编写 Dockerfile
文件,并使用docker build
命令来构建镜像
docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终 Docker 引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。
docker build的命令格式为docker build [OPTIONS] PATH | URL | -
。PATH、URL、-
指出了构建镜像的上下文(context),context 中包含了构建镜像需要的Dockerfile文件和其他文件。默认情况下,Docker 构建引擎会查找 context 中名为Dockerfile的文件,但你可以通过-f
, --file
选项,手动指定Dockerfile文件。例如:
$ docker build -f Dockerfile -t redis:test .
使用 Dockerfile 构建镜像,本质上也是通过镜像创建容器,并在容器中执行相应的指令,然后停止容器,提交存储层的文件变更。和用docker commit
构建镜像的方式相比,它有三个好处:
- Dockerfile 包含了镜像制作的完整操作流程,其他开发者可以通过 Dockerfile 了解并复现制作过程。
- Dockerfile 中的每一条指令都会创建新的镜像层,这些镜像可以被 Docker Daemnon 缓存。再次制作镜像时,Docker 会尽量复用缓存的镜像层(using cache),而不是重新逐层构建,这样可以节省时间和磁盘空间。
- Dockerfile 的操作流程可以通过docker image history [镜像名称]查询,方便开发者查看变更记录。
执行docker build后的构建流程为:
- 第一步,docker build会将 context 中的文件打包传给 Docker daemon。如果 context 中有
.dockerignore
文件,则会从上传列表中删除满足.dockerignore
规则的文件。
这里有个例外,如果.dockerignore
文件中有.dockerignore
或者Dockerfile
,docker build
命令在排除文件时会忽略掉这两个文件。如果指定了镜像的 tag,还会对 repository 和 tag 进行验证。
- 第二步,
docker build
命令向Docker server
发送 HTTP 请求,请求Docker server
构建镜像,请求中包含了需要的 context 信息。 - 第三步,
Docker server
接收到构建请求之后,会执行以下流程来构建镜像:
- 创建一个临时目录,并将 context 中的文件解压到该目录下。
- 读取并解析 Dockerfile,遍历其中的指令,根据命令类型分发到不同的模块去执行。
- Docker 构建引擎为每一条指令创建一个临时容器,在临时容器中执行指令,然后 commit 容器,生成一个新的镜像层。
- 最后,将所有指令构建出的镜像层合并,形成 build 的最后结果。最后一次 commit 生成的镜像 ID 就是最终的镜像 ID。
为了提高构建效率,docker build
默认会缓存已有的镜像层。如果构建镜像时发现某个镜像层已经被缓存,就会直接使用该缓存镜像,而不用重新构建。如果不希望使用缓存的镜像,可以在执行docker build
命令时,指定--no-cache=true
参数。
Docker 匹配缓存镜像的规则为:遍历缓存中的基础镜像及其子镜像,检查这些镜像的构建指令是否和当前指令完全一致,如果不一样,则说明缓存不匹配。对于ADD
、COPY
指令,还会根据文件的校验和(checksum)来判断添加到镜像中的文件是否相同,如果不相同,则说明缓存不匹配。
这里要注意,缓存匹配检查不会检查容器中的文件。比如,当使用RUN apt-get -y update
命令更新了容器中的文件时,缓存策略并不会检查这些文件,来判断缓存是否匹配。
最后,可以通过docker history
命令来查看镜像的构建历史,如下图所示:
通过docker save和docker load命令构建
docker save用来将镜像保存为一个 tar 文件,docker load用来将 tar 格式的镜像文件加载到当前机器上,例如:
# 在 A 机器上执行,并将 nginx-v1.0.0.tar.gz 复制到 B 机器
$ docker save nginx | gzip > nginx-v1.0.0.tar.gz# 在 B 机器上执行
$ docker load -i nginx-v1.0.0.tar.gz
通过上面的命令,我们就在机器 B 上创建了nginx镜像。
通过docker export和docker import命令构建
通过docker export 保存镜像,再通过docker import 加载镜像,具体命令如下:
# 在 A 机器上执行,并将 nginx-v1.0.0.tar.gz 复制到 B 机器
$ docker export nginx > nginx-v1.0.0.tar.gz# 在 B 机器上执行
$ docker import - nginx:v1.0.0 nginx-v1.0.0.tar.gz
通过docker export
导出的镜像和通过docker save
保存的镜像相比,会丢失掉所有的镜像构建历史。在实际生产环境中,我不建议你通过docker save和docker export这两种方式来创建镜像。
较推荐的方式是:在 A 机器上将镜像 push 到镜像仓库,在 B 机器上从镜像仓库 pull 该镜像。
Docker 四种制作镜像方式相关推荐
- Jenkins的四种安装部署方式以及Jenkins的基本配置与基本使用
Jenkins的四种安装部署方式以及Jenkins的基本配置与基本使用 安装Jenkins 1.yum安装Jenkins 下载与安装 修改配置 修改默认端口 2.基于War包的形式部署Jenkins ...
- Docker Compose搭建consul群集环境(了解Docker Compose及常用命令,Docker四种网络,Doker指定端口)
文章目录 Docker Compose搭建consul群集环境 认识Docker Compose IConsul Docker Compose容器编排 Dasker Compose配置常用字段 Bos ...
- 爆破专栏丨Spring Security系列教程之Spring Security的四种权限控制方式
原创:一一哥 前言: 在前面的章节中,一一哥 已经给大家介绍了Spring Security的很多功能,在这些众多功能中,我们知道其核心功能其实就是认证+授权. 在前面我们分别基于内存模型.基于默认的 ...
- HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令
1.上传tar包 这里我上传的是apache-hive-1.2.1-bin.tar.gz 2.解压 mkdir -p /home/tuzq/software/hive/ tar -zxvf apach ...
- java按钮权限控制_详解Spring Security 中的四种权限控制方式
Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Se ...
- ASP.NET MVC下的四种验证编程方式[续篇]
ASP.NET MVC下的四种验证编程方式[续篇] 原文:ASP.NET MVC下的四种验证编程方式[续篇] 在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET ...
- java 按钮 监听_Button的四种监听方式
Button按钮设置点击的四种监听方式 注:加粗放大的都是改变的代码 1.使用匿名内部类的形式进行设置 使用匿名内部类的形式,直接将需要设置的onClickListener接口对象初始化,内部的onC ...
- python接口自动化(十)--post请求四种传送正文方式(详解)
简介 post请求我在python接口自动化(八)–发送post请求的接口(详解)已经讲过一部分了,主要是发送一些较长的数据,还有就是数据比较安全等.我们要知道post请求四种传送正文方式首先需要先了 ...
- 计算机图片怎么截图快捷键,电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?...
电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图? 网际百科资讯 知识宝库 2020-3-18 43955 0评论 电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?给你推 ...
最新文章
- 弹出窗口以及关闭窗口
- 无需任何标记数据,几张照片就能还原出3D物体结构,自监督学习还能这样用...
- php对提交数据的验证
- CUMCM:05B DVD在线租赁
- 2021年中国在线旅游行业分析报告
- keras添加正则化全连接_第16章 Keras使用Dropout正则化防止过拟合
- 从零开始学Pytorch之数据操作
- 我的PGA我作主----搞清楚什么是真正的PGA
- 关于Myeclipse自带JDK与本机安装JDK的的区别
- cfa考试用计算机,cfa考试一定要用专用计算器么
- android 查看cad方案,安卓手机可以CAD看图吗?怎么查看接收的CAD图纸文件?
- 浩辰云建筑2021功能详细介绍
- matlab与信道编码,基于MATLAB的信道编码.doc
- WIN下静默安装MSI文件
- wamp mysql_WampServer 下载以及安装问题 以及配置远程连接MYSQL
- html中制作banner,css banner轮播图怎么做?
- Python多线程编程详解,文章比较长,需耐心浏览
- pumping lemma 泵引理
- SparkRDD函数详解
- 小苹果蹿红背后的网络营销思考
热门文章
- 情绪管理本质上是认知管理 —— 一份情绪、认知管理升级清单
- 百付宝携手瑞星 打造零风险支付平台
- 计算机关于组建网络的工作,局域网组建方法_怎么建立局域网_局域网基础知识...
- 怎样把iPhoneX手机备忘录同步到华为p20手机上?
- 编辑PDF的多级书签
- Java 全集(上)
- 在python中数据的输出用哪个函数名_在Python中,数据的输出用哪个函数名
- COM编程之三 QueryInterface
- [opencv] 练习题实现 使用轨迹栏创建颜色和画笔半径可调的Paint应用程序。有关绘制的信息,请参阅有关鼠标处理的先前教程。
- 华为OD机试真题Java实现【密室逃生游戏】真题+解题思路+代码(20222023)