Docker 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!

1

Q:Docker commit如何用?

A:简单的回答就是,不要用 commit,去写 Dockerfile。

Docker 不是虚拟机。这句话要在学习 Docker 的过程中反复提醒自己。所以不要把虚拟机中的一些概念带过来。Docker 提供了很好的 Dockerfile 的机制来帮助定制镜像,可以直接使用 Shell 命令,非常方便。而且,这样制作的镜像更加透明,也容易维护,在基础镜像升级后,可以简单地重新构建一下,就可以继承基础镜像的安全维护操作。

使用 docker commit 制作的镜像被称为黑箱镜像,换句话说,就是里面进行的是黑箱操作,除本人外无人知晓。即使这个制作镜像的人,过一段时间后也不会完整的记起里面的操作。那么当有些东西需要改变时,或者因基础镜像更新而需要重新制作镜像时,会让一切变得异常困难,就如同重新安装调试配置服务器一样,失去了 Docker 的优势了。

另外,Docker 不是虚拟机,其文件系统是 Union FS,分层式存储,每一次 commit 都会建立一层,上一层的文件并不会因为 rm 而删除,只是在当前层标记为删除而看不到了而已,每次 docker pull 的时候,那些不必要的文件都会如影随形,所得到的镜像也必然臃肿不堪。而且,随着文件层数的增加,不仅仅镜像更臃肿,其运行时性能也必然会受到影响。这一切都违背了 Docker 的最佳实践。

使用 commit 的场合是一些特殊环境,比如入侵后保存现场等等,这个命令不应该成为定制镜像的标准做法。所以,请用 Dockerfile 定制镜像。

2

Q:为什么说不要使用 import, export, save, load, commit 来构建镜像?

A:commit 命令在前一个问答已经说过,这是制作黑箱镜像,无法维护,不应该被使用。

import 和 export 的做法,实际上是将一个容器来保存为 tar 文件,然后在导入为镜像。这样制作的镜像同样是黑箱镜像,不应该使用。而且这类导入导出会导致原有分层丢失,合并为一层,而且会丢失很多相关镜像元数据或者配置,比如 CMD 命令就可能丢失,导致镜像无法直接启动。

save 和 load 确实是镜像保存和加载,但是这是在没有 registry 的情况下,手动把镜像考来考去,这是回到了十多年的 U 盘时代。这同样是不推荐的,镜像的发布、更新维护应该使用 registry。无论是自己架设私有 registry 服务,还是使用公有 registry 服务,如 Docker Hub。

3

Q:Dockerfile 怎么写?

A:最直接也是最简单的办法是看官方文档。

这篇文章讲述具体 Dockerfile 的命令语法:https://docs.docker.com/engine/reference/builder/

然后,学习一下官方的 Dockerfile 最佳实践:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/

最后,去 Docker Hub 学习那些官方(Official)镜像 Dockerfile 咋写的。

4

Q:Dockerfile 就是 Shell 脚本吧?

A:不是这样的。Dockerfile 不等于 .sh 脚本,Dockerfile 确实是描述如何构建镜像的,其中也提供了 RUN 这样的命令,可以运行 shell 命令。但是和普通 shell 脚本还有很大的不同。

Dockerfile 描述的实际上是镜像的每一层要如何构建,所以每一个RUN是一个独立的一层。所以一定要理解“分层存储”的概念。上一层的东西不会被物理删除,而是会保留给下一层,下一层中可以指定删除这部分内容,但实际上只是这一层做的某个标记,说这个路径的东西删了。但实际上并不会去修改上一层的东西。每一层都是静态的,这也是容器本身的 immutable 特性,要保持自身的静态特性。

所以很多新手会常犯下面这样的错误,把 Dockerfile 当做 shell 脚本来写了:

RUN yum update

RUN yum -y install gcc

RUN yum -y install python

ADD jdk-xxxx.tar.gz /tmp

RUN cd xxxx && install

RUN xxx && configure && make && make install

这是相当错误的。除了无畏的增加了很多层,而且很多运行时不需要的东西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。

正确的写法应该是把同一个任务的命令放到一个 RUN 下,多条命令应该用 && 连接,并且在最后要打扫干净所使用的环境。比如下面这段摘自官方 redis 镜像 Dockerfile 的部分:

RUN buildDeps='gcc libc6-dev make' && set -x && apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* && wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL" && echo "$REDIS_DOWNLOAD_SHA1 *redis.tar.gz" | sha1sum -c - && mkdir -p /usr/src/redis && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 && rm redis.tar.gz && make -C /usr/src/redis && make -C /usr/src/redis install && rm -r /usr/src/redis && apt-get purge -y --auto-remove $buildDeps

5

Q:那我把所有命令都合并到一个 RUN 就对了吧?

A:不是把所有命令都合为一个 RUN,要合理分层,以加快构建和部署。合理分层就是将具有不同变更频繁程度的层,进行拆分,让稳定的部分在基础,更容易变更的部分在表层,使得资源可以重复利用,以增加构建和部署的速度。以 node.js 的应用示例镜像为例,其中的复制应用和安装依赖的部分,如果都合并一起,会写成这样:

COPY . /usr/src/appRUN npm install

但是,在 node.js 应用镜像示例中,则是这么写的:

COPY package.json /usr/src/app/RUN npm installCOPY . /usr/src/app

从层数上看,确实多了一层。但实际上,这三行分开是故意这样做的,其目的就是合理分层,充分利用 Docker 分层存储的概念,以增加构建、部署的效率。在 docker build 的构建过程中,如果某层之前构建过,而且该层未发生改变的情况下,那么 docker 就会直接使用缓存,不会重复构建。因此,合理分层,充分利用缓存,会显著加速构建速度。

第一行的目的是将 package.json 复制到应用目录,而不是整个应用代码目录。这样只有 pakcage.json 发生改变后,才会触发第二行 RUN npm install。而只要 package.json 没有变化,那么应用的代码改变就不会引发 npm install,只会引发第三行的 COPY . /usr/src/app,从而加快构建速度。而如果按照前面所提到的,合并为两层,那么任何代码改变,都会触发 RUN npm install,从而浪费大量的带宽和时间。合理分层除了可以加快构建外,还可以加快部署,要知道,docker pull 的时候,是分层下载的,并且已存在的层就不会重复下载。

比如,这里的 RUN npm install 这一层,往往会几百 MB 甚至上 GB。而在 package.json 未发生变更的情况下,那么只有 COPY . /usr/src/app 这一层会被重新构建,并且也只有这一层会在各个节点 docker pull 的过程中重新下载,往往这一层的代码量只有几十 MB,甚至更小。这对于大规模的并行部署中,所节约的东西向流量是非常显著的。特别是敏捷开发环境中,代码变更的频繁度要比依赖变更的频繁度高很多,每次重复下载依赖,会导致不必要的流量和时间上的浪费。

小伙伴们冲鸭,后台留言区等着你!

关于Docker,今天你学到了什么?还有哪些不懂的?除此还对哪些话题感兴趣?快来留言区打卡啦!留言方式:打开第XX天,答:……

同时欢迎大家搜集更多问题,投稿给我们!风里雨里留言区里等你~

福利

1、扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

推荐阅读:

  • IEEE 回应禁止华为系审稿人;WiFi联盟、蓝牙联盟已恢复华为成员资格;中国计算机学会:暂时中止与IEEE通信学会合作……

  • ARM 发布新一代 CPU 和 GPU,实现 20% 性能提升!

  • 前端开发 20 年变迁史

  • 北漂杭漂的程序员,是如何买到第一套房子?

  • “爱装X”开源组织:“教科书级”AI知识树究竟长什么样?

  • 500行Python代码打造刷脸考勤系统

  • 权游播完了, 你在骂烂尾, 有人却悄悄解锁了新操作……

真香,朕在看了!

dockerfile如何运行镜像内的脚本_Docker精华问答 | Docker commit如何用?相关推荐

  1. dockerfile如何运行镜像内的脚本_如何从看不懂Dockerfile到创建自己的镜像

    开始了解Docker是健明的一篇文章跟着jimmy学docker系列之第2讲:一个软件一个容器,那时正在研究虚拟机(Virtual Machine),发现Docker更适合现在的需求,就从基本概念和操 ...

  2. dockerfile如何运行镜像内的脚本_第七章 Dockerfile文件解析(一)

    七 Dockerfile文件解析-1 7.1 定义:Dockerfile是用来构建Docker镜像的文件,是由一系列命令和参数构成的脚本 7.2 Dockerfile内容基础知识: 1.每条保留字指令 ...

  3. Linux安装Docker容器环境centos中安装docker-compose容器编排dockerfile文件构建镜像(史上最详细的docker)

    在Linux系统下安装docker容器环境 1.容器介绍 1.1 镜像(Image) 镜像可以用来创建Docker 容器,Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像, 用户甚至可 ...

  4. Docker精华问答 | Docker镜像和Docker容器的关系?

    毫无疑问,Docker成了近些年来最火热,甚至最具颠覆性的技术之一.国际上,所有泛云计算相关的公司,几乎都在某种程度上宣布支持并集成Docker.在2014年6月的DockerCon中,很多公司都分享 ...

  5. 在docker上调用宿主机硬件_Docker精华问答:Docker与虚拟机的区别?| 技术头条

    Docker 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署.测试和分发都变得前所未有的高效和轻松! 1 ...

  6. Dockerfile构建容器镜像 - 运维笔记

    在Docker的运用中,从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低.所以就需要一 种文件或脚本,我们把想执行的操作以命令的方式写入其 ...

  7. docker commit 发布自己的镜像

    1. docker images 的分层 首先我们需要理解的是docker images的分层原理 可能你看完这个还不太理解什么是分层, 不知道你是否有注意到当我们docker pull 一个imag ...

  8. 使用docker commit将修改后的容器保存为镜像及其使用注意事项

    docker commit使用示例 我们修改了容器的文件,也就是改动了容器的存储层.我们可以通过 docker diff 命令看到具体的改动. $ docker diff webserver C /r ...

  9. docker commit构建镜像(不推荐)

    dcoker commit镜像构建 获取docker镜像 # 下载镜像(默认从docker hub获取) docker pull ubuntu:14.04 搜索镜像 docker search IMA ...

最新文章

  1. 复杂性系统面临的难题
  2. 捉虫记---查看变量,整数转浮点
  3. MyBatis 实际使用案例-plugins
  4. SAP Hybris Enterprise Commerce Platform ECP和SAP CRM架构比较
  5. 7.11牛客题(指针)
  6. iphone/ipod网页开发教程及规则
  7. html js控制页面蒙版,JavaScript蒙板(model)功能的简单实现代码
  8. 记录一次json转换的经历
  9. 拓端tecdat|Python用Markowitz马克维兹有效边界构建最优投资组合可视化分析四只股票
  10. 微信小程序获取手机号 前台+php后台
  11. Code blocks调试教程
  12. C语言解释器的实现--让脚本跑起来(六)
  13. 定义m是第一个数,之后的每个数都是前一个的平方根,一共有n个数,计算总和。
  14. java 实现 excel normsdist_Excel实现的NORM NORMDIST函数中的幻数
  15. 如何卸载360安全卫士后windows系统启动项里面有360tray
  16. 调用app出现This app is not allowed to query for scheme...
  17. 2022年研究生初试成绩终于来了-文都管联院
  18. Gartner研究:在中国,混合云的采用已成为主流趋势
  19. 武大地理信息科学本科生的专业相关网站总结分享(包括制图、专业课、自学复习等)
  20. /usr/bin/ld: cannot find -lxxx 问题总结

热门文章

  1. POJ1315 UVA639 UVALive5325 Don't Get Rooked题解
  2. CCF NOI1050 矩阵乘法
  3. 趣味程序之打印字符图案系列
  4. 实用的 Python —— base64
  5. 空间波(space wave)
  6. PyCharm: Simplify chained comparison
  7. Tricks(三十八)—— 在不计算欧式距离的前提下判断点到两点的距离哪个更近
  8. 【程序的流程】—— 顺序 / 分支 / 循环
  9. vue 百度统计_2021暑期实习面经百度篇
  10. python就业方向-看完Python这五大就业方向的薪资待遇,你选择哪个?