【Docker】镜像
一.镜像(image)
1.概念
Docker image 本质上是一个 read-only 只读文件, 这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必须的文件。可以把 Docker image 理解成一个类, 可以通过这个类实例化出来很多实例化对象(容器)。
image 里面是一层层文件系统 Union FS。联合文件系统,可以将几层目录挂载到一起,形成一个虚拟文件系统。每一层文件系统我们叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite)和写出(whiteout-able),但是 docker 镜像中每一层文件系统都是只读的。
构建镜像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修改,增加了一层文件系统。一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解,就像上层把底层遮住了一样。
2.命令
1)docker image
列出本地镜像。
语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
关键参数:
| -a | 列出本地所有的镜像 |
| --digests | 显示镜像的摘要信息 |
| -f | 显示满足条件的镜像 |
| --format | 指定返回值的模板文件 |
| --no-trunc | 指定返回值的模板文件 |
| -q | 只显示镜像ID |

2)docker tag
标记本地镜像,将其归入某一仓库。
语法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
3)docker rmi
删除镜像。
语法:
docker rmi [OPTIONS] IMAGE [IMAGE...]
关键参数:
| -f | 强制删除 |
| --no-prune | 不移除该镜像的过程镜像,默认移除 |

4)docker save
将指定镜像保存成tar归档文件(包含文件系统内容的压缩包或tar包)。
语法:
docker save [OPTIONS] IMAGE [IMAGE...]
关键参数:
| -o | 输出到的文件 |
5)docker load
导入使用docker save命令导出的镜像。
语法:
docker load [OPTIONS]
关键参数:
| --input,-i | 指定导入的文件,代替STDIN |
| --quiet,-q | 精简输出信息 |
6)docker image inspect
查看镜像详细信息。
语法:
docker image inspect [OPTIONS] IMAGE [IMAGE...]

7)docker history
显示镜像历史。
语法:
docker history [OPTIONS] IMAGE
关键参数:
| -H,--human | 大小和日期采用人容易读的格式展现 |
| --no-trunc | 显示全部信息,不要隔断 |
| -q,--quiet | 只显示镜像id信息 |

8)docker import
从归档文件(包含文件系统内容的压缩包或tar包)中创建镜像。
语法:
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
关键参数:
| -c | 应用docker指令创建镜像 |
| -m | 提交时的说明文字 |
9)docker image prune
删除不使用的镜像(悬空镜像,没有标签且未被任何容器使用)。
语法:
docker image prune [OPTIONS]
关键参数:
| -a,--all | 删除全部不使用的镜像(没被任何容器使用) |
| --filter | 指定过滤条件 |
| -f,--force | 不提示是否删除 |
10)docker build
用于使用 Dockerfile 创建镜像。
语法:
docker build [OPTIONS] PATH | URL | -
关键参数:
| --build-arg=[] | 设置镜像创建时的变量 |
| -f | 指定要使用的Dockerfile路径 |
| --label=[] | 设置镜像使用的元数据 |
| --no-cache | 创建镜像的过程不使用缓存 |
| --pull | 尝试去更新镜像的版本 |
| --quiet,-q | 安静模式,成功只输出镜像ID |
| --tag,-t | 镜像的名字及标签,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个标签 |
| --network | 默认default,在构建期间设置RUN指令的网络模式 |
二.镜像仓库命令
1.docker login
登陆到一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub。
语法:
docker login [OPTIONS] [SERVER]
关键参数:
-u :登陆的用户名
-p :登陆的密码
2.docker pull
从镜像仓库中拉取或者更新指定镜像。
语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
关键参数:
-a :拉取所有 tagged 镜像
--disable-content-trust :忽略镜像的校验,默认开启
3.docker push
将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。
语法:
docker push [OPTIONS] NAME[:TAG]
关键参数:
-a :推送所有 tagged 镜像
--disable-content-trust :忽略镜像的校验,默认开启
4.docker search
从 Docker Hub 查找镜像。
语法:
docker search [OPTIONS] TERM
关键语法:
--no-trunc :显示完整的镜像描述;
-f <过滤条件>:列出收藏数不小于指定值的镜像
5.docker logout
登出一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub。
语法:
docker logout [SERVER]
三.镜像制作
镜像制作是因为某种需求,官方的镜像无法满足需求,需要我们通过一定手段来自定义镜像来满足要求。制作镜像往往因为以下原因:
1)编写的代码如何打包到镜像中直接跟随镜像发布;
2)第三方制作的内容安全性未知,如含有安全漏洞;
3)特定的需求或者功能无法满足,如需要给数据库添加审计功能;
4)公司内部要求基于公司内部的系统制作镜像,如公司内部要求使用自己的操作系统作为基础镜像。
制作容器镜像,主要有两种方法:
制作快照方式获得镜像(偶尔制作的镜像):在基础镜像上(比如 Ubuntu),先登录容器中,然后安装镜像需要的所有软件,最后整体制作快照。
Dockerfile 方式构建镜像(经常更新的镜像):将软件安装的流程写成 Dockerfile,使用 docker build 构建成容器镜像。
四.快照方式制作镜像
1.制作命令
docker commit
从容器创建一个新的镜像。
语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
参数:
| -a | 提交的镜像作者 |
| -c | 使用 Dockerfile 指令来创建镜像;可以修改启动指令 |
| -m | 提交时的说明文字 |
| -p | 在 commit 时,将容器暂停 |
五.Dockerfile 制作镜像
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,这个脚本就是 Dockerfile。Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
1.Dockerfile指令
官方文档:Dockerfile reference | Docker Docs
1)FROM
功能:FROM 指令用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像所提供的运行环境;
注意事项:
FROM 指令必须是 Dockerfile 中非注释行或者 ARG 之后的第一个指令;
实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build 会在docker 主机上查找指定的镜像文件,在其不存在时,则会自动从 Docker 的公共库 pull 镜像下来。如果找不到指定的镜像文件,docker build 会返回一个错误信息;
FROM 可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像,或将一个构建阶段作为另一个的依赖。
如果 FROM 语句没有指定镜像标签,则默认使用 latest 标签。
语法:
FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
参数:
| <platform> | 构建的 cpu 架构,如 linux/amd64, linux/arm64, windows/amd64 |
| <image> | 指定作为 base image 的名称 |
| <tag> | base image 的标签,省略时默认 latest |
| <digest> | 是镜像的哈希码 |
| AS <name> | 指定构建步骤的名称,配合 COPY --from=<name>可以完成多级构建 |
2)MAINTAINER
功能:用于让 dockerfile 制作者提供本人的详细信息,该功能已经废弃,由 label 替代。
语法:
MAINTAINER <authtor's detail>
参数:
| <authtor's detail> | 作者信息 |
3)LABEL
功能:为镜像添加元数据,元数据是 kv 对形式。
语法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
4)COPY
功能:用于从 docker 主机复制新文件或者目录至创建的新镜像指定路径中 。
语法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
参数:
| <src> | 要复制的源文件或目录,支持使用通配符 |
| <dest> | 目标路径,即正在创建的 image 的文件系统路径;建议<dest>使用绝对路径,否则,COPY 指定以 WORKDIR 为当前路径在路径中有空白字符时,通常使用第 2 种格式 |
| --chown | 修改用户和组 |
| --from <name> | 可选项 :可以从之前构建的步骤中拷贝内容,结合 FROM .. AS <name>往往用作多级构建,后续我们有实战课专门完成多级构建 |
注意事项:
<src>必须是 build 上下文中的路径,不能是其父目录中的文件;
如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制;
如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目
录,且必须以 / 结尾;
如果<dest>事先不存在,它将会被自动创建,这包括父目录路径。
5)ENV
功能:用于为镜像定义所需的环境变量,并可被 Dockerfile 文件中位于其后的其它指令(如 ENV、ADD、COPY 等)所调用;调用格式为$variable_name 或 ${variable_name}。
语法:
ENV <key>=<value> ...
6)WORKDIR
功能:为 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指定设定工作目录。
语法:
WORKDIR /path/to/workdir
注意事项:
默认的工作目录是/;
如果提供了相对路径,它将相对于前一条 WORKDIR 指令的路径;
WORKDIR 指令可以解析先前使用设置的环境变量 ENV。
7)ADD
功能:ADD 指令类似于 COPY 指令,ADD 支持使用 TAR 文件和 URL 路径,会自动完成解压和下载。
语法:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
参数:
| <src> | 要复制的源文件或目录,支持使用通配符 |
| <dest> | 目标路径,即正在创建的 image 的文件系统路径;建议<dest>使用绝对路径,否则,ADD 指定以 WORKDIR 为其实路径;在路径中有空白字符时,通常使用第 2 种格式 |
| --chown | 修改用户和组 |
8)RUN
功能:用于指定 docker build 过程中运行的程序,其可以是任何命令。
语法:
#shell form
RUN <command>
#exec form
RUN ["executable", "param1", "param2"]
参数:
第一种格式中,<command>通常是一个 shell 命令, 且以“/bin/sh -c”来运行它,Windows 默认为 cmd /S /C。如果一个脚本 test.sh 不能自己执行,必须要/bin/sh -c test.sh 的方式来执行,那么,如果使用 RUN 的 shell 形式,最后得到的命令相当于:
/bin/sh -c "/bin/sh -c 'test.sh'"
第二种语法格式中的参数是一个 JSON 格式的数组,其中<executable>为要运行的命令,后面的 <paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的 shell 操作如变量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此 shell 特性的话,可以将其替换为类似下面的格式。 RUN ["/bin/bash", "-c", "<executable>", "<param1>"]
9)CMD
功能:
类似于 RUN 指令,CMD 指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同;
RUN 指令运行于映像文件构建过程中,而 CMD 指令运行于基于 Dockerfile构建出的新映像文件启动一个容器时;
CMD 指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD 指定的命令其可以被 docker run 的命令行选项所覆盖;
在 Dockerfile 中可以存在多个 CMD 指令,但仅最后一个会生效。
语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
注意事项:
第二种则用于为 ENTRYPOINT 指令提供默认参数;
json 数组中,要使用双引号,单引号会出错。
10)EXPOSE
功能:
用于为容器声明打开指定要监听的端口以实现与外部通信;
该 EXPOSE 指令实际上并不发布端口。它充当构建图像的人和运行容器的人之间的一种文档,关于要发布哪些端口。要在运行容器时实际发布端口,使用-p 参数发布和映射一个或多个端口,或者使用-Pflag 发布所有暴露的端口并将它们映射宿主机端口。
语法:
EXPOSE <port> [<port>/<protocol>...]
参数:
| <protocol> | tcp/udp 协议 |
| <port> | 端口 |
11)ENTRYPOINT
功能:用于指定容器的启动入口。
语法:
#exec from
ENTRYPOINT ["executable", "param1", "param2"]
# shell form
ENTRYPOINT command param1 param2
参数:
json 数组中,要使用双引号,单引号会出错
12)ARG
功能:
ARG 指令类似 ENV,定义了一个变量;区别于 ENV:用户可以在构建时docker build --build-arg <varname> = <value> 进行对变量的修改;ENV 不可以;
如果用户指定了未在 Dockerfile 中定义的构建参数,那么构建输出警告。
语法:
ARG <name>[=<default value>]
注意事项:
Dockerfile 可以包含一个或多个 ARG 指令
ARG 支持指定默认值
使用范围:定义之后才能使用,定义之前为空,如下面的案例,执行命令docker build --build-arg username=what_user .第二行计算结果为some_user ,不是我们指定的 build-arg 中的参数值 what_user:
FROM busybox
USER ${username:-some_user}
ARG username
USER $username
# ...
ENV 和 ARG 同时存在,ENV 会覆盖 ARG
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=v1.0.0
RUN echo $CONT_IMG_VER
13)VOLUME
功能:
用于在 image 中创建一个挂载点目录;
通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。
语法:
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
参数:
mountpoint:挂载点目录
注意事项:
如果挂载点目录路径下此前有文件存在,docker run 命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中;
其实 VOLUME 指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能;
volume 只是指定了一个目录,用以在用户忘记启动时指定-v 参数也可以保证容器的正常运行。比如 mysql,你不能说用户启动时没有指定-v,然后删了容器,把 mysql 的数据文件都删了,那样生产上是会出大事故的,所以 mysql 的 dockerfile 里面就需要配置 volume,这样即使用户没有指定-v,容器被删后也不会导致数据文件都不在了。还是可以恢复的;
volume 与-v 指令一样,容器被删除以后映射在主机上的文件不会被删除;
如果-v 和 volume 指定了同一个位置,会以-v 设定的目录为准,其实volume 指令的设定的目的就是为了避免用户忘记指定-v 的时候导致的数据丢失,那么如果用户指定了-v,自然而然就不需要 volume 指定的位置了。
14)SHELL
功能:
SHELL 指令允许覆盖用于 shell 命令形式的默认 shell;
Linux 上的默认 shell 是["/bin/sh","-c"],在 Windows 上是["cmd","/S","/C"];
SHELL 指令必须以 JSON 格式写入 Dockerfile。
语法:
SHELL ["executable", "parameters"]
参数:
| executable | shell 可执行文件的位置 |
| parameters | shell 执行的参数 |
注意事项:
SHELL 指令可以多次出现;
每个 SHELL 指令都会覆盖所有先前的 SHELL 指令,并影响所有后续指令;
该 SHELL 指令在 Windows 上特别有用,因为 windows 行有两种不同的shell:cmd 和 powershell。
15)USER
功能:
用于指定运行 image 时的或运行 Dockerfile 中任何 RUN、CMD 或ENTRYPOINT 指令定的程序时的用户名或 UID;
默认情况下,container 的运行身份为 root 用户。
语法:
USER <user>[:<group>]
USER <UID>[:<GID>]
参数:
| user | 用户 |
| group | 用户组 |
| uid | 用户 id |
| gid | 组 id |
注意事项:
<UID>可以为任意数字,但实践中其必须为/etc/passwd 中某用户的有效UID,否则将运行失败。
16)HEALTHCHECK
功能:
HEALTHCHECK 指令告诉 Docker 如何测试容器以检查它是否仍在工作;
即使服务器进程仍在运行,这也可以检测出陷入无限循环且无法处理新连接的 Web 服务器等情况。
语法:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
参数:
OPTIONS 选项有:
| --interval=DURATION (default: 30s) | 每隔多长时间探测一次,默认 30秒 |
| -- timeout= DURATION (default: 30s) | 服务响应超时时长,默认 30 秒 |
| --start-period= DURATION (default: 0s) | 服务启动多久后开始探测,默认 0 秒 |
| --retries=N (default: 3) | 认为检测失败几次为宕机,默认 3 次 |
返回值:
| 0 | 容器成功是健康的,随时可以使用 |
| 1 | 不健康的容器无法正常工作 |
| 2 | 保留不使用此退出代码 |
17)ONBUILD
功能:
用于在 Dockerfile 中定义一个触发器;
以该 Dockerfile 中的作为基础镜像由 FROM 指令在 build 过程中被执行时,将会“触发”创建其 base image 的 Dockerfile 文件中的 ONBUILD 指令定义的触发器。
语法:
ONBUILD <INSTRUCTION>
参数:
INSTRUCTION:dockerfile 的一条指令
18)STOPSIGNAL
功能:
STOPSIGNAL 指令设置将发送到容器的系统调用信号;
此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如 9,或者 SIGNAME 格式的信号名,例如 SIGKILL。
参数:
STOPSIGNAL 指令设置将发送到容器出口的系统调用信号。 此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如 9,或者 SIGNAME 格式的信号名,例如 SIGKILL。常见的信号如下:
| 1 | SIGHUP | 启动被终止的程序,可让该进程重新读取自己的配置文件,类似重新启动 |
| 2 | SIGINT | 相当于用键盘输入 [ctrl]-c 来中断一个程序的进行 |
| 9 | SIGKILL | 代表强制中断一个程序的进行,如果该程序进行到一半,那么尚未完成的部分可能会有“半产品”产生,类似 vim 会有 .filename.swp 保留下来 |
| 15 | SIGTERM | 以正常的方式来终止该程序。由于是正常的终止,所以后续的动作会将他完成。不过,如果该程序已经发生问题,就是无法使用正常的方法终止时,输入这个 signal 也是没有用的 |
| 19 | SIGSTOP | 相当于用键盘输入 [ctrl]-z 来暂停一个程序的进行 |
2.制作命令
docker build
docker build 命令用于使用 Dockerfile 创建镜像。
语法:
docker build [OPTIONS] PATH | URL | -
关键参数:
| --build-arg=[] | 设置镜像创建时的变量 |
| -f | 指定要使用的 Dockerfile 路径 |
| --label=[] | 设置镜像使用的元数据 |
| --no-cache | 创建镜像的过程不使用缓存 |
| --pull | 尝试去更新镜像的新版本 |
| --quiet,-q | 安静模式,成功后只输出镜像 ID |
| -tag,-t | 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签 |
| --network | 默认 default。在构建期间设置 RUN 指令的网络模式 |
更多推荐


所有评论(0)