1.镜像选择
镜像名称 |
版本标记 |
大小 |
备注 |
busybox |
latest |
1.22M |
|
alpine |
3.9.5 |
5.33M |
优先考虑 |
CentOS |
7.9 |
300M |
|
Debian |
buster |
114M |
制作docker镜像时,使用 multi stage 构建各个不同阶段的命令文件,最终copy到busybox或alpilne中执行。这样做得好处有二:
1、保持镜像最小,busybox,alpine 是最小的操作系统镜像
2、有各种linux工具使用,busybox本身是一个linux工具集
构建stage建议使用alpine和其它的官方包, 主要理由是此镜像比busybox稍大,但是比其他的系统镜像都小。busybox没有包管理工具,带来很多不便;这也是busybox和alpine的主要区别。
2.创建基础镜像
Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是上文说到的UnionFS。 在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。 当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。 Docker在bootfs之上的一层是rootfs(根文件系统)。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。 Docker 核心技术与实现原理 这篇文章,作者阅读了 rootfs 的规范,指出构建rootfs一些必须的文件夹。 |
2.1.创建 alpine 镜像
可以通过下载离线文件的方式构建,也可以通过 Docker 下载后再构建。区别在于 Dockerfile 文件中的配置语句的引用。
可以直接通过alpine 的网站下载离线文件。
离线文件,直接下载到本地。
2.2.容器在线配置
执行 docker build 命令时,当前的工作目录被称为构建上下文。默认情况下,Dockerfile 就位于该路径下。也可以通过 -f 参数来指定 dockerfile ,但 docker 客户端会将当前工作目录下的所有文件发送到 docker 守护进程进行构建。
确保构建目录内容干净 |
2.3.容器离线配置
离线文件,构建文件的引用内容如下
Dockerfile 中相关参数
FROM 指的是依赖的基础镜像,如scratch表示的是空白的,从零开始的。依赖的镜像可以是本地的,也可以是远程库的
ADD 指的是添加本地文件到镜像中,如果遇到linux可解压格式文件,会自动解压,这就是为什么整个文件中没有对tar.gz进行显式解压
RUN 运行命令,如安装软件的相关命令
CMD 设置启动Container时默认执行的命令,这个可以在启动容器时覆盖
2.4.构建镜像
3.经验
3.1.尽量使用 URL 添加源码
如果不采用分阶段构建,对于一些需要在容器内进行编译的项目,最好通过 git 或者 wegt 的方式将源码打入到镜像内,而非采用 ADD 或者 COPY ,因为源码编译完成之后,源码就不需要可以删掉了,而通过 ADD 或者 COPY 添加进去的源码已经用在下一层镜像中了,是删不掉的。
也就是说 git & wget source 然后 build ,最后 rm -rf source/ 这三部放在一条 RUN 指令中,这样就能避免源码添加到镜像中而增大镜像体积。
3.2.使用虚拟编译环境
对于只在编译过程中使用到的依赖,可以将这些依赖安装在虚拟环境中,编译完成之后可以一并删除这些依赖,比如 alpine 中可以使用 apk add --no-cache --virtual .build-deps ,后面加上需要安装的相关依赖。
构建完成之后可以使用 apk del .build-deps 命令,一并将这些编译依赖全部删除。需要注意的是,.build-deps 后面接的是编译时以来的软件包,并不是所有的编译依赖都可以删除,不要把运行时的依赖包接在后面,最好单独 add 一下。
3.3.最小化层数
docker 在 1.10 以后,只有 RUN、COPY 和 ADD 指令会创建层,其他指令会创建临时的中间镜像,但是不会直接增加构建的镜像大小了。
前文提到了建议使用 git 或者 wget 的方式来将文件打入到镜像当中,但如果我们必须要使用 COPY 或者 ADD 指令呢?
多个文件需要添加到容器中不同的路径,每个文件使用一条 ADD 指令的话就会增加一层镜像,这样就多了 12 层镜像。
其实大可不必,可以将这些文件全部打包为一个文件为 src.tar.gz 然后通过 ADD 的方式把文件添加到当中去,然后在 RUN 指令后使用 mv 命令把文件移动到指定的位置。这样仅仅一条 ADD 和 RUN 指令取代掉了 12 个 ADD 指令 。
4.配置指令
- ARG : 定义创建镜像过程中使用的变量,格式为 ARG <name>[=<default value>]
- FROM : 指定所创建镜像的基础镜像。格式为 FROM <image>:<tag>
- LABEL : 为生成的镜像添加元数据标签信息,辅助过滤特定镜像。格式为 LABEL <key>=<value> <key>=<value>
- EXPOSE : 声明镜像内服务监听的端口。格式为 EXPOSE <port>[/<protocol>]
- ENV : 指定环境变量,该变量在容器中存在,也可在容器启动时覆盖。格式为 ENV <key> <value>
- ENTRYPOINT : 指定镜像的默认入口命令,做为容器启动时的根命令执行。格式为 ENTRYPOINT ["executable", "param1", "param2"] 或者 ENTRYPOINT command param1 param2
- VOLUME : 创建一个数据卷挂载点。格式为 VOLUME ["/data"]
- USER : 指定容器运行时的用户名或UID,后续的RUN指令也使用该用户身份。格式为 USER daemon
- WORKDIR : 配置RUN\CMD\ENTRYPOINT等指令的工作目录,推荐使用绝对路径。格式为:WORKDIR /path/to/workdir
- ONBUILD : 指定当基于所生成镜像创建子镜像时,自动执行的操作指令。
- STOPSIGNAL : 指定容器接收退出的信号值。格式为: STOPSIGNAL signal
- HEALTHCHECK : 配置容器健康检查命令,自 Docker 1.12 开始支持。格式为: HEALTHCHECK [OPTIONS] CMD command
- SHELL : 指定默认的shell类型。格式为: SHELL ["executable", "parameters"]
5.操作指令
- RUN : 运行指定命令。格式为: RUN <command> 或 RUN ["executable", "param1", "param2"] 当命令较长时,可以用 \ 来换行。
- CMD : 指定容器启动时默认执行的命令,每个Dockerfile只能有一条CMD命令。格式有三种,分别为:CMD ["executable", "param1", "param2"] 或 CMD command param1 param2 或 CMD ["param1", "param2"]
- ADD : 添加内容到镜像中,将SRC内容复制到DEST中。格式为: ADD <src> <dest>
- COPY : 复制内容到镜像中。格式为 : COPY <src> <dest>
6.参考内容
容器指南之第一个容器 https://blog.51cto.com/waringid/5904849
容器指南之容器架构及常用指令 https://blog.51cto.com/waringid/5913145
容器指南之日常运维 https://blog.51cto.com/waringid/5914178
Docker For Windows 安装配置及常用维护 https://blog.51cto.com/waringid/5917666