前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker Review - dockerfile 入门篇

Docker Review - dockerfile 入门篇

作者头像
小小工匠
发布2022-11-30 14:07:01
1.2K0
发布2022-11-30 14:07:01
举报
文章被收录于专栏:小工匠聊架构

文章目录

在这里插入图片描述
在这里插入图片描述

Docker 镜像、容器 、Docker file

在这里插入图片描述
在这里插入图片描述

Docker 镜像、容器和 Dockerfile 三者之间的关系如上图所示

使用 Dockerfile 定义镜像,运行镜像启动容器。


概述

官文: https://docs.docker.com/engine/reference/builder/

官文Blog :Best practices for writing Dockerfiles

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
  • 镜像不包含任何动态数据,其内容在构建之后也不会被改变
  • 镜像的定制实际上就是定制每一层所添加的配置、文件 如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
  • Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
  • 有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。
在这里插入图片描述
在这里插入图片描述

Docker File文件格式

代码语言:javascript
复制
##  Dockerfile文件格式

# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
 
# 1、第一行必须指定 基础镜像信息
FROM ubuntu
 
# 2、维护者信息
MAINTAINER docker_user docker_user@email.com
 
# 3、镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
 
# 4、容器启动执行指令
CMD /usr/sbin/nginx

Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。

  • 开始必须要指明所基于的镜像名称,
  • 接下来一般会说明维护者信息;
  • 后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;
  • 最后是 CMD 指令,来指明运行容器时的操作命令。
在这里插入图片描述
在这里插入图片描述

Docker File 解读

https://docs.docker.com/engine/reference/builder/#from

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
FROM         指定所创建镜像的基础镜像
MAINTAINER   制定维护者信息
RUN          运行命令
CMD          容器启动是默认执行的命令
LABEL        指定生成镜像的元数据标签信息
EXPOSE       声明镜像内服务所监听的端口
ENV          指定环境变量
ADD          复制指定src路径的内容到容器的dest路径下,如果src为tar文件,则自动解压到dest路径下
copy         复制指定src路径的内容到镜像的dest路径下
ENTERPOINT   指定镜像的默认入口
VOLUME       创建数据卷挂载点
USER         指定运行容器是的用户名或UID
WORKDIR      配置工作目录
ARG          指定镜像内使用的参数
ONBUILD      配置当所创建的镜像作为其他镜像的基础镜像时,所执行创建操作指令
STOPSIGAL    容器退出信号值
HEALTHCHECK  如何进行健康检查
SHELL        指定使用shell的默认shell类型

下面详细展开

1、FROM 指定基础镜像

https://docs.docker.com/engine/reference/builder/#from

FROM 指令用于指定其后构建新镜像所使用的基础镜像。FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docker 将会基于该镜像构建新镜像,FROM 后的命令也会基于这个基础镜像。

在这里插入图片描述
在这里插入图片描述

通过 FROM 指定的镜像,可以是任何有效的基础镜像。

需要注意的事项如下:

  • FROM 必须 是 Dockerfile 中第一条非注释命令
  • 在一个 Dockerfile 文件中创建多个镜像时,FROM 可以多次出现。只需在每个新命令 FROM 之前,记录提交上次的镜像 ID。
  • tag 或 digest 是可选的,如果不使用这两个值时,会使用 latest 版本的基础镜像
在这里插入图片描述
在这里插入图片描述

2、RUN 执行命令

https://docs.docker.com/engine/reference/builder/#run

在镜像的构建过程中执行特定的命令,并生成一个中间镜像。

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
RUN <command>
#exec格式
RUN ["executable", "param1", "param2"]
  • RUN 命令将在当前 image 中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行 Dockerfile 中的下一个指令。
  • 层级 RUN 指令和生成提交是符合 Docker 核心理念的做法。它允许像版本控制那样,在任意一个点,对 image 镜像进行定制化构建。
  • RUN 指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定 --no-cache 参数,如:docker build --no-cache。

3、COPY 复制文件

https://docs.docker.com/engine/reference/builder/#copy

COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的<目标路径>位置

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]

和 RUN 指令一样,也有两种格式,一种类似于命令行,一种类似于函数调用。

代码语言:javascript
复制
COPY package.json /usr/src/app/

<源路径>可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则,如:

代码语言:javascript
复制
COPY hom* /mydir/
COPY hom?.txt /mydir/

<目标路径>可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。

此外,还需要注意一点,使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git 进行管理的时候。


4、ADD 更高级的复制文件

ADD 指令和 COPY 的格式和性质基本一致。

在这里插入图片描述
在这里插入图片描述

在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。

另外需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。

因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD


5、ENV 设置环境变量

设置环境变量

在这里插入图片描述
在这里插入图片描述

格式有两种:

代码语言:javascript
复制
ENV <key> <value> 

这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。

代码语言:javascript
复制
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
代码语言:javascript
复制
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
    MY_CAT=fluffy

这个例子中演示了如何换行,以及对含有空格的值用双引号括起来的办法,这和 Shell 下的行为是一致的。


6、EXPOSE

为构建的镜像设置监听端口,使容器在运行时监听

代码语言:javascript
复制
EXPOSE <port> [<port>...]
在这里插入图片描述
在这里插入图片描述

EXPOSE 指令并不会让容器监听 host 的端口,如果需要,需要在 docker run 时使用 -p、-P 参数来发布容器端口到 host 的某个端口上。

在这里插入图片描述
在这里插入图片描述

7、VOLUME 定义匿名卷

VOLUME用于创建挂载点,即向基于所构建镜像创始的容器添加

在这里插入图片描述
在这里插入图片描述

一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

  • 卷可以容器间共享和重用
  • 容器并不一定要和其它容器共享卷
  • 修改卷后会立即生效
  • 对卷的修改不会对镜像产生影响
  • 卷会一直存在,直到没有任何容器在使用它

VOLUME 让我们可以将源代码、数据或其它内容添加到镜像中,而又不并提交到镜像中,并使我们可以多个容器间共享这些内容。


8、CMD容器启动命令

CMD用于指定在容器启动时所要执行的命令

在这里插入图片描述
在这里插入图片描述

CMD 有以下三种格式:

代码语言:javascript
复制
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

省略可执行文件的 exec 格式,这种写法使 CMD 中的参数当做 ENTRYPOINT 的默认参数,此时 ENTRYPOINT 也应该是 exec 格式,具体与 ENTRYPOINT 的组合使用,参考 ENTRYPOINT

与 RUN 指令的区别:RUN 在构建的时候执行,并生成一个新的镜像,CMD 在容器运行的时候执行,在构建时不进行任何操作。


9、ENTRYPOINT入口点

ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令. ENTRYPOINT 用于给容器配置一个可执行程序。也就是说,每次使用镜像创建容器时,通过 ENTRYPOINT 指定的程序都会被设置为默认程序。

在这里插入图片描述
在这里插入图片描述

ENTRYPOINT 有以下两种形式:

代码语言:javascript
复制
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
  • ENTRYPOINTCMD 非常类似,不同的是通过docker run执行的命令不会覆盖 ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给 ENTRYPOINT
  • Dockerfile 中只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令。
  • docker run运行容器时指定的参数都会被传递给 ENTRYPOINT ,且会覆盖 CMD 命令指定的参数。如,执行docker run <image> -d时,-d 参数将被传递给入口点。
  • 也可以通过docker run --entrypoint重写 ENTRYPOINT 入口点。如:可以像下面这样指定一个容器执行程序:
代码语言:javascript
复制
ENTRYPOINT ["/usr/bin/nginx"]
在这里插入图片描述
在这里插入图片描述

10、USER 指定当前用户

USER 用于指定运行镜像所使用的用户

代码语言:javascript
复制
USER daemon
在这里插入图片描述
在这里插入图片描述

使用USER指定用户时,可以使用用户名、UID 或 GID,或是两者的组合。以下都是合法的指定试:

代码语言:javascript
复制
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

使用USER指定用户后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT 都将使用该用户。镜像构建完成后,通过 docker run 运行容器时,可以通过 -u 参数来覆盖所指定的用户。


11、WORKDIR 指定工作目录

WORKDIR用于在容器内设置一个工作目录

https://docs.docker.com/engine/reference/builder/#workdir

代码语言:javascript
复制
WORKDIR /path/to/workdir

通过WORKDIR设置工作目录后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。

如,使用WORKDIR设置工作目录:

代码语言:javascript
复制
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

在以上示例中,pwd 最终将会在 /a/b/c 目录中执行。在使用 docker run 运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。


12、LABEL为镜像添加元数据

LABEL用于为镜像添加元数据,元数以键值对的形式指定:

代码语言:javascript
复制
LABEL <key>=<value> <key>=<value> <key>=<value> ...

使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。

推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。 如,通过LABEL指定一些元数据:

代码语言:javascript
复制
LABEL version="1.0" description="artisanLearnDocker" by="artisan"

指定后可以通过docker inspect查看:

代码语言:javascript
复制
docker inspect itbilu/test
"Labels": {
    "version": "1.0",
    "description": "artisanLearnDocker",
    "by": "ITartisan"
},

13、ARG构建参数

ARG用于指定传递给构建运行时的变量:

代码语言:javascript
复制
ARG <name>[=<default value>]

如,通过ARG指定两个变量:

代码语言:javascript
复制
ARG site
ARG build_user=artisan

以上我们指定了 site 和 build_user 两个变量,其中 build_user 指定了默认值。

在使用 docker build 构建镜像时,可以通过 --build-arg <varname>=<value> 参数来指定或重设置这些变量的值。

代码语言:javascript
复制
docker build --build-arg site=artisan.com -t artisan/test .

这样我们构建了 artisan/test 镜像,其中site会被设置为 artisan.com,由于没有指定 build_user,其值将是默认值artisan。


14、ONBUILD

ONBUILD用于设置镜像触发器

代码语言:javascript
复制
ONBUILD [INSTRUCTION]

当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发。 如,当镜像被使用时,可能需要做一些处理:

代码语言:javascript
复制
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

15、STOPSIGNAL

STOPSIGNAL用于设置停止容器所要发送的系统调用信号:

代码语言:javascript
复制
STOPSIGNAL signal

所使用的信号必须是内核系统调用表中的合法的值,如:SIGKILL。


16、SHELL指令

SHELL用于设置执行命令(shell式)所使用的的默认 shell 类型:

代码语言:javascript
复制
SHELL ["executable", "parameters"]

SHELL在Windows环境下比较有用,Windows 下通常会有 cmd 和 powershell 两种 shell,可能还会有 sh。

这时就可以通过 SHELL 来指定所使用的 shell 类型:

代码语言:javascript
复制
FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • Docker 镜像、容器 、Docker file
  • 概述
  • Docker File文件格式
  • Docker File 解读
    • 1、FROM 指定基础镜像
      • 2、RUN 执行命令
        • 3、COPY 复制文件
          • 4、ADD 更高级的复制文件
            • 5、ENV 设置环境变量
              • 6、EXPOSE
                • 7、VOLUME 定义匿名卷
                  • 8、CMD容器启动命令
                    • 9、ENTRYPOINT入口点
                      • 10、USER 指定当前用户
                        • 11、WORKDIR 指定工作目录
                          • 12、LABEL为镜像添加元数据
                            • 13、ARG构建参数
                              • 14、ONBUILD
                                • 15、STOPSIGNAL
                                  • 16、SHELL指令
                                  相关产品与服务
                                  容器服务
                                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档