Docker 制作镜像Dockerfile和commit操作

构建镜像

构建镜像主要有两种方式:

使用docker commit命令从运行中的容器提交为镜像;

使用docker build命令从 Dockerfile 构建镜像。

首先介绍下如何从运行中的容器提交为镜像。我依旧使用 busybox 镜像举例,使用以下命令创建一个名为 busybox 的容器并进入 busybox 容器。

$ docker run --rm --name=busybox -it busybox sh

执行完上面的命令后,当前窗口会启动一个 busybox 容器并且进入容器中。在容器中,执行以下命令创建一个文件并写入内容:

/ # touch hello.txt && echo "I love Docker. " > hello.txt

此时在容器的根目录下,已经创建了一个 hello.txt 文件,并写入了 "I love Docker. "。

下面,我们新打开另一个命令行窗口,运行以下命令提交镜像:

$ docker commit busybox busybox:hello

sha256:cbc6406aaef080d1dd3087d4ea1e6c6c9915ee0ee0f5dd9e0a90b03e2215e81c

然后使用上面讲到的docker image ls命令查看镜像:

$ docker image ls busybox
REPOSITORY     TAG         IMAGE ID      CREATED       SIZE
busybox       hello        cbc6406aaef0    2 minutes ago    1.22MB
busybox       latest       018c9d7b792b    4 weeks ago     1.22MB

此时我们可以看到主机上新生成了 busybox:hello 这个镜像。

通过对比显然使用Dockerfile的docker build更好。docker commit的缺点如下:

需要在容器内操作麻烦,效率低。

这一点也是最重要的,其他人或者过一段时间后自己也不知道这个镜像是怎么做出来的,但是使用Dockerfile构建的镜像,我们看到是执行了apt-get install命令。

第二种方式是最重要也是最常用的镜像构建方式:Dockerfile。Dockerfile 是一个包含了用户所有构建命令的文本。通过docker build命令可以从 Dockerfile 生成镜像。

使用 Dockerfile 构建镜像具有以下特性:

Dockerfile 的每一行命令都会生成一个独立的镜像层,并且拥有唯一的 ID

Dockerfile 的命令是完全透明的,通过查看 Dockerfile 的内容,就可以知道镜像是如何一步步构建的

Dockerfile 是纯文本的,方便跟随代码一起存放在代码仓库并做版本管理

看到使用 Dockerfile 的方式构建镜像有这么多好的特性,你是不是已经迫不及待想知道如何使用了。别着急,我们先学习下 Dockerfile 常用的指令。

Dockerfile 指令 指令简介
FROM Dockerfile 除了注释第一行必须是 FROM ,FROM 后面跟镜像名称,代表我们要基于哪个基础镜像构建我们的容器。
RUN RUN 后面跟一个具体的命令,类似于 Linux 命令行执行命令。
ADD 拷贝本机文件或者远程文件到镜像内
COPY 拷贝本机文件到镜像内
USER 指定容器启动的用户
ENTRYPOINT 容器的启动命令
CMD CMD 为 ENTRYPOINT 指令提供默认参数,也可以单独使用 CMD 指定容器启动参数
ENV 指定容器运行时的环境变量,格式为 key=value
ARG 定义外部变量,构建镜像时可以使用 build-arg = 的格式传递参数用于构建
EXPOSE 指定容器监听的端口,格式为 [port]/tcp 或者 [port]/udp
WORKDIR 为 Dockerfile 中跟在其后的所有 RUN、CMD、ENTRYPOINT、COPY 和 ADD 命令设置工作目录。

看了这么多指令,感觉有点懵?别担心,我通过一个实例让你来熟悉它们。这是一个 Dockerfile:

FROM centos:7
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum install -y nginx
EXPOSE 80
ENV HOST=mynginx
CMD ["nginx","-g","daemon off;"]

第一行表示我要基于 centos:7 这个镜像来构建自定义镜像。这里需要注意,每个 Dockerfile 的第一行除了注释都必须以 FROM 开头。

第二行表示拷贝本地文件 nginx.repo 文件到容器内的 /etc/yum.repos.d 目录下。这里拷贝 nginx.repo 文件是为了添加 nginx 的安装源。

第三行表示在容器内运行yum install -y nginx命令,安装 nginx 服务到容器内,执行完第三行命令,容器内的 nginx 已经安装完成。

第四行声明容器内业务(nginx)使用 80 端口对外提供服务。

第五行定义容器启动时的环境变量 HOST=mynginx,容器启动后可以获取到环境变量 HOST 的值为 mynginx。

第六行定义容器的启动命令,命令格式为 json 数组。这里设置了容器的启动命令为 nginx ,并且添加了 nginx 的启动参数 -g 'daemon off;' ,使得 nginx 以前台的方式启动。

镜像的实现原理

其实 Docker 镜像是由一系列镜像层(layer)组成的,每一层代表了镜像构建过程中的一次提交。下面以一个镜像构建的 Dockerfile 来说明镜像是如何分层的。

FROM busybox

COPY test /tmp/test

RUN mkdir /tmp/testdir

上面的 Dockerfile 由三步组成:

第一行基于 busybox 创建一个镜像层;

第二行拷贝本机 test 文件到镜像内;

第三行在 /tmp 文件夹下创建一个目录 testdir。

这里我的 Docker 使用的是 overlay2 文件驱动,进入到/var/lib/docker/overlay2目录下使用tree .命令查看产生的镜像文件:

$ tree .

# 以下为 tree . 命令输出内容

|-- 3e89b959f921227acab94f5ab4524252ae0a829ff8a3687178e3aca56d605679

|  |-- diff # 这一层为基础层,对应上述 Dockerfile 第一行,包含 busybox 镜像所有文件内容,例如 /etc,/bin,/var 等目录

... 此次省略部分原始镜像文件内容

|  `-- link 

|-- 6591d4e47eb2488e6297a0a07a2439f550cdb22845b6d2ddb1be2466ae7a9391

|  |-- diff  # 这一层对应上述 Dockerfile 第二行,拷贝 test 文件到 /tmp 文件夹下,因此 diff 文件夹下有了 /tmp/test 文件

|  |  `-- tmp

|  |    `-- test

|  |-- link

|  |-- lower

|  `-- work

|-- backingFsBlockDev

|-- bec6a018080f7b808565728dee8447b9e86b3093b16ad5e6a1ac3976528a8bb1

|  |-- diff # 这一层对应上述 Dockerfile 第三行,在 /tmp 文件夹下创建 testdir 文件夹,因此 diff 文件夹下有了 /tmp/testdir 文件夹

|  |  `-- tmp

|  |    `-- testdir

|  |-- link

|  |-- lower

|  `-- work

...

通过上面的目录结构可以看到,Dockerfile 的每一行命令,都生成了一个镜像层,每一层的 diff 夹下只存放了增量数据,如图 2 所示。

分层的结构使得 Docker 镜像非常轻量,每一层根据镜像的内容都有一个唯一的 ID 值,当不同的镜像之间有相同的镜像层时,便可以实现不同的镜像之间共享镜像层的效果。

总结一下, Docker 镜像是静态的分层管理的文件组合,镜像底层的实现依赖于联合文件系统(UnionFS)。充分掌握镜像的原理,可以帮助我们在生产实践中构建出最优的镜像,同时也可以帮助我们更好地理解容器和镜像的关系。

总结

到此,相信你已经对 Docker 镜像这一核心概念有了较深的了解,并熟悉了 Docker 镜像的常用操作(拉取、查看、“重命名”、删除和构建自定义镜像)及底层实现原理。

镜像操作命令:

拉取镜像,使用 docker pull 命令拉取远程仓库的镜像到本地 ;

重命名镜像,使用 docker tag 命令“重命名”镜像 ;

查看镜像,使用 docker image ls 或 docker images 命令查看本地已经存在的镜像;

删除镜像,使用 docker rmi 命令删除无用镜像 ;

构建镜像,构建镜像有两种方式。第一种方式是使用 docker build 命令基于 Dockerfile 构建镜像,也是我比较推荐的镜像构建方式;第二种方式是使用 docker commit 命令基于已经运行的容器提交为镜像。

镜像的实现原理:

镜像是由一系列的镜像层(layer )组成,每一层代表了镜像构建过程中的一次提交,当我们需要修改镜像内的某个文件时,只需要在当前镜像层的基础上新建一个镜像层,并且只存放修改过的文件内容。分层结构使得镜像间共享镜像层变得非常简单和方便。

以上这篇Docker 制作镜像Dockerfile和commit操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Docker配置阿里云镜像加速pull的实现

    今天使用docker拉取镜像,那速度简直不能看,而且等着等着到最后还出现了 read tcp 192.168.31.60:55550->104.18.123.25:443: read: connection reset by peer 传输异常 然后看见网上说可以配置阿里云提供的镜像加速 具体方式 进入阿里云的容器镜像服务 快速链接: 容器镜像服务 复制加速器的地址 在/etc/docker目录下找到在daemon.json文件(没有就新建),将下面内容写入 { "registry-mir

  • docker 打包本地镜像,并到其他机器进行恢复操作

    1.使用docker images查看本机所有的镜像文件 2.docker save eb40dcf64078> /root/mydjango-save-1016.tar 将镜像保存为本地文件,其中eb40dcf64078为image id 3.将保存到本地的文件上传到不能pull的服务器上,网络是相通的我这里直接使用的是scp命令 4.使用load方法加载刚才上传的tar文件 docker load < /root/mydjango-save-1016.tar 5.在新的机器上再此使用doc

  • Docker 配置阿里云容器服务操作

    配置阿里云Docker容器服务 登录 阿里云镜像服务控制台 首先要有一个自己的阿里云账号 1.点击名称空间,建议用自己名字/公司名字 比如叫 aliyun-stg 创建完成名字空间 2.点击镜像仓库,创建镜像,填写细信息 仓库可以使用Redis mysql 等名字进行管理 创建仓库 3.观察创建好后的信息 registry.cn-beijing.aliyuncs.com/aliyun-stg/flask 阿里docker域名 registry.cn-beijing.aliyuncs.com 我自

  • Docker Gitlab+Jenkins+Harbor构建持久化平台操作

    CI/CD概述 CI工作流程设计 Git 代码版本管理系统 只能命令行去管理git Gitlab 基于git做了图形管理页面,企业使用gitlab做私有的代码管理仓库 Github 公共代码管理仓库 搭建gitlab 搭建gitlab先创建工作目录,因为有些数据需要持久化 [root@www ~]# mkdir -p /gitlab [root@www ~]# cd /gitlab/ docker run -d \ --name gitlab \ -p 8443:443 \ -p 9999:80

  • Docker镜像的制作,上传,拉取和部署操作(利用阿里云)

    由于学习过程中发现push镜像的时候一直超时,所以直接把阿里云的Docker仓库申请一个(管理中心–>创建镜像仓库–>我的是华东2绑定github账户即可),搞定!以后push就用这个仓库,pull的时候使用加速器,注意切换根据使用场景进行切换,dockerhub丢弃--记录了一下操作流程: 1.创建命名空间hhu(以当前学校为单位,只能小写,每个账号只能创建5个),创建菜鸟Docker镜像仓库docker1(绑定github中某个仓库,个人可以随意,这个仓库镜像就像是一个app,可以不断的更

  • Docker 容器监控原理及 cAdvisor的安装与使用说明

    生产环境中监控容器的运行状况十分重要,通过监控我们可以随时掌握容器的运行状态,做到线上隐患和问题早发现,早解决. 所以今天我就和你分享关于容器监控的知识(原理及工具 cAdvisor). 虽然传统的物理机和虚拟机监控已经有了比较成熟的监控方案,但是容器的监控面临着更大的挑战,因为容器的行为和本质与传统的虚拟机是不一样的,总的来说,容器具有以下特性: 容器是短期存活的,并且可以动态调度 容器的本质是进程,而不是一个完整操作系统 由于容器非常轻量,容器的创建和销毁也会比传统虚拟机更加频繁 Docke

  • Docker重命名镜像名称和TAG操作

    使用docker images时,可能会出现REPOSITORY和TAG均为none的镜像,如下图 这时,我们可以重命名镜像 # docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签) 补充知识:docker image 重命名 docker image 名称不小心写错了,例如想命名为 ubuntu1604-arm-qt,写成了 unbuntu1604-arm-qt.如何改回来? 用 docker tag 重命名 docker images 找到image_

  • Docker 制作镜像Dockerfile和commit操作

    构建镜像 构建镜像主要有两种方式: 使用docker commit命令从运行中的容器提交为镜像: 使用docker build命令从 Dockerfile 构建镜像. 首先介绍下如何从运行中的容器提交为镜像.我依旧使用 busybox 镜像举例,使用以下命令创建一个名为 busybox 的容器并进入 busybox 容器. $ docker run --rm --name=busybox -it busybox sh 执行完上面的命令后,当前窗口会启动一个 busybox 容器并且进入容器中.在

  • Docker制作镜像的完整过程

    目录 前言 创建步骤 创建CentOS基础镜像 创建容器并自定义 以自定义容器创建新镜像 保存.加载镜像tar包 将镜像推送到远程仓库 参考链接 前言 以制作CentOS镜像为例,讲述对镜像自定义,打包以及推送的远程仓库的过程,步骤都比较简单可以快速上手. 创建步骤 创建CentOS基础镜像 创建构建目录和Dockerfile,在Dockerfile中编辑镜像相关设置. echo "在当前用户目录下创建创建目录docker/build/centos_7.8.2003" > /de

  • Docker中Dockerfile制作镜像的方法步骤

    目录 1.基于容器制作 2. 基于Dockerfile制作镜像 2.1 Dockerfile命令 2.2 简单示例 docker 镜像的制作,可以基于容器创建镜像,也可基于 dockerfile 构建镜像.但需要注意的是,我们并不是真正"创建"新镜像,而是基于一个已有的基础镜像,如 centos 或 ubuntu 等,构建新镜像而已. 1.基于容器制作 联合文件系统(UnionFS)挂载提供了容器的文件系统,任何对容器内文件系统的改动都会被写入到新的文件层中,这个文件层归创建它的容器所

  • Docker镜像的commit操作示例及作用

    目录 Docker 镜像是什么 UnionFS(联合文件系统) Docker 镜像加载原理 分层的镜像 Docker 镜像 commit 操作 docker commit 能做什么 案例演示 Docker 镜像是什么 UnionFS(联合文件系统) UnionFS(联合文件系统):Union文件系统是一种分层.轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a

  • Docker中镜像构建文件Dockerfile与相关命令的详细介绍

    前言 使用docker build命令或使用Docker Hub的自动构建功能构建Docker镜像时,都需要一个Dockerfile文件.Dockerfile文件是一个由一系列构建指令组成的文本文件,docker build命令会根据这些构建指令完成Docker镜像的构建.本文将会介绍Dockerfile文件,及其中使用的构建指令. 1. Dockerfile文件使用 docker build命令会根据Dockerfile文件及上下文构建新Docker镜像.构建上下文是指Dockerfile所在

  • Docker的镜像制作与整套项目一键打包部署的实现

    Dockerfile常用指令介绍 指令 描述 FROM 构建的新镜像是基于哪个镜像.例如:FROM centos:6 MAINTAINER 镜像维护者姓名或邮箱地址.例如:MAINTAINER Mr.chen RUN 构建镜像时运行的Shell命令.例如:RUN ["yum","install","httpd"]   或者RUN yum install httpd CMD 运行容器时执行的Shell命令(可以被运行时传递的参数覆盖).例如:CMD

  • 详解docker 制作mysql镜像并自动安装脚本

    centos7环境下 一键制作mysql docker镜像,并安装 centos7环境下 一键制作mysql docker镜像,并安装 shell脚本内容如下: #docker自动安装mysql echo -e "\033[32m '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&

  • 使用Docker制作Python环境连接Oracle镜像

    目录 Python连接Oracle本地测试 依赖安装准备 制作Docker镜像 Python连接Oracle本地测试 依赖安装准备 Python.链接Oracle需要Python依赖和本地Oracle客户端,测试环境Oracle版本12.1.0.2.0,开发和测试环境为linux,先安装linux客户端,选择zip解压免安装版本 Oracle linux客户端 解压到某个目录 unzip instantclient-basic-linux.x64-12.1.0.2.0.zip 解压后新建/net

  • docker官方镜像下载及使用Dockerfile创建镜像的方法

    1.登陆docker hut官方网站:https://hub.docker.com/ 2.search centos 3.docker pull centos:7.2.1511 4.创建Dockerfile文件: [root@vmhost centos7.2]# cat Dockerfile [plain] view plain copy FROM centos:7.2.1511 MAINTAINER wanghongwei(wanghongwei@4paradigm.com) RUN yum

  • 利用Docker制作Nginx+PHP镜像的步骤详解

    前言 这篇文章给大家介绍的是使用Docker制作nginx+php的镜像,本文里的镜像是centos + nginx 1.9.7 + php 5.6.14,下面话不多说,直接看实现的步骤吧. 1.首先下载到nginx和php: nginx-1.9.5.tar.gz 下载:http://nginx.org/en/download.html php-5.6.14.tar.gz   下载:>http://php.net/downloads.php 2.以及扩展包so: memcache-2.2.4.t

随机推荐