加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

编写Dockerfiles的优秀实践

发布时间:2019-09-17 23:26:17 所属栏目:建站 来源:架构师之路
导读:本文档介绍了构建高效镜像的优秀实践和方法。 Docker通过从Dockerfile(按顺序包含构建给定镜像所需的所有命令的文本文件)读取命令来自动构建镜像。Dockerfile遵循特定的格式和一组命令,您可以在Dockerfile reference中找到这些命令。 Docker镜像由只读层

每个容器应该只有一个关注点。将应用程序解耦到多个容器可以更容易地水平伸缩和重用容器。例如,web应用程序栈可能由三个独立的容器组成,每个容器都有自己独特的镜像,以解耦的方式管理web应用程序、数据库和内存缓存。

限制每个容器只运行一个进程是一个很好的经验法则。但是,这并不准确。因为很多应用都会有很多进程。比如,Celery就会有很多worker进程。Apache每个request就会有一个进程。容器自己也有init进程。

所以,用你的严谨和专业来保持容器尽可能的干净和模块化。如果容器彼此依赖,可以使用Docker容器网络来确保这些容器能够通信。

保存最小数量的层

在老一点的docker版本中,保持层数的最少是非常重要的,因为要保证性能。

为了减少这样的限制,增加了一下的特性:

  • 只有指令RUN,COPY,ADD创建层。其他指令创建临时中间镜像,并且不增加构建的大小
  • 在可能的情况下,使用多阶段构建,并且只将您需要的工件复制到最终镜像中。这允许您在中间构建阶段包含工具和调试信息,而不需要增加最终映像的大小。

命令行参数排序

只要方便,可以通过对多行参数进行字母数字排序来简化后面的更改。这有助于避免包的重复,并使列表更容易更新。这也使得PRs更容易阅读和审查。在反斜杠()之前添加空格也有帮助。

下面是一个参数排列的例子:

  1. RUN apt-get update && apt-get install -y  
  2. bzr  
  3. cvs  
  4. git  
  5. mercurial  
  6. subversion 

利用构建缓存

在构建映像时,Docker逐步读取 Dockerfile中的指令,并且按照顺序执行。在检查每条指令时,Docker会在缓存中查找可以重用的现有镜像,而不是创建一个新的(重复的)镜像。

如果,你就是不想用cache,可以使用—no-cache=true来关闭在执行docker build的时候。当然,如果你开启了cacha,docker 在构建是找到缓存,如果没有匹配到,就创建新的镜像。 Docker遵循的基本规则如下:

  • 从缓存中已经存在的父镜像开始,将下一条指令与从该基本镜像派生的所有子镜像进行比较,看看其中一条是否使用完全相同的指令构建。否则,缓存将无效
  • 在大多数情况下,只需将Dockerfile中的指令与其中一个子镜像进行比较就足够了。然而,某些指示需要更多的检查和解释。
  • 对于ADD和COPY指令,将检查镜像中文件的内容,并且检查和校验每个文件 。最后修改时间和最后访问时间不会被校验。在缓存查找期间,将校验和与现有镜像中的校验和进行比较。如果文件中有任何更改,比如内容和元数据,那么缓存将无效。
  • 除了ADD和COPY命令外,缓存检查不会查看容器中的文件来确定缓存匹配。例如,在处理RUN apt-get -y update命令时,不会检查容器中更新的文件,以确定是否存在缓存命中。在这种情况下,仅使用命令字符串本身来查找匹配项。

一旦缓存失效,所有后续的Dockerfile命令都会生成新的镜像,而缓存则不被使用。

Dockerfile 指令

这些建议旨在帮助您创建一个高效且可维护的Dockerfile。

FROM

只要可能,使用当前的官方镜像作为你的镜像的基础镜像。我们推荐Alpine镜像【https://hub.docker.com/_/alpine/】,因为编写这个镜像是非常严格的,并且很小(目前小于5 MB),但仍然是一个完整的Linux发行版。

LABEL

您可以将标签添加到镜像中,以帮助按项目组织镜像、记录许可信息、帮助实现自动化或出于其他原因。对于每个标签,用LABEL标记开始,用一个或者多个键值对 。下面的示例显示了不同的可接受格式。解释性注释是内联的。

必须引用带空格的字符串,否则必须转义空格。内部引号字符(")也必须转义。

  1. # Set one or more individual labels 
  2. LABEL com.example.version="0.0.1-beta" 
  3. LABEL vendor1="ACME Incorporated" 
  4. LABEL vendor2=ZENITH Incorporated 
  5. LABEL com.example.release-date="2015-02-12" 
  6. LABEL com.example.version.is-production="" 

一个镜像可以有多个标签。在Docker 1.10之前,建议将所有标签合并到一个标签指令中,以防止创建额外的层。这不再需要,但是仍然支持组合标签。

  1. # Set multiple labels on one line 
  2. LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12" 

上面的这个例子还可以写成下面这样:

  1. # Set multiple labels at once, using line-continuation characters to break long lines 
  2. LABEL vendor=ACME Incorporated  
  3. com.example.is-beta=  
  4. com.example.is-production=""  
  5. com.example.version="0.0.1-beta"  
  6. com.example.release-date="2015-02-12" 
  7. RUN 

使用反斜杠() 来分隔独立的命令行可以使RUN命令更有可读性、易于维护。

APT-GET

Apt-get 命令是很多Docker经常使用的命令。因为,他是安装各种包必须使用的命令。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读