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 下,多条命令应该用 && 连接,并且在最后要打扫干净所使用的环境。比如下面这段摘自官方 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代码打造刷脸考勤系统

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

真香,朕在看了!

Docker精华问答 | Docker commit如何用?相关推荐

  1. Docker精华问答 | Docker vs VM

    在计算机技术日新月异的今天, Docker 在国内发展的如火如荼.特别是在一线互联网公司 Docker 的使用是十分普遍的,甚至成为了一些企业面试的加分项,那么今天我们继续关于Docker 的精华问答 ...

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

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

  3. dockerfile如何运行镜像内的脚本_Docker精华问答 | Docker commit如何用?

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

  4. Docker精华问答 | Consul是什么?

    在计算机技术日新月异的今天, Docker 在国内发展的如火如荼.特别是在一线互联网公司 Docker 的使用是十分普遍的,甚至成为了一些企业面试的加分项,那么今天我们继续关于Docker 的精华问答 ...

  5. Docker精华问答 | 数据库为什么不适合放在 Docker 中运行?

    戳蓝字"CSDN云计算"关注我们哦! Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux或Windo ...

  6. Docker精华问答 | 多个 Docker 容器之间共享数据怎么办?

    在计算机技术日新月异的今天, Docker 在国内发展的如火如荼.特别是在一线互联网公司 Docker 的使用是十分普遍的,甚至成为了一些企业面试的加分项,那么今天我们继续关于Docker 的精华问答 ...

  7. Docker精华问答:Docker与虚拟机的区别?| 技术头条

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

  8. Docker精华问答 | task与executor有什么关系?

    戳蓝字"CSDN云计算"关注我们哦! 容器技术是这两年热门的话题,因为容器技术给我们带来了很多方便的地方,节约了不少成本,不管是在运维还是开发上.今天,就让我们来看看关于Docke ...

  9. Docker精华问答 | 如何让一个容器连接两个网络?

    如今Docker的使用已经非常普遍,特别在一线互联网公司.使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力.在云服务概念兴起之后,Docker的使用场景和范围进一步发展.今 ...

最新文章

  1. selenium 等待页面加载完成
  2. 栈(Stack),轻松解决数制转换和括号匹配问题!
  3. BugkuCTF-MISC题where is flag2
  4. angular2或4部署到tomcat中,让他跑起来
  5. 二叉查找树与平衡二叉树【转载】
  6. oracle表访问方式
  7. TensorFlow 2 Object Detection API 教程: model 命名规则
  8. VS2017离线下载及安装方式
  9. 6,JESD204B接口简介
  10. PythonC++相互混合调用编程全面实战-24QT按钮事件的Open槽函数中调用python函数
  11. 2020年11月程序员工资统计,平均14327元
  12. 应用出海之--AdMob
  13. 翟菜花:她经济的营销攻坚战,4C的用户导向才是破局之法
  14. 凉宫春日的忧郁[数学题]
  15. 教育部中央电教馆—家庭教育指导师证书
  16. 快看世界公布“神笔马良”工程 国漫借AI技术走向世界
  17. Vim中如何全选并复制?
  18. c语言中scanf(%d%*c, n);的意思。
  19. 物联网卡智能净水器打造智慧洁净生活
  20. Eureka之IpAddress:eureka.instance.prefer-ip-address = true

热门文章

  1. Symbian S60第三版手机最基本常见问题及解决方案
  2. Java实现按键精灵(鼠标篇)
  3. vscode侧边栏Git源代码管理器丢了?
  4. QQ2009、QQ2010、QQ2011远程攻击漏洞,详细使用方法。
  5. peek和pop的区别
  6. 【微信读书】 《乔布斯传》Walter Isaacson 读书笔记
  7. Python 下载贴吧图片到指定地址
  8. python贴吧顶贴_贴吧回复app-贴吧回复(贴吧顶贴神器手机版)v3.2.5-西西软件下载...
  9. 书法学习要学会什么?
  10. Unity获取安卓手机运营商信息